Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with code for HD44780 LCD initialization

Status
Not open for further replies.

smiles

Advanced Member level 4
Joined
Jul 27, 2007
Messages
110
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Activity points
2,096
Hi! I did this C code for initilazation LCD (16x2) and write some text on it, but nothing happen, pin 1 to GND, pin 2 to 5V, pin3 is 1V above GND
Used PIC16F877A, 4MHz crystal
Code:
void WrCmd2Lcd(char cmd);
void WrDat2Lcd(char data);
void InitLcd();
void Speech(char words,int position);
void main()
{
   char hello[]="HELLO WORLD!\n";

   #define   lcd_rs   PIN_B0
   #define   lcd_rw   PIN_B1
   #define   lcd_e   PIN_B2
   #define   lcd_cmd_wri   0x00
   #define   lcd_data_wri   0x01
   #define   lcd_set_function   0x38
   #define   lcd_set_visible   0x0F
   #define   lcd_set_shift   0x16
   #define   lcd_set_mode   0x06
   #define   lcd_set_home_address   0x00
   #define   lcd_clear   0x01
   #define   lcd_init   0x30

   set_tris_a(0x0f);
   set_tris_b(0x00);
   set_tris_c(0x00);
   set_tris_d(0x00); // to LCD D0-D7
   output_high(PIN_C0); //affect relay and it works well
   InitLcd();
   Speech(hello,0x00); //
}
void WrCmd2Lcd(char cmd)
{
   output_d(cmd);
   output_b(lcd_cmd_wri);
   output_high(lcd_e);
   #asm
   nop
   #endasm
   output_low(lcd_e);
}
void WrDat2Lcd(char data)
{
   output_d(data);
   output_b(lcd_data_wri);
   output_high(lcd_e);
   #asm
   nop
   #endasm
   output_low(lcd_e);
   delay_ms(1);
}
void InitLcd()
{
   delay_ms(16);
   WrCmd2Lcd(lcd_init);
   delay_ms(5);
   WrCmd2Lcd(lcd_init);
   delay_cycles(200);
   WrCmd2Lcd(lcd_init);
   delay_cycles(100);
   WrCmd2Lcd(lcd_set_function);
   delay_cycles(100);
   WrCmd2Lcd(lcd_set_visible);
   delay_cycles(100);
}
void Speech(char words,int position)
{
   char *textptr;
   textptr = words;
   WrCmd2Lcd(position);
   delay_ms(64);
   do
   {
   WrDat2Lcd(*textptr);
   *textptr++;
   }
   while(*textptr != '\n');
}

Do you see any wrong place of my initilazation ?
Thanks !!!
 

lcd init

Hello,

nothing happen(s) is somewhat unclear. You could see, e. g. if the display is initialized and the cursor appears, as you activated it. On first look, I see obvious errors only in the Speech() function, that should loop until a \0 terminator rather than \n (which never occurs). Also char words is incorrect, should be char *words. But I guess, you didn't post the original code, cause the latter could never compile without errors.

The issue could be also from a hardware fault, I would single step the code in ICD debugger and check all signals during execution steps.

Regards,
Frank
 

controller received data whilst busy

I test with Proteus simulation, it is okey, but I think "okey" here is just for the text appear on screen, and the code for initiation LCD is wrong, I don't sure :(
 

controller received command whilst busy

you have use #define within the main routine

dont do this
define all things at the very top of the code
any variables not local to just the main routine need to go here also

attached is an lcd driver

before use you need to #include this class

then in main you just need to call the init branch in the class
void LCD_INITIALMODE ( int CGCHARSET ); << this needs set to 1 or 2
to setup the cgram charset in use
i wrote this driver and have used it so i know it works

you can also find on this eboard the full source for comvdd ebox
there is the full c code there incase you need to see anything in it

try to study this code
 

    smiles

    Points: 2
    Helpful Answer Positive Rating
init lcd

From the misplaced #define you see, that this code never could have compiled without errors. At this point I stopped checking what else could be wrong.
 

hd44780 received data whilst busy

maybe .. however some compilers will allow redefinition within parenthasis
perhaps the bug as it is should be pointed out
to the makers of the c compiler that chap uses
i agree its a definate smoking bug
but not entierly wrong in logic esp when using micros and uc
and the need to not have to escape a main routine to run a re #define on ifdef
anyway the driver i wrote works fine and the command list is easy to expand
i only covered cgram and ddram and init
and not any special functions for some types of hitachi varients on this drivers chip
{like using two chip type lcds {easily changed though by adjusting the delays etc}
i also wrote a quickbuilder driver and lib for this class
i wonder what happened to this guy and if he sold and what he sold
and his wonderfull app
im glad for sure i have a copy and key as its fab...
for building quick ports and driver classes for ccs
and they are easily changed for hytec picc and sdcc
{sdcc changes are easy and sdcc is free}
if you get a copy of quickbuilder maybe even a crack as its disappeared {abandonedware so fair game i feel}
its a great tool
....
:D
here is a code i wrote up in c
its a good example of quickbuilders power
if you try to define the lower nibble of port b then its hard to do using standard c
if your already using interrupts on the higher nibble of port b
it seems masked to the main class even when you #define the pins
so.. this is a good solution for sure
the chip simply is a schmit flip flop X4 my pal uses for a control over 4 quickly switched scanning aids for his alarm all it does is switch on a high signal
with some functions and eeprom incase the power fails etc...
and i feel an example to us all if lcd is also part of the main class and interrupts are utilised on the same port
 

hd44780 init

VSMVDD said:
then in main you just need to call the init branch in the class
void LCD_INITIALMODE ( int CGCHARSET ); << this needs set to 1 or 2
to setup the cgram charset in use
Could you tell me why I should need to set up CGRAM when initiate LCD ?
Thanks !!!
 

hd44780 lcd

you dont have to set it up i did just becouse i needed it for my use
i used it for custom charicters to display level reading over 8 pots and as pointer type level

you can just remove the associated routines if you like

LCD_INITIALMODE ( int CGCHARSET ); this passes the cgram char set to use at init time

so just use
LCD_INITIALMODE ();

in the main routine before you enable global interrupts

attached is the same driver with cgram removed

remember this is a 4bit driver so needs only one port

just now its set to use port D

#define LCD_D0 PIN_D4
#define LCD_D1 PIN_D5
#define LCD_D2 PIN_D6
#define LCD_D3 PIN_D7
#define LCD_EN PIN_D3 //enable
#define LCD_RS PIN_D2 //reset
and uses d0-d3 only on the lcd display you should ground d4-d7
 

    smiles

    Points: 2
    Helpful Answer Positive Rating
lcd init

I had used some from your code, code is better (I test in Proteus and it notice nothing like "controller received command whilst busy") but LCD still not run, do you think the difference between frequency of LCD and Pic may be a reason ???
The circuit I connect for this LCD is completely like that (contrast pin connect to a varistor) **broken link removed**
Code:
[size=9]
   // MNEMONICS FOR BUTTONS
   #define   row1   PIN_A0
   #define   row2   PIN_A1
   #define   row3   PIN_A2
   #define   row4   PIN_A3
   #define   col1   PIN_D3
   #define   col2   PIN_D2
   #define   col3   PIN_D1
   #define   col4   PIN_D0
   // MNEMONICS FOR LCD
   #define   lcd_rs   PIN_B0
   #define   lcd_rw   PIN_B1
   #define   lcd_e   PIN_B2
   #define   lcd_cmd_wri   0x00
   #define   lcd_data_wri   0x01
   #define   lcd_busy_rd   0x02
   #define   lcd_set_function   0x38   //8 bit interface, 2 line mode, 5x7 dot format
   #define   lcd_set_visible   0x0F   //Display on, cursor underline on, cursor blink on
   #define   lcd_set_shift   0x16   //Cursor move, Right shift
   #define   lcd_set_mode   0x06   //Increment, display shift off
   #define   lcd_set_cgaddr   0x40
   #define   lcd_set_ddaddr   0x80
   #define   lcd_clr   0x01
   #define   lcd_init   0x30
   #include "D:\Pic16F877\MyProject\Doit\Doit.h"
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>

void LcdEnable();
void WrCmd2Lcd(char cmd);
void WrDat2Lcd(char data);
void InitLcd();
void Speech(char words,int position);
void LcdWait();
void LcdPutPar(int par);
void main()
{
   //INTRO OR GUIDED WORDS
   char hello[]="HELLO WORLD!\n";
   //PIC SET-UP PARAMETERS
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   // TODO: USER CODE!!
   set_tris_a(0x0f);
   set_tris_b(0x00);
   set_tris_c(0x00);
   output_high(PIN_C0);
   InitLcd();
   WrDat2Lcd("A");
//   for(;;)
   Speech(hello,lcd_set_ddaddr+0x40);
}
void LcdEnable()
{
   output_high(lcd_e);
   delay_us(10);
   output_low(lcd_e);
}
void WrCmd2Lcd(char cmd)
{
   set_tris_d(0x00);
   LcdPutPar(cmd);
   output_b(lcd_cmd_wri);
   LcdEnable();
//   LcdWait();
}
void WrDat2Lcd(char data)
{
   set_tris_d(0x00);
   LcdPutPar(data);
   output_b(lcd_data_wri);
   LcdEnable();
   LcdWait();
}
void InitLcd()
{
   output_low(lcd_e);
   delay_ms(125);
   WrCmd2Lcd(lcd_init);
   delay_ms(20);
   LcdEnable();
   delay_us(200);
   LcdEnable();
   delay_us(100);
   WrCmd2Lcd(lcd_set_function);
   delay_ms(10);
   WrCmd2Lcd(lcd_set_visible);
   delay_ms(10);
//   WrCmd2Lcd(lcd_clr);
//   delay_us(100);
   WrCmd2Lcd(lcd_set_mode);
   delay_ms(10);
//   WrCmd2Lcd(lcd_set_ddaddr);
//   delay_us(100);
}
void Speech(char words,int position)
{
   char *textptr;
   textptr = words;
   WrCmd2Lcd(position);
   LcdWait();
   delay_ms(64);
   do
   {
   WrDat2Lcd(*textptr);
   *textptr++;
   }
   while(*textptr != '\n');
}
void LcdWait()
{
   int status;
   set_tris_d(0xFF);
   output_b(lcd_busy_rd);
   do
   {
      output_high(lcd_e);
      status=input_d();
      output_low(lcd_e);
   }
   while(status & 0x80);   // test busy flag.
}
void LcdPutPar(int par)
{
    output_bit(PIN_D0,par & 0X01 );
    output_bit(PIN_D1,par & 0X02 );
    output_bit(PIN_D2,par & 0X04 );
    output_bit(PIN_D3,par & 0X08 );
    output_bit(PIN_D4,par & 0X10 );
    output_bit(PIN_D5,par & 0X20 );
    output_bit(PIN_D6,par & 0X40 );
    output_bit(PIN_D7,par & 0X80 );
}
[/size]
 

hd44780 controller received data whilst busy

PIC frequency doesn't matter, when it was made known to the compiler with #use delay() to get correct timing with built-in delay functions. You most likely did.

There must be some other yet unknown fault. If you have an ICD, you can single-step the code and check each action related to display interface.
 

    smiles

    Points: 2
    Helpful Answer Positive Rating
lcd init command

Hi, at last it runs :)
I change some in two function WrCmd2Lcd() and WrDat2Lcd(), more detail like in datasheet
Code:
void WrCmd2Lcd(char cmd)
{
   set_tris_d(0x00);
   output_low(lcd_rw);
   output_high(lcd_rs);
   output_d(cmd);
   output_low(lcd_rs);
   LcdEnable();
}
void WrDat2Lcd(char data)
{
   set_tris_d(0x00);
   output_high(lcd_rs);
   output_low(lcd_rw);
   output_low(lcd_rs);
   output_d(data);
   LcdEnable();
   output_high(lcd_rs);
   output_high(lcd_e);
}
and char words to char *words like FvM said
Now I get some problems with keypad, press and realese a button than a char displayed on screen, 4 columns and 4 rows, let each column "off" in order and check whether which row is "off" to get the character but PIC doesn't understand the code (it doesn't show "off" in order at each column), could you tell me what wrong with my code, thanks so much
Code:
...
void main()
{
   //INTRO OR GUIDED WORDS
   char hello[]="HELLO WORLD! ";
   char keyPressed;
   //PIC SET-UP PARAMETERS
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   // TODO: USER CODE!!
   set_tris_b(0x00);
   set_tris_c(0x00);
   InitLcd();
   WrDat2Lcd("A");
   play:
   keyPressed=OnRelease();
   if(keyPressed!=" ")
   {
      WrDat2Lcd(keyPressed);
   }
   goto play;
//   WrDat2Lcd("B");
//   Speech(hello,lcd_set_ddaddr+0x40);
}
....
char OnRelease()
{
   int i,j,k;
   int row[4]={PIN_A0,PIN_A1,PIN_A2,PIN_A3};
   int col[4]={PIN_D3,PIN_D2,PIN_D1,PIN_D0};
   char array[16]={'1','4','7','<','2','5','8','0','3','6','9','>','C','&','E','M'};
   set_tris_a(0xff);
   set_tris_d(0x00);
   loop:
   k=0;
   for(i=0;i<4;i++)
   {
   output_d(0xff);
   output_low(col[i]);
   for(j=0;j<4;j++)
   {
      if(input(row[j])==0)
      {
         do
         {
         }
         while(input(row[j])==0);
         goto end;
      }
   k++;
   }
   }
   goto loop;
   end:
   return array[k];
}
...
 

hd44780 cgram pic c

Hello,

I don't see an error at first look, but the code loops forever if no key pressed. I would return a null character in this case. Also the scan operation may be simplified, but that isn't as important.

My CCS compiler V3.22 doesn't support the array of bit addresses used for row and column access, thus I can't check the code as is.

Regards,
Frank
 

hd44780 custom characters cursor blinking

Code:
char OnRelease() 
{ 
   int i,j,k; 
   int row[4]={PIN_A0,PIN_A1,PIN_A2,PIN_A3}; 
   int col[4]={PIN_D3,PIN_D2,PIN_D1,PIN_D0}; 
   char array[16]={'1','4','7','<','2','5','8','0','3','6','9','>','C','&','E','M'}; 
   set_tris_a(0xff); 
   set_tris_d(0x00); 
   k=0; 
   for(i=0;i<4;i++) 
   { 
   output_d(0xff); 
   output_low(col[i]); 
   for(j=0;j<4;j++) 
   { 
      if(input(row[j])==0) 
      { 
         do 
         { 
         } 
         while(input(row[j])==0); 
         return array[k]; //// how to jump out of this function with the value I got ???
      } 
   k++; 
   } 
   } 
   return null; //?????
}
then in the main() function
we use if(keyPressed!="null") ...
Sorry, I am not good at C, is that code all right ?
Thanks !!!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top