Professional Documents
Culture Documents
com/print/51999
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:
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.
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"
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;
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
//1: Directives
#include "sfr62.h"
#include "global.h"
#include "S6A0069.h"
//
//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;
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;
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;
}
}
void gest_seriale(void);
void check_bufrx0(void);
void ela_bufpk0(void);
void pktx0(void);
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++;
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
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.
Trademarks