Hi all.
I'm new in AVR, and now I'm trying to create a program that displays characters to an 16x2 LCD in 4-bit mode using ATmega4809 Curiosity Nano board.
As a guide, I've used this tutorial on how to interface LCD with ATmega: Interfacing LCD 16x2 with ATmega16
Below is my code:
LCD header file: lcd.h
#include <avr/io.h> #include <util/delay.h> #define lcdPort PORTC_OUT //Data Output value of PORTC #define lcdDir PORTC.DIR //Setting pins as I/O #define EN (PORTC.IN & (1 << 0)) //ENABLE (EN) pin to PORTC PIN0 #define RS (PORTC.IN & (1 << 1)) //REGISTER SELECT (RS) pin to PORTC PIN1 void lcdInit(void); void lcdClear(); void lcdCmd(uint8_t cmnd); void lcdChar(uint8_t cmnd); void lcdString(uint8_t *str);
And lcd.c
/*** PIN ASSIGNMENTS ***/ /* EN - PC0 RS - PC1 D4 - PC4 D5 - PC5 D6 - PC6 D7 - PC7 */ #include <avr/io.h> #include <util/delay.h> #include "lcd.h" /* INITIALIZATION */ void lcdInit(void) { lcdDir = PORTC.DIRSET; //LCD port direction as output _delay_ms(20); //LCD power initialization time lcdCmd(0x02); //Initializes LCD in 4-bit mode lcdCmd(0x28); //Configures LCD in 2-line 4-bit mode and 5x7 matrix lcdCmd(0x0c); //Display on, cursor off lcdCmd(0x06); //Increment cursor: shift cursor to right lcdCmd(0x01); //Clear display screen } /* FOR CLEARING LCD DISPLAY */ void lcdClear() { lcdCmd(0x01); //Clear display screen _delay_ms(2); lcdCmd(0x08); //Clear display without clearing ram content } /* LCD COMMAND MODE */ void lcdCmd(uint8_t cmnd) { //Sending upper nibble since 4-bit lcdPort = (lcdPort & 0x0F) | (cmnd & 0xF0); lcdPort &= ~(1<<RS); //RS OFF lcdPort |= (1<<EN); //Set bit in EN _delay_us(1); lcdPort &= ~(1<<EN); //Clear bit in EN _delay_us(200); //Sending lower nibble lcdPort = (lcdPort &0x0F) | (cmnd <<4); lcdPort |= (1<<EN); _delay_us(1); lcdPort &= ~(1<<EN); _delay_ms(2); } /* ACCEPTING CHARACTERS IN LCD */ void lcdChar(uint8_t cmnd) { //Sending upper nibble since 4-bit lcdPort = (lcdPort & 0x0F) | (cmnd & 0xF0); lcdPort &= ~(1<<RS); //RS ON lcdPort |= (1<<EN); //Set bit in EN _delay_us(1); lcdPort &= ~(1<<EN); //Clear bit in EN _delay_us(200); //Sending lower nibble lcdPort = (lcdPort &0x0F) | (cmnd <<4); lcdPort |= (1<<EN); _delay_us(1); lcdPort &= ~(1<<EN); _delay_ms(2); } /* CONVERTS THE CHARACTER INTO STRING */ void lcdString(uint8_t *str) { int i; for(i=0; str[i] != 0; i++) { lcdChar(str[i]); } }
And for the main.c
#include <avr/io.h> #include <avr/delay.h> #include "lcd.c" #include "twswitch.c" int main(void) { lcdInit(); lcdString("hello"); lcdCmd(0xC0); lcdString("world"); }
The LCD displays only black pixels on the upper line; just the default display when plugged into a 5V, but none on the second line.
It does not also display any characters I wanted to appear.
I am pretty sure that it's not due to hardware because I've tried the same set-up to an Arduino UNO board, and it works just fine.
So my guess is the problem is really in the code but I'm kind of new at this.
Any insights on the code? It would be much appreciated. Thank you!