Som ett skoj projekt för att öva på avr+c kod, tänkte jag mig att skriva en enklare drivrutin för en hd44780 kontroller. Efter att ja läst på lite om den tänkte jag mig ha 4-bits interface och alla pinnar på samma port(data och kontroll på samma port ut från avr:en).
Det visar sig att nu när jag försökt ett tag går det inte alls. Jag har verifierat uppkopplingen med ett bibliotek för hd44780+avr och med det kunnat skriva lite saker på displayen.
Men min egna kod funkar ej. Uppställningen är som följer. atmega8518 + stk500. LCDn är ansluten på portB . LCD pinne DB4-DB7 sitter på portB 0-3. Megan snurrar i 8MHz
RS sitter på portB 4
RW sitter på portB 5
E sitter på portB 6
Koden då. Det är väl antaglingen i någon av bit operationerna det är fel. Det är just för att bli lite mer rutinerad på bit operationer och tänka hexadecimalt som jag försöker mig på att skriva detta.
Om någon god själ skulle kunna slå ett öga på koden och ge mig några tips. Jag har änså länge inte brytt mig om att läsa busyflag eftersom vad jag förstått behövs det inte när man försöker göra så här enkla grejer =)
Jag använder avr-gcc + avr-libc + ubuntu om det nu har någon betydelse.
LCD.h
Kod: Markera allt
#define F_CPU 8000000
#include <inttypes.h>
#ifndef LCD_H
#define LCD_H
#define LCD_PORT PORTB // One port for data and control
#define LCD_DDR DDRB
#define LCD_DATA_PIN_0 0 // Pin number for lcd pin DB4
#define LCD_RS_PIN 4 // Pin number for
#define LCD_RW_PIN 5 // Hårdkodat tillsvidare
#define LCD_E_PIN 5 // Hårdkodat tillsvidare
#define DELAY_TIME 5
#define DELAY_E_TOGGLE 2
void lcd_init(void);
void lcd_setup(void);
void toggle_e(void);
void write_data(uint8_t d);
void write_nibble(uint8_t d);
int main(void);
#endif
Kod: Markera allt
#include "lcd.h"
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#define toggle_e_high() LCD_PORT = LCD_PORT | _BV(LCD_E_PIN)
#define toggle_e_low() LCD_PORT = LCD_PORT & ~_BV(LCD_E_PIN)
#define toggle_rs_high() LCD_PORT = LCD_PORT | _BV(LCD_RS_PIN)
#define toggle_rs_low() LCD_PORT = LCD_PORT & ~_BV(LCD_RS_PIN)
/*
Used for writing data to CGRAM/DDRAM
*/
void write_data(uint8_t d){
toggle_rs_high();
write_nibble(d >> 4); // HIGH BITS first
_delay_us(DELAY_TIME);
write_nibble(d & 0x0F); // Low bits set high to zero
_delay_us(DELAY_TIME);
toggle_rs_low();
}
void write_command(uint8_t d){
write_nibble(d >> 4); // HIGH BITS first
_delay_us(DELAY_TIME);
write_nibble(d & 0x0F); // Low bits set high to zero
_delay_us(DELAY_TIME);
}
void toggle_e(){
toggle_e_high();
_delay_us(DELAY_E_TOGGLE);
toggle_e_low();
}
void write_nibble(uint8_t d){
LCD_PORT &= 0xF0; // TODO Hård kodat antar PIN 0-3
LCD_PORT |= d;
}
void lcd_init(){
_delay_ms(20); // Eventual power on time
LCD_DDR = (0x0F << (LCD_DATA_PIN_0) ) & ( 0x07 << (LCD_RW_PIN)); // Set as output
write_nibble(0x03); // First command for init 0011
_delay_ms(5); // 5 milli
write_nibble(0x03); // second command 0011
_delay_us(DELAY_TIME);
write_nibble(0x03); // 0011
_delay_us(DELAY_TIME);
write_nibble(0x02); // 4 bit interface
_delay_us(DELAY_TIME);
}
void lcd_setup(){
write_command(0x28); // Lines 2 font 5*8 font
write_command(0x08); // LCD OFF
write_command(0x01); // LCD Clear
write_command(0x02); // First position
_delay_ms(4000); // Denna för att idealt se lcd blinka på o av.
write_command(0x0E); // LCD On cursor on
write_data(0x48); // write char
}
int main(){
lcd_init();
lcd_setup();
while(1){
_delay_ms(1);
}
return 0;
}
Anders