Following is my code
#include <avr/io.h>
#include <util/delay.h>
#define Delay_ms(x) _delay_ms(x)
#define RS 1 //PC0
#define RW 1 //PC1
#define EN 2 //PC2
void lcd_cmnd(unsigned char);
void lcd_data(unsigned char dta);
int main()
{
DDRC=0xff;
DDRD=0xff;
lcd_cmnd(0x38); //sets 8-bit interacing
Delay_ms(1);
lcd_cmnd(0x0e); //display on
Delay_ms(1);
lcd_cmnd(0x08); //display off
Delay_ms(1);
lcd_cmnd(0x01); //clears screen
Delay_ms(1);
lcd_cmnd(0b00000000);
lcd_cmnd(0x06); //Entry Mode, Increment cursor position, No display shift
lcd_data('N');
Delay_ms(250);
lcd_data('a');
Delay_ms(25);
lcd_data('s');
Delay_ms(25);
lcd_data('i');
Delay_ms(25);
lcd_data('r');
Delay_ms(25);
return 0;
}
void lcd_cmnd(unsigned char cmd)
{
PORTD=cmd;
PORTC=(0<<RS); //command mode PC0=RS(low)
PORTC|=(0<<RW); // read mode PC1=RW
PORTC=(1<<EN); // enable high PC2=EN
Delay_ms(1);
PORTC=(0<<EN); //enable low
Delay_ms(50);
}
void lcd_data(unsigned char dta)
{
PORTC|=(0<<RW); //PC1=RW (low)
PORTC|=(1<<0); //DATA mode PC0=RS
PORTD=dta;
PORTC=(1<<EN); //enable high PC2=EN
Delay_ms(1);
PORTC=(0<<EN); //enable low
Delay_ms(50);
}
It executes well, the simulation in proteus runs but the cursor just blinks and nothing is displayed. I don't know why.
Following is other code which runs and displays on the LCD "Hello World!"
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <stdio.h>
//Define functions
//==========================================================
void io_init(void); //Initializes IO
void send_nibble(unsigned char __rs, unsigned char __data);
//==========================================================
int main (void)
{
io_init();
_delay_ms(15);
send_nibble(0,0b0010); //Set to 4 bit operation (note: 1 nibble operation)
_delay_ms(5);
send_nibble(0,0b0010); //Function set, 4 bit
send_nibble(0,0x08); //display off, cursor off
send_nibble(0,0b0000);
send_nibble(0,0b1111); //Display ON, Cursor On, Cursor Blinking
send_nibble(0,0b0000);
send_nibble(0,0b0001); //Clear Display
send_nibble(0,0b0000);
send_nibble(0,0x06); //Entry Mode, Increment cursor position, No display shift
send_nibble(1,0b0100); //H
send_nibble(1,0b1000);
send_nibble(1,0b0110); //e
send_nibble(1,0b0101);
send_nibble(1,0b0110); //l
send_nibble(1,0b1100);
send_nibble(1,0b0110); //l
send_nibble(1,0b1100);
send_nibble(1,0b0110); //o
send_nibble(1,0b1111);
send_nibble(1,0b0010); //Space
send_nibble(1,0b0000);
send_nibble(1,0b0101); //w
send_nibble(1,0b0111);
send_nibble(1,0b0110); //o
send_nibble(1,0b1111);
send_nibble(1,0b0111); //r
send_nibble(1,0b0010);
send_nibble(1,0b0110); //l
send_nibble(1,0b1100);
send_nibble(1,0b0110); //d
send_nibble(1,0b0100);
return(0);
}
void io_init (void)
{
/*
PC 7: N/A
PC 6: Reset
PC 5: Enable
PC 4: Register Select
PC 3: Data 7
PC 2: Data 6
PC 1: Data 5
PC 0: Data 4
*/
DDRC = 0b00111111; //63
}
void send_nibble(unsigned char __rs, unsigned char __data)
{
PORTC = (__rs<<4) | __data | 0b00100000; // Set RS & Data. Set EN=High
_delay_ms(1);
PORTC = (__rs<<4) | __data; // Set RS & Data. Set EN=Low
_delay_ms(1);
}
I tried to proceed in the same order but in vain. I am stuck in learning the LCD programming for last 10 days. Any healthy and effective help is appreciated in advance!
Best Answer
Time to elaborate on my original comment...
You seem to be misunderstanding the part that the left shift operator (<<) the bitwise OR operator (|) play in setting bits. You can use the OR operator to set a bit to 1, but you cannot use it to reset a bit to 0. For example, in your code:
...you seem to be trying to reset the RW bit in PORTC to 0, but that is not what will happen with the above code. Since RW is defined as 1, 0<<1 will be compiled as "0 shifted left by 1 bit" (i.e. multiplied by 2) which is still just 0. Then you OR that 0 to the contents of PORTC resulting in no change to PORTC. That is, if PORTC bit 1 was on, it will still be on after the above is executed.
Assuming that what you really want to do is reset bit 1 (RW) of PORTC to 0 leaving all others the same, then that can be done by using the AND operator:
Personally, given the confusion this is causing you, I would recommend simply defining and using RW (and other bits) as follows:
To me that is clearer anyway. Alternatively, if you really want to work with bit position numbers, you could hide the bit-level acrobatics in a macro as follows: