Files
Sem van der Hoeven 80909212ad added test lcd project
2021-02-24 11:19:54 +01:00

200 lines
4.9 KiB
C

/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** ioisr.c
**
** Beschrijving: BigAVR LCD module
** Target: AVR mcu
** Build: avr-gcc -std=c99 -Wall -O3 -mmcu=atmega128 -D F_CPU=8000000UL -c lcd.c
** avr-gcc -g -mmcu=atmega128 -o lcd.elf lcd.o
** avr-objcopy -O ihex lcd.elf lcd.hex
** or type 'make'
** Author: dkroeske@gmail.com
** -------------------------------------------------------------------------*/
#define F_CPU 8e6
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LCD_E 6 // RA6 UNI-6
#define LCD_RS 4 // RA4 UNI-6
void lcd_strobe_lcd_e(void);
void init_4bits_mode(void);
void lcd_write_string(char *str);
void lcd_write_data(unsigned char byte);
void lcd_write_cmd(unsigned char byte);
void lcd_clear(void);
/******************************************************************
short: Busy wait number of millisecs
inputs: int ms (Number of millisecs to busy wait)
outputs:
notes: Busy wait, not very accurate. Make sure (external)
clock value is set. This is used by _delay_ms inside
util/delay.h
Version : DMK, Initial code
*******************************************************************/
void wait( int ms ) {
for (int i=0; i<ms; i++) {
_delay_ms( 1 ); // library function (max 30 ms at 8MHz)
}
}
/******************************************************************
short: Strobe LCD module E pin --__
inputs:
outputs:
notes: According datasheet HD44780
Version : DMK, Initial code
*******************************************************************/
void lcd_strobe_lcd_e(void) {
PORTA |= (1<<LCD_E); // E high
_delay_ms(1); // nodig
PORTA &= ~(1<<LCD_E); // E low
_delay_ms(1); // nodig?
}
/******************************************************************
short: Init LCD module in 4 bits mode.
inputs:
outputs:
notes: According datasheet HD44780 table 12
Version : DMK, Initial code
*******************************************************************/
void init_4bits_mode(void) {
// PORTC output mode and all low (also E and RS pin)
DDRD = 0xFF;
DDRA = 0xFF;
PORTC = 0x00;
PORTA = 0x00;
//PORTA = 0xFF;
// Step 2 (table 12)
PORTC = 0x20; // function set
lcd_strobe_lcd_e();
// Step 3 (table 12)
PORTC = 0x20; // function set
lcd_strobe_lcd_e();
PORTC = 0x80;
lcd_strobe_lcd_e();
// Step 4 (table 12)
PORTC = 0x00; // Display on/off control
lcd_strobe_lcd_e();
PORTC = 0xF0;
lcd_strobe_lcd_e();
// Step 4 (table 12)
PORTC = 0x00; // Entry mode set
lcd_strobe_lcd_e();
PORTC = 0x60;
lcd_strobe_lcd_e();
}
/******************************************************************
short: Writes string to LCD at cursor position
inputs:
outputs:
notes: According datasheet HD44780 table 12
Version : DMK, Initial code
*******************************************************************/
void lcd_write_string(char *str) {
// Het kan met een while:
// while(*str) {
// lcd_write_data(*str++);
// }
// of met een for:
for(;*str; str++){
lcd_write_data(*str);
}
}
/******************************************************************
short: Writes 8 bits DATA to lcd
inputs: byte - written to LCD
outputs:
notes: According datasheet HD44780 table 12
Version : DMK, Initial code
*******************************************************************/
void lcd_write_data(unsigned char byte) {
// First nibble.
PORTC = byte;
PORTA |= (1<<LCD_RS);
lcd_strobe_lcd_e();
// Second nibble
PORTC = (byte<<4);
PORTA |= (1<<LCD_RS);
lcd_strobe_lcd_e();
}
/******************************************************************
short: Writes 8 bits COMMAND to lcd
inputs: byte - written to LCD
outputs:
notes: According datasheet HD44780 table 12
Version : DMK, Initial code
*******************************************************************/
void lcd_write_command(unsigned char byte) {
// First nibble.
PORTC = byte;
PORTA &= ~(1<<LCD_RS);
lcd_strobe_lcd_e();
// Second nibble
PORTC = (byte<<4);
PORTA &= ~(1<<LCD_RS);
lcd_strobe_lcd_e();
}
void lcd_clear() {
lcd_write_command (0x01); //Leeg display
_delay_ms(2);
lcd_write_command (0x80); //Cursor terug naar start
}
/******************************************************************
short: main() loop, entry point of executable
inputs:
outputs:
notes: Slow background task after init ISR
Version : DMK, Initial code
*******************************************************************/
int main( void ) {
// Init I/O
DDRC = 0xFF; // PORTD(7) output, PORTD(6:0) input
PORTC = 0xFF;
// Init LCD
init_4bits_mode();
_delay_ms(10);
lcd_clear();
// Write sample string
lcd_write_string("Hello world!");
// Loop forever
while (1) {
PORTC ^= (1<<0); // Toggle PORTD.7
wait( 250 );
}
return 1;
}