This project shows you how to create a serial LCD module that you can drive from any serial RS232 interface.
You may be asking yourself why is this project using RS232 when computers are no longer even produced with a serial port as standard?
There are three reasons:
The last point means that signal transmission can be made fairly error free and robust (although you can achieve higher data rates and lower error rates by using the full RS232 spec). However it is probably better to move to a multi-drop interface such as RS485.
Since the hardware module is built in it becomes super-easy to use the internal UART which can use interrupts allowing fast and transparent operation.
The only problem now becomes what to do about the interface in the PC and you either buy an RS232 to USB adaptor cable that presents an RS232 interface as a COM port in the usual way at the PC but allows it to be plugged into a USB port or you can use a Digital to Serial USB converter. This last one does away with RS232 signals altogether and instead provides digital RX/TX signals to plug straight into the microcontroller i.e. you miss out the MAX232 chip. Ultimately both work fine and both look the same at the PC side.
Here is some more information on Serial RS232 to USB adaptors.
The design here uses a pure ASCII command set so you can control it easily from a terminal program such as Tera Term (download from web = free).
There are no 'odd' command sequences such as 0xef to define a command - you
can type all commands at the terminal interface making it very easy to use i.e.
this is a purely text based control system.
If you want to use it as a debugging terminal for your PIC projects then it
makes sense to remove the level translator and just use the 0-5V input
otherwise you would end up having two level translators for no real reason!
Note: Using it like this you will need to
invert the RS232 output data so you either need an inverter chip if driven from
the built in USART or you can drive it using a software USART (The transmitter
part anyway) since you will have full control over the output signal.
Serial LCD Specification
Baud Rate | 9600 |
Crystal | 20Mhz -You can use a lower value xtal but must re-compile the files and set the clock value into the MikroC chip settings. |
Serial LCD Project Details
|
|
Compiler | Mikroelectronika MikroC compiler Free! |
Target | 16F877A (retargetable to other PICs that have enough pins and a built in USART). |
Software level | Easy. |
Software notes | Uses unget_char to reverse getchar action. |
Hardware level | easy. |
Hardware notes | No special notes. |
Project version | 1.01 |
Project files | Enter your details to get the Download Link and get the microcontroller newsletter: (Your email is safe it will
never be sold or rented). |
You can recompile the serial LCD files if you want examine code operation (using the built in simulator) or change the source code. Note the hex file is contained in the download.
All commands are prefixed with the hash character '#'. In all cases except
#X and #Y the single character following the '#' causes a command to execute.
For #X and #Y the decimal digits following (up to 2 digits) specify a
position on the display.
Note: for #X and #Y the top left position is
at 0,0.
You can use upper or lower case commands:
Serial LCD Commands | |
#C or #c | Clear screen |
#H or #h | Cursor Home |
#L or #l | Cursor Left |
#R or #r | Cursor Right |
#U or #u | Cursor Underline mode |
#B or #b | Cursor Block mode |
#I or #i | Cursor Invisible |
#F or #f | Display OFf |
#O or #o | Display On |
#Xnn or #xnn | Cursor X position (left nn=0) |
#Ynn or #ynn | Cursor Y position (top nn=0) |
#> or #. | Scroll display right (hash dot as easier to type!) |
#< or #, | Scroll display left (hash commaas easier to type!) |
## | Display a '#' character. |
To clear the display you would type:
#C
To set the cursor to block mode type:
#B
There must be at least two digits following the #X or #Y command unless the following command is not a digit.
All this means is that you can finish an X or Y commands by typing a letter
- if you type a digit the parser won't know if it is a digit to display or a
digit to specify the position.
Here is a cursor positioning example command sequence:
#H | Home | Sets cursor position to (0,0) - top left. |
#X3JFM | < Set X and print | Sets the X position to 3 and prints JFM (Note the cursor is only moved once the J is entered). |
You can also use the longer command:
#H#X00JFM
It does exactly the same thing but the cursor is immediately moved after the
'00' since the command parser knows that it is the end of the X cursor position
command as it only accepts 2 digits.
These commands are valid:
Command | Result |
#X10234 | Cursor x position is set to 10 and 234 is displayed. |
#Y1ABC | Cursor y position is set to 1 and ABC is displayed. |
#Y01ABC | Same as above. |
#X3HI | Cursor x position is set to 3 and HI is displayed.. |
#X03HI | Same as above. |
#Y0BYE | Cursor y position is set to 0 and BYE is displayed. |
If you enter any other ASCII text other than the '#' character then it is
displayed on the LCD and the cursor is advanced to the right.
Note: to display a '#' character enter it twice '##'.
The circuit simply consists of a PIC micro, ICSP interface, an RS232 level translator and an HD44780 LCD.
The software is contained in two files (note there are many more created by the compiler):
16F877A-serial-lcd.c
bit.h
bit.h contains bit manipulation macros.
Project Files
16F877A-serial-lcd.mcppi
Output files:
serial-lcd.hex
For a tutorial on compiling these files click here.
Initially a scrolling message is displayed using show_intro. When a serial input is detected the main program starts. All keys are now either text entry or commands.
An infinite loop keeps checking for key input. If the key is a hash symbol then the command is fetched using:
get_prefix_and_execute_command(&x,&y);
Otherwise the key value is displayed on the LCD at the current cursor position.
Note: the use of x and y addresses (&x,&y) to pass the variable address through to the called functions so that values of x and y in main() are updated (using pointers in the called functions).
get_prefix_and_execute_command calls execute_command which gets another key from the UART (or waits for one). If it matches a valid command then the appropriate code is executed to control the LCD. If not then UART1_unget_char is used to push the key back.
The most interesting commands in execute_command are #X and #Y which use get_and_Set_X and get_and_Set_Y, again using pointers (this time the address & de-reference is not used as px is a pointer that returns its address when invoked).
These functions both use get_2dig_num which gets more characters expecting digits - if it does not get them it pushes the key back again using UART1_unget_char.
These complementary functions are used in parsers (this program is a very small parser) where you need to look at the next character of the input to see if you want to continue. If you don't i.e. its not the character you were expecting then you use UART1_unget_char to put the current character into memory.
The function UART1_get_char always checks this memory first before getting a character from its normal input so the system works well - but you can only do one unget-char at a time. For more you would need an array of unget storage etc.
The routines let you avoid complicated look ahead algorithms or indexing - you can concentrate on the current character without knowing where an index is. For a bigger parser you work with complete words.
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.