Renesas M16C Microcontroller LCD Display
M16C RENESAS REMOTE LCD Display
1.The Target
How many times when using a device you think: How nice it would be to have more informations from something different from the same led that has 527 colours and flashes in 6432 various ways often making things more confusing.
How many of your applications are using a GSM module? Remote controls, remote activation commands etc. but why not use it for sending and receiving SMS? Certainly we must re elaborate the original firmware, but at least we could start from the hardware of an already existing project! Well, if you have the same problems the following project can help you.
2.DESCRIPTION
The RENESAS M16C lcd display allows both to visualize on a display the data received from an other device and to send a sequence of data string, as a response to a specific request.
The main functional blocks that are composing it, are:
1) Visualization display lcd.
2) Alphanumeric keyboard.
3) Serial communication.
4) Central processing unit.
Let's analyze these blocks!
3.VISUALIZATION DISPLAY
To visualize the data we selected a classic 16x2 alphanumeric display lcd that is a device on which 16 ASCII standard characters can be visualized on each of the two available lines. The interface with the Renesas microcontroller is handled through three control signals and eight data lines, obviously managed inside the firmware.
4.ALPHANUMERIC KEYBOARD
An alphanumeric keyboard with 14 keys (0-9,RD,WR,SEND,UP DOWN) allows both to write data to be sent. The interface with the microcontroller has been designed using the matrix layout that allows to reduce the number of I/O necessary for the electric connection and simplifies the firmware driver.
5.SERIAL COMMUNICATION
The communication with the external world is assigned to a serial port using TX, RX and GND signals. A simple RS232 transceiver is interposed between the central processing unit and the external world.
6.CENTRAL PROCESSING UNIT
The system control is assigned to a the M16C/62P series Renesas 16bit microcontroller that thanks to its firmware can control and manage in real time the correct functioning of the CONSOLE. The program is written in C and consists of the following main functional blocks:
keyboard management
display management
serial management
These routines are periodically called in a loop located inside of the main program and allow the user to access all the functionalities of the CONSOLE. Obviously there are also low level drivers for the physical management of peripheral (for example the keyboard acquisition or the activation of the display). As an example it is here shown the routine that reads keyboard status.
Keyboard Manager
//Title: gest_tastiera_100.c
//Author: najro.prestato
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: Keys capture module
//
// ptastihi and ptastilo freeze the keyboard state at the first acquisition.
// mtastihi and mtastilo freeze the keyboard state at the next acquisition.
// tastihi and tastilo are used so that every program's module can have real
// time access to the keyboard state.
// NB: key pressed bit=0
// key not pressed bit=1
//
// Example 1:
// no key pressed
// tastilo=11111111b tastihi=11111111b
//
// Example 2:
// key4pressed for a NOT acceptable time
// ptastilo=11111110b (*) ptastihi=11111111b
// after x mS key not active
// mtastilo=11111111b mtastihi=11111111b
// as mtastilo is different of ptastilo, I am not updating tastilo and tastihi that maintain
// the previous value, that is the configuration for no key pressed (Example 1)
//
// Example 3:
// key 4 pressed for an acceptable time
// ptastilo=11111110b(*) ptastihi=11111111b
// after xmS key active
// mtastilo=11111110b(*) mtastihi=11111111b
// as mtastilo is equal to ptastilo, updating tastilo and tastihi with the new
// configuration, that is:
// tastilo=11111110b(*) tastihi=11111111b
//
// (*) for the program, the bit 0 of tastilo represents the key 4
// but it can be configured as you wish
//1: Directives
#include "sfr62.h"
#include "global.h"
#include "gest_wdt.h"
#include "gest_tastiera.h"
//2: Local Variables
union register tastilo,tastihi;
unsigned char ptastilo,ptastihi;
unsigned char mtastilo,mtastihi;
unsigned char statotastiera,tmrari;
//3: Local Function Prototypes
void gest_tastiera(void);
//4: Keyboard Management Module
void gest_tastiera(void)
{
//NB: Key not pressed = 1 logic
//
//Define temporary register
uchar wkreg;
switch (statotastiera)
{
//Keyboard definition acquisition for the first time and anti bouncing activation
case 0:
wkreg=0xFF;
//Acquisition keys line 1 (1-2-3-4)
TR1=0;
wkreg=p3;
ptastilo=wkreg>>4;
TR1=1;
//Acquisition keys line 2 (5-6-7-8)
TR2=0;
wkreg=p3 & 0xF0;
ptastilo=ptastilo+wkreg;
TR2=1;
//Acquisition keys line 3 (9-0-U-D)
TR3=0;
wkreg=p3;
ptastihi=wkreg>>4;
TR3=1;
//Acquisition keys line 4 (S-W/R- - )
TR4=0;
wkreg=p3 & 0xF0;
ptastihi=ptastihi+wkreg;
TR4=1;
//Preload timer antibouncing
tmrari=cTMRARI;
//Goto antibouncing management
statotastiera=01;
break;
//Waiting the end of anti bouncing and verify keyboard configuration with eventual assignment
case 1:
//Wait the end of anti bouncing
if (tmrari==00)
{
wkreg=0xFF;
//Reacquisition keys line 1 (1-2-3-4)
TR1=0;
wkreg=p3;
mtastilo=wkreg>>4;
TR1=1;
//Reacquisition keys line 2 (5-6-7-8)
TR2=0;
wkreg=p3 & 0xF0;
mtastilo=mtastilo+wkreg;
TR2=1;
//Reacquisition keys line 3 (9-0-U-D)
TR3=0;
wkreg=p3;
mtastihi=wkreg>>4;
TR3=1;
//Reacquisition keys line 4 (S-W/R- - )
TR4=0;
wkreg=p3 & 0xF0;
mtastihi=mtastihi+wkreg;
TR4=1;
//Verify if configuration valid and eventual transfer on tastilo
//and tastihi the new configuration
if ((mtastilo==ptastilo) || (mtastihi==ptastihi))
{
tastilo.byte=mtastilo;
tastihi.byte=mtastihi;
}
//Reinit acquisition
statotastiera=00;
}
break;
//
default:
//In case of unexpected values on statotastiera, restart cycle.
statotastiera=00;
break;
}
//Update the WDT management register
checkwdt+=cWDTRO;
}
Using support registers (ptastilo and ptastihi,mtastilo and mtastihi,) the keyboard is scanned twice, if both readings match then the keyboard new status is accepted. This makes the keyboard immune from noise and bouncing.
These are the functions for the management of a 16x2 display equipped with Samsung S6A0069 controller
//Title: DrvS6A0069_100.c
//Author: najro.prestato
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: LCD display management with Samsung S6A0069 controller
// The LCD format is managed by LCD_ROWS and LCD_COLS
// The modality is managed by LCD_BUS.
// The LCD control pins are declared by the following constants:
// LCD_RS pin for Register selector
// LCD_RW pin for Read/Write
// LCD_EN pin for Enable
// LCD_IO_RS tris for Register selector
// LCD_IO_RW tris for Read/Write
// LCD_IO_EN tris for Enable
// The pins for DATA are all on the same port.
// 8 bit: D0-D7 connected to Portx0 - Portx7
// 4 bit: D4-D7 connected to Portx4 - Portx7
// The point Top, Left is set to 1,1
// The setting of the connections comes through:
// LCD_PORT_DATA pin port for Data
// LCD_IO_DATA tris for Data
// In order to modify the characteristics for other LCD:
// access and modify lcd.h
//Note: Size Char pos DDRAM addresses
// 2*16 00..15 00h..0Fh + 40h..4Fh
// 2*20 00..19 00h..13h + 40h..53h
//
//
//Functions available for piloting LCD :
//
// lcdinit(void) Starts LCD
// checkbf(void) Waits for the end of the last operation
// lcdclear(void) Sends command Clear & Home
// lcdputch(char) Writes a character in the cursor position
// lcdputs(char *) Writes a character string
// lcdwrite(char, char) Writes a byte unsigned into DD RAM
// lcdcommand(char) Writes a command
// lcdgetch(char) Reads the character in the cursor position
// lcdread(char) Reads a byte unsigned from DD RAM
// lcdsetcurs(char, char) Moves the cursor to the line, row
// lcdgetcurs (char, char) Returns the current cursor line, row
//
//1: Directives
#include "sfr62.h"
#include "global.h"
#include "S6A0069.h"
//2: Local variables
//3: Local functions prototypes
void delayms(uchar dly_ms); //Delay routine in mS (NB: realized with loop)
void delayus10(uchar dly_us); //Delay routine of 10uS (NB: realized with loop)
void lcdinit(void); //Starts LCD - call first, before any other function
void checkbf(void); //Waits the end of the last operation
void lcdputch(uchar car); //Writes a character in the current position of the cursor
void lcdputs(uchar far *str); //Writes a character string
//(NB: It is used to address eventual messages allocated in flash)
void lcdcommand(uchar lcd_cmd); //Writes a command
void lcdwrite(uchar value, uchar modo); //Writes a byte unsigned into DD RAM
uchar lcdgetch(void); //Reads the character in the cursor position
uchar lcdread(unsigned char modo); //Reads a byte unsigned from DD RAM
void lcdsetcurs(uchar row, uchar col); //Moves the cursor to line, row
void lcdgetcurs(uchar *row,uchar *col); //Returns the current cursor line, row
//4: LCD driver
void s6a0069(void)
{
;
}
//5: Local functions code
//
//
//5a) Delay generation routine with BT 1mS (max 255mS)-
void delayms(unsigned char dly_ms)
{
unsigned char wkreg,wkreg1,wkreg2;
for (wkreg = dly_ms; wkreg ; --wkreg)
{
//delay cycle of 1000 uS
for (wkreg1 = 100; wkreg1 ; --wkreg1)
{
delayus10(DLY10US);
}
}
}
//
//5b) Delay generation routine with BT 10us-
void delayus10(unsigned char dly_us)
{
#pragma asm
loop1us: adjnz.b #-1,R1L,loop1us
#pragma endasm
}
//
//5c) LCD initialization with S6A0069 Samsung controller
void lcdinit(void)
{
LCD_RS = LCD_CMD; //Set modality Command
LCD_RW = LCD_WRITE; //Set modality Write
LCD_EN = LCD_DISABLE; //Disable lcd
LCD_IO_RS = 1; //Set pin as output
LCD_IO_RW = 1; //Set pin as output
LCD_IO_EN = 1; //Set pin as output
LCD_PORT_DATA = 0x00; //Set DB7-DB0 = 00000000
LCD_IO_DATA |= LCD_IO_DMASK; //Set data bus as output
//Initialization sequence for S6A0069 Samsung
//
//1-Wait for stabilization Vcc: minimum 40mS
delayms(60);
//2-Function set: Bus at 8 bit, 2 lines, font 5x8
LCD_PORT_DATA = (LCD_BUS_8BIT | LCD_LINE_MULTI | LCD_FONT_5x8);
//Strobe E
LCD_STROBE;
delayms(1);
//3-Display on
lcdcommand(LCD_DISPLAY_ON | LCD_CURSOR_OFF |LCD_BLINK_OFF);
delayms(1);
//4-Display clear
lcdcommand(LCD_CLEAR);
delayms(3);
//5-Default Entry Mode: Auto increment right, Display shift off
lcdcommand(LCD_CURSOR_INC);
}
//
//5d) Verify busy flag LCD
void checkbf(void)
{
unsigned char busy;
LCD_RS = LCD_CMD; // Set modality command
LCD_RW = LCD_READ; // Set modality read
LCD_IO_DATA &= ~LCD_IO_DMASK; // Set port as input
LCD_EN = LCD_ENABLE; // Activate Lcd
do{
busy = LCD_PORT_DATA & LCD_BIT_BUSY; // DB7 = BF
}while (busy);
LCD_EN = LCD_DISABLE; // Disable lcd
LCD_RW = LCD_WRITE; // Set modality write
LCD_IO_DATA |= LCD_IO_DMASK; // Set port as output
}
//
//5e) Send a command to LCD
void lcdcommand(uchar lcd_cmd)
{
//Verify busy flag display (nb: verify made reading BF in loop)
checkbf();
//Set modality command on display
LCD_RS = LCD_CMD;
//Transfer to display (check first if bus at 4 or 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = lcd_cmd;
#else
//Transfer high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd & LCD_IO_DMASK);
LCD_STROBE;
//Trasfer low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd << 4);
#endif
LCD_STROBE;
}
//
//5f) Write a character on the LCD
void lcdputch(uchar car)
{
//Verify busy flag display (nb: verify made reading BF in loop)
checkbf();
//Set modality data on display
LCD_RS = LCD_DATA;
//Trasfer to display (check first if bus at 4 or 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = car;
#else
//Trasfer high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car & LCD_IO_DMASK);
LCD_STROBE;
//Trasfer low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car << 4);
#endif
LCD_STROBE;
}
//
//5g) Write a character string on the LCD
void lcdputs(uchar far *str)
{
while(*str)
lcdputch(*str++);
}
//
//5h) Write an 8 bit unsigned into DDRAM
void lcdwrite(uchar value, uchar modo)
{
//Verify busy flag display (nb: verify made reading BF in loop)
checkbf();
//Set modality display (CMD if modo=0 or DATA if modo=1)
if (modo==0)
LCD_RS = LCD_CMD;
else
LCD_RS = LCD_DATA;
//Trasfer to display (check first if bus at 4 or 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = value;
#else
//Trasfer high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value & LCD_IO_DMASK);
LCD_STROBE;
//Trasfer low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value << 4);
#endif
LCD_STROBE;
}
//
//5i) Read the character from the current cursor position
uchar lcdgetch (void)
{
return lcdread(LCD_DATA);
}
//
//5j) Read a byte unsigned from DD RAM
uchar lcdread (uchar modo)
{
unsigned char byteDDRAM;
unsigned char highbits;
//Sets DB7/DB0 as input
LCD_IO_DATA &= ~LCD_IO_DMASK;
//Set modality display (CMD if modo=0 or DATA if modo=1)
LCD_RS = (modo) ? LCD_DATA : LCD_CMD;
//Sets on display operation of Read
LCD_RW = LCD_READ;
delayus10(DLY10US);
//Enable display
LCD_EN = LCD_ENABLE;
delayus10(DLY10US);
//Read from display (check first if bus at 4 or 8 bit)
#if (LCD_BUS == 4 )
//Read high byte
highbits = LCD_PORT_DATA & LCD_IO_DMASK;
LCD_EN = LCD_DISABLE;
delay_us(1);
LCD_EN = LCD_ENABLE;
//Read low byte
byteDDRAM = ((LCD_PORT_DATA & LCD_IO_DMASK) >> 4);
byteDDRAM |= highbits;
#else
byteDDRAM = LCD_PORT_DATA;
#endif
LCD_EN = LCD_DISABLE;
LCD_RS = LCD_CMD;
LCD_IO_DATA &= ~LCD_IO_DMASK;
//Sets port lines as output
return (byteDDRAM);
//Returns the read character
}
//
//5k) Move the cursor to the indicated line and row; the index starts from 1
void lcdsetcurs(uchar row, uchar col)
{
unsigned char pos;
//Controls correctness of the line and row values
if (row == 0)
row = 1;
if (col == 0)
col = 1;
if (row > LCD_ROWS)
row = LCD_ROWS;
if (col > LCD_COLS)
col = LCD_COLS;
//Sets the base address
switch (row)
{
case 1:
pos = LCD_ADDRESS_ROW1;
break;
case 2:
pos = LCD_ADDRESS_ROW2;
break;
case 3:
pos = LCD_ADDRESS_ROW3;
break;
case 4:
pos = LCD_ADDRESS_ROW4;
break;
}
lcdcommand(LCD_SET_ADDRESS | (pos+col-1));
}
//
//5l) Returns the current cursor's position line, row
void lcdgetcurs (uchar *row, uchar *col)
{
unsigned char curAdd;
unsigned char pos;
//Reads cursor's address
curAdd = lcdread(LCD_CMD);
//Mask for determine the row address this can be 00h, 10h, 40h, 50h
pos = (curAdd & 0x50);
switch(pos)
{
case LCD_ADDRESS_ROW1:
*row = 1;
*col = curAdd - LCD_ADDRESS_ROW1 + 1;
break;
case LCD_ADDRESS_ROW2:
*row = 2;
*col = curAdd - LCD_ADDRESS_ROW2 + 1;
break;
case LCD_ADDRESS_ROW3:
*row = 3;
*col = curAdd - LCD_ADDRESS_ROW3 + 1;
break;
case LCD_ADDRESS_ROW4:
*row = 4;
*col = curAdd - LCD_ADDRESS_ROW4 + 1;
break;
}
}
This is the routine that manages the serial communication:
//Title: gest_seriale_100.c
//Author: najro.prestato
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: RS232 management module:
// Communication protocol -> STX CMD DATI ETX
// Commands managed -> MI: Visualize on the display the ASCII string
// contained in DATI
// -> MA: sends to the serial an ASCII string
// contained in DATI
//
//1: Directives for the compiler
#include "sfr62.h"
#include "global.h"
#include "gest_lcd.h"
#include "messaggi_I.h"
#include "gest_seriale.h"
//2: Local Variables
union registro flagrx0;
union registro flagtx0;
unsigned char bufrx0[cBUFRX0];
unsigned char buftx0[cBUFTX0];
unsigned char pibufrx0,pubufrx0;
unsigned char bufpk0[cBUFPK0];
unsigned char lenpkrx0;
unsigned char statopkrx0;
unsigned char bytetx0,bytetxed0,tmrcmdmatx0;
unsigned char r0uart,r1uart,r2uart;
//3: Local functions prototypes
void gest_seriale(void);
void check_bufrx0(void);
void ela_bufpk0(void);
void pktx0(void);
//4: Serial Management Module
void gest_seriale(void)
{
//Verify if a new data package has arrived on bufrx0
check_bufrx0();
//Elaborate an eventual package extrapolated by buffer rx0(bufpk0)
ela_bufpk0();
//Sends data/reply through buftx0
pktx0();
}
//5: Local Function Codes
//
//5a) Function extrapolation package from buffer RX0
void check_bufrx0(void)
{
unsigned char datorx;
//Verify if there is any data to elaborate
while (pibufrx0 ^ pubufrx0)
{
//acquire data from serial
datorx=bufrx0[pubufrx0];
pubufrx0++;
//verify if the index is for reseting (buffer circolare)
if (pubufrx0 > cBUFRX0-1)
pubufrx0 = 0;
//analize acquired data
switch (datorx)
{
//research cLF without to have cSTX
//NB: This happens when waiting the echo of a command
// from a remote system ex: MA
case cLF:
//if STX not received
if (!flagrx0.bit.FSTX)
{
if (lenpkrx0 > 2)
{
if ( (bufpk0[lenpkrx0-1]==cCR)
&& (bufpk0[lenpkrx0-2]>0x19)
&& (bufpk0[lenpkrx0-3]>0x19))
{
bufpk0[0]=bufpk0[lenpkrx0-3]; //
bufpk0[1]=bufpk0[lenpkrx0-2]; //
flagrx0.bit.FPKRX=1;
//found identified end package rx
lenpkrx0=0; //reset data package counter
}
}
}
//If this is a non valid character and
//in specific it has to restart the cycle
else
{
lenpkrx0=0;
flagrx0.bit.FSTX=0;
}
break;
//research start of package
case cSTX:
flagrx0.bit.FSTX=1;
//found identified start of package rx
lenpkrx0=0;
//reset data package counter
break;
//research end of package
case cETX:
//if not received flag of the head of the package discard this ETX
if (flagrx0.bit.FSTX)
{
//verify that it has been found at least 'cNUMRXVAL'
//given among STX and ETX
if (lenpkrx0 < cNUMRXVAL)
{
flagrx0.bit.FSTX=0;
//declares not found identified start package rx
lenpkrx0=0;
//reset data package counter
}
else
{
flagrx0.bit.FPKRX=1;
//found identified end of package rx
flagrx0.bit.FSTX=0;
//reset flag identified start package rx
}
}
break;
//Data acquisition
default:
//if not received flag start package discard this ETX
if (flagrx0.bit.FSTX)
{
//Verify if received a non valid character (<20h)
if (datorx > 0x19)
{
//memorize package in dedicated buffer
bufpk0[lenpkrx0]=datorx;
lenpkrx0++;
if (lenpkrx0 > cBUFPK0-1)
lenpkrx0 = 0;
}
//If no discard all
else
{
lenpkrx0=0;
flagrx0.bit.FSTX=0;
}
}
else
{
//Memorize data that could be of an eventual
//response from the remote system (see case cLF: )
bufpk0[lenpkrx0]=datorx;
lenpkrx0++;
}
break;
}
}
}
//
//5b) Function elaboration package buffer RX0 (bufpk0)
void ela_bufpk0(void)
{
unsigned char wki,wkj;
switch(statopkrx0)
{
//Command Recognizing
case 0:
if (flagrx0.bit.FPKRX==1)
{
//Verify for commands Mx
if (bufpk0[0]=='M')
//recognized command 'M'
statopkrx0=1;
//Reinit if no valid command group it is identified
else
{
flagrx0.bit.FPKRX=0;
//reenable RX on RS232
statopkrx0=00;
//turn to state 0
}
}
break;
//Commands Mx
case 1:
//Verify for subcommand MI
if (bufpk0[1]=='I')
{
statopkrx0=10;
break;
}
//Verify for echo command MA
else if (bufpk0[1]=='A')
{
statopkrx0=11;
break;
}
//Reinit if no valid subcommand Mx identified
else
{
flagrx0.bit.FPKRX=0;
//reenable RX on RS232
statopkrx0=00;
//turn to state 0
}
break;
//Elaborate command MI
case 10:
//Reinit buffer indexes lcd rx if new message to be aquired
rowlcdrx=0;
cullcdrx=0;
prowlcdrx=00;
irowlcdrx=00;
//Clean buffer display visualisation
clearbuflcdrx();
//Enable backlight dislpay
tmronlcd=cTMRONLCD;
//Prepare buffer lcd rx. NB: substract 2 from lenpkrx0 to consider 'MI'
for (wki=2; wki < (lenpkrx0); wki++)
{
//Load data in LCD buffer already organized in line/rows
if ((bufpk0[wki] != '[') && (bufpk0[wki] != ']'))
{
//NB: Use wki+2 to discharge initial 'MI'
buflcdrx[rowlcdrx][cullcdrx]= bufpk0[wki];
cullcdrx++;
if (cullcdrx >= cCULLCDRX)
{
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
}
else
{
//Hexadecimal string management
//If [0D]:
if ( (bufpk0[wki] == '[')
&& (bufpk0[wki+1]=='0')
&& ((bufpk0[wki+2]=='D') || (bufpk0[wki+2]=='d'))
&& (bufpk0[wki+3]==']') )
{
unsigned char wkj;
if (cullcdrx < (cCULLCDRX-1))
{
for (wkj=cullcdrx; wkj < cCULLCDRX; wkj++)
buflcdrx[rowlcdrx][wkj] = ' ';
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
wki+=2;
}
//If [xx]:
else
{
if ( (bufpk0[wki] == '[') && (bufpk0[wki+3]==']') )
{
buflcdrx[rowlcdrx][cullcdrx] = ' ';
cullcdrx++;
if (cullcdrx > cCULLCDRX)
{
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
wki+=2;
}
}
}
}
flaglcd.bit.FBLRX=1; //Declare message for available LCD
flagrx0.bit.FPKRX=0; //Free RX0 serial
statopkrx0=00; //Wait new package
break;
//Ricezione echo comando MA
case 11:
flagrx0.bit.FPKRX=0; //Free RX0 serial
statopkrx0=00; //Wait new package
flaglcd.bit.FBLTX=1; //Declare echo received command
break;
//No valid/known command
default:
flagrx0.bit.FPKRX=0; //reenable RX0
statopkrx0=00; //turn to state 0
break;
}
}
//
//5c) Function send data to buftx0
void pktx0(void)
{
//Verify if package ready && UART available
if ((flagtx0.bit.FTXAT==1) && (ti_u0c1==1))
{
if (flagtx0.bit.FTXST==0)
{
flagtx0.bit.FTXST=1; //Declare STX sent
u0tbl=cSTX; //Transmit STX (start of package)
bytetxed0=00; //Reset counter sent data to uart
}
else
{
if (flagtx0.bit.FTXDA==0)
{
u0tbl=buftx0[bytetxed0];
bytetxed0++;
if (bytetxed0==bytetx0)
{
flagtx0.bit.FTXDA=1; //declare tx data
}
}
else
{
if (flagtx0.bit.FTXET==0)
{
flagtx0.bit.FTXET=1; //declare ETX sent
u0tbl=cETX; //transmit ETX (end of package)
}
else
{
flagtx0.bit.FTXAT=0;
//declares package not available
}
}
}
}
}
The schematic

Component list
Item Qty Reference Part ________________________________________________________ 1 8 C1,C4,C5,C6,C8, 1uF C9,C10,C13 2 3 C2,C3,C7 0,1uF 3 2 C11,C12 22pF 4 6 D1,D3,D4,D5,D6,D7 BYD17D 5 1 D2 LGR971 6 1 J1 CON8 7 1 J2 DISPLAY 16x2 8 1 J3 MOLEX 53261-1290 9 1 J4 MOLEX MICRO-FIT 10 1 Q1 BCX 54-16 11 1 Q2 MMBT2222 12 1 R1 2K2 13 4 R2,R3,R19,R21 4K7 14 4 R4,R5,R6,R7 100K 15 5 R8,R12,R13,R14,R15 1K 16 6 R9,R11,R16,R18,R20,R25 47K 17 2 R10,R24 10 18 1 R17 0 19 2 R22,R23 10K 20 1 U1 M30624FGPFP 21 1 U2 ST232BD 22 1 U3 DS1818 23 1 U4 24LC16 24 1 Y1 4 MHz
I didn't talk about the power supply because you can use any other power supply from other applications as long as it provides 5Vdc. I'm looking forward to your comments or questions.
Download the complete PDF documentation --->> DOWNLOAD
- Emanuele's blog
- 12495 reads





M16C Microcontroller Renesas
M16C uses a Renesas 16 bit microcontroller? Or a 32 bit?
Renesas M16C is a 16 bit
Renesas M16C is a 16 bit microcontroller. M32 or SH are 32 bit
Post new comment