Interfacing LCD with PIC Microcontroller – Hi Tech C
Contents
16×2 Character LCD is a very basic LCD module which is commonly used in electronics projects and products. It contains 2 rows that can display 16 characters. Each character is displayed using 5×8 or 5×10 dot matrix. It can be easily interfaced with a microcontroller. In this tutorial we will see how to write data to an LCD with PIC Microcontroller using Hi-Tech C Compiler. Hi-Tech C has no built in LCD libraries so we require the hardware knowledge of LCD to control it. Commonly used LCD Displays uses HD44780 compliant controllers.
This is the pin diagram of a 16×2 Character LCD display. As in all devices it also has two inputs to give power Vcc and GND. Voltage at VEE determines the Contrast of the display. A 10K potentiometer whose fixed ends are connected to Vcc, GND and variable end is connected to VEE can be used to adjust contrast. A microcontroller needs to send two informations to operate this LCD module, Data and Commands. Data represents the ASCII value (8 bits) of the character to be displayed and Command determines the other operations of LCD such as position to be displayed. Data and Commands are send through the same data lines, which are multiplexed using the RS (Register Select) input of LCD. When it is HIGH, LCD takes it as data to be displayed and when it is LOW, LCD takes it as a command. Data Strobe is given using E (Enable) input of the LCD. When the E (Enable) is HIGH, LCD takes it as valid data or command. The input signal R/W (Read or Write) determines whether data is written to or read from the LCD. In normal cases we need only writing hence it is tied to GROUND in circuits shown below.
The interface between this LCD and Microcontroller can be 8 bit or 4 bit and the difference between them is in how the data or commands are send to LCD. In the 8 bit mode, 8 bit data and commands are send through the data lines DB0 – DB7 and data strobe is given through E input of the LCD. But 4 bit mode uses only 4 data lines. In this 8 bit data and commands are splitted into 2 parts (4 bits each) and are sent sequentially through data lines DB4 – DB7 with its own data strobe through E input. The idea of 4 bit communication is introduced to save pins of a microcontroller. You may think that 4 bit mode will be slower than 8 bit. But the speed difference is only minimal. As LCDs are slow speed devices, the tiny speed difference between these modes is not significant. Just remember that microcontroller is operating at high speed in the range of MHz and we are viewing LCD with our eyes. Due to Persistence of Vision of our eyes we will not even feel the speed difference.
Hope that you got rough idea about how this LCD Module works. Actually you need to read the datasheet of HD44780 LCD driver used in this LCD Module to write a Hi-Tech C program for PIC. But we solved this problem by creating a header file lcd.h which includes all the commonly used functions. Just include it and enjoy.
Functions in lcd.h
Lcd8_Init() & Lcd4_Init() : These functions will initialize the LCD Module connected to the following defined pins in 8 bit and 4 bit mode respectively.
8 Bit Mode :
#define RS RB6 #define EN RB7 #define D0 RC0 #define D1 RC1 #define D2 RC2 #define D3 RC3 #define D4 RC4 #define D5 RC5 #define D6 RC6 #define D7 RC7
4 Bit Mode :
#define RS RB2 #define EN RB3 #define D4 RB4 #define D5 RB5 #define D6 RB6 #define D7 RB7
These connections must be defined for the working of LCD library.
Lcd8_Clear() & Lcd4_Clear() : Calling these functions will clear the LCD Display when interfaced in 8 Bit and 4 Bit mode respectively.
Lcd8_Set_Cursor() & Lcd4_Set_Cursor() : These functions set the row and column of the cursor on the LCD Screen. By using this we can change the position of the character being displayed by the following functions.
Lcd8_Write_Char() & Lcd4_Write_Char() : These functions will write a character to the LCD Screen when interfaced through 8 Bit and 4 Bit mode respectively.
Lcd8_Write_String() & Lcd4_Write_String() : These functions are used to write strings to the LCD Screen.
Lcd8_Shift_Left() & Lcd4_Shift_Left() : These functions are used to shift the content on the LCD Display left without changing the data in the display RAM.
Lcd8_Shift_Right() & Lcd4_Shift_Right() : Similar to above functions, these are used to shift the content on the LCD Display right without changing the data in the display RAM.
8 Bit Mode
Circuit Diagram
Hi-Tech C Code
#include<htc.h> #include<pic.h> #define RS RB6 #define EN RB7 #define D0 RC0 #define D1 RC1 #define D2 RC2 #define D3 RC3 #define D4 RC4 #define D5 RC5 #define D6 RC6 #define D7 RC7 #define _XTAL_FREQ 8000000 #include "lcd.h" void main() { int i; TRISB = 0x00; TRISC = 0x00; Lcd8_Init(); while(1) { Lcd8_Set_Cursor(1,1); Lcd8_Write_String("electroSome LCD Hello World"); for(i=0;i<15;i++) { __delay_ms(1000); Lcd8_Shift_Left(); } for(i=0;i<15;i++) { __delay_ms(1000); Lcd8_Shift_Right(); } Lcd8_Clear(); Lcd8_Set_Cursor(2,1); Lcd8_Write_Char('e'); Lcd8_Write_Char('S'); __delay_ms(2000); } }
4 Bit Mode
Circuit Diagram
Hi-Tech C Code
#include<htc.h> #include<pic.h> #define RS RB2 #define EN RB3 #define D4 RB4 #define D5 RB5 #define D6 RB6 #define D7 RB7 #define _XTAL_FREQ 8000000 #include "lcd.h" void main() { int i; TRISB = 0x00; Lcd4_Init(); while(1) { Lcd4_Set_Cursor(1,1); Lcd4_Write_String("electroSome LCD Hello World"); for(i=0;i<15;i++) { __delay_ms(1000); Lcd4_Shift_Left(); } for(i=0;i<15;i++) { __delay_ms(1000); Lcd4_Shift_Right(); } Lcd4_Clear(); Lcd4_Set_Cursor(2,1); Lcd4_Write_Char('e'); Lcd4_Write_Char('S'); __delay_ms(2000); } }
Note : Don’t forget to add lcd.h to Header files before building.
You can download the header file lcd.h, Hi-Tech C and Proteus files here…
Did you tried adjusting contrast ?
First of all, thank you for this tutorial.
I tried it with PIC18F25K22 and I see only black rectangles.
Does anybody have an idea?
Thanks
John
hi.
i got the following error. could you please give me a solution.
thanks.
hi
i have error
first row full black box only displaying
how to solve this error??
I want to use C for coding and run multiple tasks at the same time. Here I hit the wall. In the code above, you use a function __delay_ms(xx) which stuck the controller for xx mS. Something I realty don’t want. I want to set a time delay and pursue other tasks. Later when the processor is free I will check if the delay expired. If it is, move ahead, set a new delay, set a pointer where I am with this particular task and get out to the next check. Please give me some suggestions or links how to move from mono- to “multi-task” with PIC
You meant an integer variable ?? You can use sprintf for that.
hello I was wondering
how can you print the value assigned to a variable???
What errors ?
hello sir,i have used your code of lcd but the header file lcd.h gives error, can you please suggest me the solution
the lcd does not display any data using 16f877a
Want the code for questions no.b
build fine, placed in proteus fine lighting up i can see E pin and data pins getting power but not seeing any letter ???? and no idea how to debug
Hello If I want to add an LCD display like this one to my PIC18f4455.
The steps are the same or they differ from your PIC?I want to do this
for a project at my univeristy. This is the schematic of my pic
Hello If I want to add an LCD display like this one to my PIC18f4455. The steps are the same or they differ from your PIC?I want to do this for a project at my univeristy.
Hi Ligo,
Could you please briefly explain the function of the header file as well?
Like each subroutine and its action in one or two line.
-Thanks
HELLO MY LCD IS NOT DISPLAYING PRACTICALLY. DONT KNOW WHY. PLEASE NEED HELP AS CONCERNING CONNECTION
bull shit the coding is wrong change it
Pleases .the LCD is on but no show me any data
I Opened files atached and run in proteus…and…displays nothing ;(
Try opening a new project in a new folder.
Send ASCII value of degree.
Dear Sir,
I found this error after debugging it. Please kindly guide us.
sir,
How to put a degree symbol in lcd using PIC16F877a. I am using MPlab IDE.
Great Article. Unfortunately, I found this article too late – I already found the answer on another service. I just filled out a form with an online software. It looked much better typed than hand-written. I used
http://goo.gl/OeiYxJ
and it’s very easy to use.It is already there in the download.
hello, thanks for the information. The above code works well on my board. Will it be possible for you to share hi-tech compiler c code for lcd.h ?? thanks
help i’m using a assembly language program
create a program that makes the LEDs light up in the order D5, D5, D7, D1, D4, D2, D4, and then repeats this sequence continuously.
Each LED should be ON for a period of approximately 0.5 second before turning OFF for the next 0.5 second so that they are clearly visible. Then the next LED in the sequence takes over.
Please use our forums ( https://electrosome.com/forums ) for technical support not directly related to above tutorial.
Note : forums are for technical support only. We can’t freely develop projects/programs for all those who contacts us. We will provide free technical support only. If you need us to develop your project / code. Please hire one of our engineers. It will help us to survive.
my project is anti-theft vehicle security.we want attaching keypad to enter the password.if it is not correct(3 trials),the message is send to owner through gsm, simultaneosly the door will be locked until the owner to open the car by using original key.what we do?,plz help me,,,and provide a code for it.we use pic18f4580 with mplabide
sir i need to know the c code of programming pic16f690 with lcd and adc module
Hi for everyone,
I’d like to remark, I just a beginner in programming. I suppose, I found the problem for many person’s non-working project. Here on the website the source code seems OK, but the downloadable part isn’t. Why? See my attached picture. On left hand side you can see the website and next to them on right hand side is the downloaded source code. As you can see, the downloaded source code referring the port D4-D7 as data lines against of B4-B7. The schematic is OK, matching to the website source code.
Next serious issue is the clock frequency. Here on the website is the right value, 8MHz (#define _XTAL_FREQ 8000000) and the downloaded has wrong, 20MHz (#define _XTAL_FREQ 20000000).
I think is the best solution at the moment is build the project as schematic shows and copy the source code from here from the website, if you don’t want to type manually.
I’ll be back soon after modifying the downloaded source code. I’ll try first the 4 bit mode.
I want to build a wireless temprature monitor using pic and xbee…….please guide me!
Hi,
Sorry I don’t understand what you are saying. Above define statements will not give errors.
Hi,
I am trying to interface a 16X2 LCD with PIC24FJ128GB202, and I am using the above code. i added the appropriate libraries in the program but unfortunately I am unable to define on which registers the pin corresponds i.e. all the #define RS RB2
#define EN RB3
#define D4 RB4
#define D5 RB5
#define D6 RB6
#define D7 RB7
are giving an error as : newmain.c:16:3: error: ‘D4’ undeclared (first use in this function)
newmain.c:16:3: note: each undeclared identifier is reported only once for each function it appears in
newmain.c:21:3: error: ‘D5’ undeclared (first use in this function)
newmain.c:26:3: error: ‘D6’ undeclared (first use in this function)
newmain.c:31:3: error: ‘D7’ undeclared (first use in this function)
I am very confused, any help will appreciated.
It is just only a warning, you may ignore it.
You may solve it by typecasting const string.
Hi. I’m using MPLAB X with XC8 and when I try to build the project I get the following warning “check.c:63: warning: (359) illegal conversion between pointer types pointer to const unsigned char -> pointer to unsigned char” on all Lcd8_Write_String(“”) lines. Other than that, great code. Thanks.
It is clearly describe in the above article.. it for 8 bit interfacing.
whats this used for ?
Lcd8_
It should work… make sure that your connections are correct..
Just try LED Blinking .. in the same project.
Yes.
But not working. to configure I used below conigure code
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_ON & BOREN_ON & CP_OFF & CPD_OFF & LVP_OFF & DEBUG_OFF);
Yes.
But not working. to configure I used below conigure code __CONFIG(FOSC_XT & WDTE_OFF & PWRTE_ON & BOREN_ON & CP_OFF & CPD_OFF & LVP_OFF & DEBUG_OFF);
Best regards
Kawser
Did you set the configuration bits ?
Please read the article : https://electrosome.com/blinking-led-pic-microcontroller-hi-tech-c/
for more details.
I download this project.But Hardware does not work.I check again and again but do not find the fault.
Thanks for your reply.
Best regards
Kawser
Delay ? Where ?
You can download the complete project files above.
Hello,
Really A Great Work.
But I could not compile with
__delay_ms(1000);
Ravi
Hi, I can not find the lcd.h header file. Please help me…
Your compiler is not getting your micro controller configuration i gues.
I tested both codes before uploading. There is no maximum size.. It depends on pic memory.
ur 8 Bit Interfacing code work fine on Proteus ,
but 4 Bit Interfacing code not work on Proteus why ?
First copy the file lcd.h to your project directory… then add it to your project in the IDE as shown above..
When I build the code I have this problem…”can’t open include file “lcd.h” : No such file or derectory..I had add the header..plz tell me hw can I fix this
Sorry, I haven’t yet used C30 compiler..
Hello plz i would like to use LCD to iplay ‘helo world” but by using C in Mplab and C30 commpiler
Try opening a new project in a new folder.. include the header file and your source file..
Hello, thanks for this info.
I am having a problem simulating this with Proteus i keep getting this error:
“picc.exe
–pass1 –errformat=”Error at file %%f line %%l column %%c: (%%n) %%s”
–warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s”
–msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s”
-D_XTAL_FREQ=1000000 -G –chip=16F877A -O”main.p1″ “../main.c”
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Warning at file ../main.c line 22 column 26: (111) redefining preprocessor macro “_XTAL_FREQ” ((null): 0)
Warning at file ../main.c line 31 column 1: (361) function declared implicit int
Warning at file ../main.c line 34 column 1: (361) function declared implicit int
Warning at file ../main.c line 35 column 1: (361) function declared implicit int
Warning at file ../main.c line 39 column 1: (361) function declared implicit int
Warning at file ../main.c line 44 column 1: (361) function declared implicit int
Warning at file ../main.c line 46 column 1: (361) function declared implicit int
Warning at file ../main.c line 48 column 1: (361) function declared implicit int
picc.exe
–output=mcof –errformat=”Error at file %%f line %%l column %%c: (%%n)
%%s” –warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s”
–msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s” -G
–chip=16F877A -O”Debug.cof” “main.p1” “lcd.p1″
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error at file line 0 column : (500) undefined symbols:
_Lcd8_Write_Char(Debug.obj) _Lcd8_Write_String(Debug.obj)
_Lcd8_Init(Debug.obj) _Lcd8_Clear(Debug.obj) _Lcd8_Shift_Left(Debug.obj)
_Lcd8_Set_Cursor(Debug.obj) _Lcd8_Shift_Right(Debug.obj)
make: *** [Debug.cof] Error 1
Error code 2”
I used same code for the 8bit mode and i use same circuit with it . please tell me what to do.
Many Thanks
Nwafor Austine
Hello, thanks for this info.
I am having a problem simulating this with Proteus i keep getting this error:
“picc.exe –pass1 –errformat=”Error at file %%f line %%l column %%c: (%%n) %%s” –warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s” –msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s” -D_XTAL_FREQ=1000000 -G –chip=16F877A -O”main.p1″ “../main.c”
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Warning at file ../main.c line 22 column 26: (111) redefining preprocessor macro “_XTAL_FREQ” ((null): 0)
Warning at file ../main.c line 31 column 1: (361) function declared implicit int
Warning at file ../main.c line 34 column 1: (361) function declared implicit int
Warning at file ../main.c line 35 column 1: (361) function declared implicit int
Warning at file ../main.c line 39 column 1: (361) function declared implicit int
Warning at file ../main.c line 44 column 1: (361) function declared implicit int
Warning at file ../main.c line 46 column 1: (361) function declared implicit int
Warning at file ../main.c line 48 column 1: (361) function declared implicit int
picc.exe –output=mcof –errformat=”Error at file %%f line %%l column %%c: (%%n) %%s” –warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s” –msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s” -G –chip=16F877A -O”Debug.cof” “main.p1” “lcd.p1″
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error at file line 0 column : (500) undefined symbols:
_Lcd8_Write_Char(Debug.obj) _Lcd8_Write_String(Debug.obj) _Lcd8_Init(Debug.obj) _Lcd8_Clear(Debug.obj) _Lcd8_Shift_Left(Debug.obj) _Lcd8_Set_Cursor(Debug.obj) _Lcd8_Shift_Right(Debug.obj)
make: *** [Debug.cof] Error 1
Error code 2”
I used same code for the 8bit mode and i use same circuit with it . please tell me what to do.
Many Thanks
Nwafor Austine
Hello, I can’t guess what is the problem without enough information..
hi i am using the same code pic16f883 and it is not working, please help
Yes, I think so..
CAN I GO FOR THE SAME CODING WITH XC8 COMPILER
Hey, Thank you so much for sharing this! I do have a question though, can you display the value of a variable via LCD?
For example if I define counter as a variable and change it through out my code based on the user’s input, can I display the value of ‘counter’ directly with the LCD? (Of course, I can always try to find what the counter is and send the numbers one at a time, but that seems like a very inefficient way to do it & it’s not always easy to determine what the numbers will be)
Hi,
I have PICDEM™ 2 Plus Demonstration board and use PIC16F1937. I use your code and did change the output port to associate the board layout, but I always receive first line black box, I don’t understaqnd what;s going on, can you help me for this?
Thanks
hi..i got two inputs from the led..and output as lcd display..if the 1st led lights up,the lcd will display ‘in’ and 2nd led lights up,lcd will display ‘out’,if both led lights up at the same time the lcd will show blank display n every displayed result will be reset after 10 seconds..im using PIC16F877.
this is the coding for lcd display
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
void main() {
TRISB = 0x00;
PORTB = 0x00;
Delay_ms(500);
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
LCD_Out(1,1,”Smart Badminton”);
LCD_Out(2,2,”Line Call”);
while(1){
Delay_ms(3000);
LCD_Out(1,1,”In”);
Delay_ms(3000);
LCD_Out(1,1,”Out”);
Delay_ms(3000);
LCD_Cmd(_LCD_CLEAR);
}
}
i dont know how to do the coding for the led as the input in order to display the output as in,out,blank display and reset after 10 seconds after the result displayed..any idea??thank you..
could you help me with this? is this compatible for pic16f877a?
Define LOADER_USED 1
Define OSC 4 ‘ Core is running at 4MHz
‘ Define LCD registers and bits
Define LCD_DREG PORTB
Define LCD_DBIT 0
Define LCD_RSREG PORTB
Define LCD_RSBIT 4
Define LCD_EREG PORTB
Define LCD_EBIT 5
‘ Define ADCIN parameters
DEFINE ADC_BITS 10 ‘ Set number of bits in result
DEFINE ADC_CLOCK 3 ‘ Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ‘ Set sampling time in uS
LED var PORTB.7
Relay var PORTD.0
SW1 var PORTE.0
SW2 Var PORTE.1
‘ —–[ Constants ]——————————————————-
LcdCmd con $FE
LcdLine1 con $80
LcdLine2 con $C0
‘ Declare variables
i var byte
adVal var word
lmTemp var word
targetTemp var byte
TRISA = %11111111 ‘ Set PORTA to all input
ADCON1 = %10000010 ‘ Set PORTA analog and right justify result
Pause 100 ‘ Wait for LCD to start up
read 0, targetTemp ‘READ FROM PIC EPROM ADDRESS 0
low led
low relay
Lcdout lcdcmd, 1
MainLoop:
toggle led
ADCIN 0, adval ‘ANALOG VALUE FROM LM35
lmtemp = adval * 500 ‘CONVERT DIGITAL VALUE TO DECIMAL
lmtemp = lmtemp / 1024
Lcdout lcdcmd, lcdline1, “LM35:”, dec2 lmtemp,223, “C” ‘223 = SIMBOL 0 BG C
Lcdout lcdcmd, lcdline2, “TARGET: “, dec2 targettemp,223,”C”
if sw1 = 0 then ‘SUIS -1
while sw1 = 0
wend
if targettemp > 0 then
targettemp = targettemp – 1
else
targettemp = 99
endif
write 0, targettemp
endif
if sw2 = 0 then ‘SUIS +1
while sw2 = 0
wend
if targettemp < 99 then
targettemp = targettemp + 1
else
targettemp = 0
endif
write 0, targettemp
endif
if lmtemp < targettemp then 'IF MORE THAN TARGET THEN
high relay 'ON RELAY
Lcdout lcdcmd, lcdline2+13,"ON "
else
low relay 'OFF RELAY
Lcdout lcdcmd, lcdline2+13,"OFF"
endif
pause 250
Goto mainloop ' Do it forever
End
*** please help me :(((
Hai, this is similar with what I wrote for my program using LCD 16×2. However, after compiled, it said to be undefined identifier “RB4”.. why is that so? Please help me. Thank you.
don’t we need to connect pin number 16 and 15 ?
^library files actually
I need to use lcd8_out function and i need header file for that.Can anyone help me asap?
Please help me , how to read data from pic controller and it display to lcd
Thank you for replying…. Thank you sir
Sorry.. I haven’t yet used CCS C
hi will you give me small lcd display program using ccs compiler for pic 16f877a
Thanks for the feedback..
Thank you so much I understood LCD,it exactly work without any change
It is not a good logic… it executing following functions in a loop..
1. Read data from keypad
2. Display it in LCD
The data read from keypad is already known to microcontroller .. so no need to read again it from LCD…
I have seen a pic lock project that reads the user entered password directly from lcd.
ie, it ask the user for enter the password, then a loop reads the button presses and display the charactor on the lcd, then it reads the whole string from lcd. they didn’t provide the code.
Why do you read from LCD??… all data on the LCD are written by our program.. so it is known to us… not required to read data from it..
How to read from lcd?
The difference is cleared described in the above article.. Please read it..
Can you please elaborate??
Check the comments below..
what is the difference between 8bit n 4bit mode?
how to print ascii data in lcd
Thank you so much!!
An integer can be displayed …. digit by digit.. means character by character…
if ‘a’ is a single digit number… ie (0,1,2,3…. 9)..
it can be displayed by..
Lcd8_Write_Char(a+48); // in 8 bit mode
or
Lcd4_Write_Char(a+48); // in 4 bit mode…
Where 48 is the ASCII value of zero (0)…
How to printf (“%d”,i); i∈N. Help me!! Thanhk you so much!
Thank you so much!!
You can download it from the above download link….
You must login/register (free) to download it..
Can u pls give me the lcd.h header file..
Don’t bother about.. it.. Those are default header files.. that comes with hi-tech c..
what is htc.h and pic.h
Thanks for the feedback..
FANTASTIC!!
Very good tutorial! You are the best! Ever!
Please, keep up this good work with Hi-Tech C.