Sidewalk: The IoT network from Amazon
08.05.2024
Elektronik | Funk | Software
Der Technik-Blog
There is also a video on YouTube for this article: Standalone ATMega328 16x2 LCD Display control with 4-Bit in C - Amtel Studio (German)
This article is about the ATMega328 and how to control it with a 16x2 character LC-Display. Everything is programmed in C with Amtel Studio. The software is loaded to the microcontroller via a programmer (AVRISP). The display is connected to PORTD with a 4-bit line.
The displays available on the market are based on the HD44780 standard. This standard means that the display supports almost all characters of the ASCII character table. Therefore, it is possible to display the most important characters. The display controller, which is integrated in the display, can generate these characters and send them to the matrix. In addition to the already 208 known characters, it is also possible to draw any other characters and signs. The display controller handles most of the operations, so the code for the microcontroller is very short.
In addition to the microcontroller, a 16 MHz clock is needed, which contains a quartz oscillator with two capacitors. In addition to the display, a 10K potentiometer is needed to adjust the contrast of the LCD. The display can be controlled with 8 or 4 data lines. In this example, the display is controlled with 4-bit, as it can save 4 data lines. In addition, the display requires two more data lines (EN & RS), which are responsible for the activation and control of the display. The R / W pin is not needed and therefore connected to ground. The last two pins are used for the backlight.
Pin | Function |
---|---|
VSS | GND (ground) |
VDD | 5V (positive pole) |
V0 | Contrast setting |
RS | switching (0 = command, 1 = data) |
RW | read / write (connected to GND) |
E | Enable (activates display control) |
D0 - D7 | data bits (4-bit = D4-D7, 8-bit = D0-D7) |
A | Anode (positive pole of LED) |
K | cathode (negative pole of LED) |
The source code provides the minimum functionality needed for the display. There are no additional libraries required. The individual pins for the data lines do not need to be defined, since all lines are connected to the same port and therefore ports 4-7 are automatically defined for them. EN & RS must be specified separately. The individual tasks have been divided into functions, which makes it easy to call a specific function several times. The sample code writes a static string to the first line. The second line displays the runtime of the controller in seconds.
/* 4-Bit 16x2 LCD Example More information at www.aeq-web.com */ #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #define LCD_Port PORTD //Define LCD Port (PORTA, PORTB, PORTC, PORTD) #define LCD_DPin DDRD //Define 4-Bit Pins (PD4-PD7 at PORT D) #define RSPIN PD0 //RS Pin #define ENPIN PD1 //E Pin int runtime; //Timer for LCD void LCD_Init (void) { LCD_DPin = 0xFF; //Control LCD Pins (D4-D7) _delay_ms(15); //Wait before LCD activation LCD_Action(0x02); //4-Bit Control LCD_Action(0x28); //Control Matrix @ 4-Bit LCD_Action(0x0c); //Disable Cursor LCD_Action(0x06); //Move Cursor LCD_Action(0x01); //Clean LCD _delay_ms(2); } void LCD_Action( unsigned char cmnd ) { LCD_Port = (LCD_Port & 0x0F) | (cmnd & 0xF0); LCD_Port &= ~ (1<<RSPIN); LCD_Port |= (1<<ENPIN); _delay_us(1); LCD_Port &= ~ (1<<ENPIN); _delay_us(200); LCD_Port = (LCD_Port & 0x0F) | (cmnd << 4); LCD_Port |= (1<<ENPIN); _delay_us(1); LCD_Port &= ~ (1<<ENPIN); _delay_ms(2); } void LCD_Clear() { LCD_Action (0x01); //Clear LCD _delay_ms(2); //Wait to clean LCD LCD_Action (0x80); //Move to Position Line 1, Position 1 } void LCD_Print (char *str) { int i; for(i=0; str[i]!=0; i++) { LCD_Port = (LCD_Port & 0x0F) | (str[i] & 0xF0); LCD_Port |= (1<<RSPIN); LCD_Port|= (1<<ENPIN); _delay_us(1); LCD_Port &= ~ (1<<ENPIN); _delay_us(200); LCD_Port = (LCD_Port & 0x0F) | (str[i] << 4); LCD_Port |= (1<<ENPIN); _delay_us(1); LCD_Port &= ~ (1<<ENPIN); _delay_ms(2); } } //Write on a specific location void LCD_Printpos (char row, char pos, char *str) { if (row == 0 && pos<16) LCD_Action((pos & 0x0F)|0x80); else if (row == 1 && pos<16) LCD_Action((pos & 0x0F)|0xC0); LCD_Print(str); } int main() { LCD_Init(); //Activate LCD LCD_Print("WWW.AEQ-WEB.COM"); //Begin writing at Line 1, Position 1 while(1) { char showruntime [16]; itoa (runtime,showruntime,10); LCD_Action(0xC0); //Go to Line 2, Position 1 LCD_Print("RUNTIME (s): "); LCD_Print(showruntime); _delay_ms(1000); runtime++; } }
In this article we show how the ATMega328 drives a 16x2 character LC-Display with 4-bit. Everything is programmed in C with Amtel Studio and AVRISP Programmer
read moreIn this article, we show how to control an LED with the ATMega328. Everything is programmed in Atmel Studio and we upload the Software via AVR ISP
read moreAEQ-WEB © 2015-2024 All Right Reserved