Hallo, ich möchte ein 4x16 LCD mit einem ATmega2560 ansteuern. Ich habe bereits ein Display mit mit einem 162 angesteuert... hierfür hatte ich 2 Ports verwendet... Da Ich aber den 4 Bit-modus verwende und nur die 3 steuerleitungen habe, habe ich das Display komplett an Port K angeschlossen... Irgendwie funktioniert jedoch die Software nicht, ich habe alles an Port K angepasst... tut sich jedoch nix
Schick doch mal Schaltplan und Programm, sonst wird dir hier wohl niemand helfen können.
Hier ist der Code: #include <avr/interrupt.h> #include <avr/io.h> #include <string.h> #include <stdint.h> #include <stdbool.h> #include <util/crc16.h> #include <util/delay.h> #include "1wire.h" #define F_CPU 14745600UL #define nop() asm volatile("nop") //Verzögerung //Display Clear: #define LCD_CLEAR 0x01 //Display löschen //Return Home: #define LCD_RETURN_HOME 0x02 //Cursor in Grundstellung //Eintragungsmodus: #define LCD_DEC 0x04 //Dekrement, Displayshift aus #define LCD_INC 0x06 //Inkrement, Displayshift aus //Display on/off: #define LCD_OFF 0x08 //Display aus #define LCD_ON 0x0F //Display ein, kein Kursor, kein blinken //#define LCD_ 0x0D //Display ein, kein Kursor, Zeichen blinkt //#define LCD_ 0x0E //Display ein, Kursor aktiv, kein blinken //#define LCD_ 0x0F //Display ein, Kursor aktiv, Zeichen blinkt //Shift: //#define LCD_ 0x10 //Cursorbewegung nach links //#define LCD_ 0x17 //Cursorbewegung nach rechts //#define LCD_ 0x18 //Display und Cursorbewegung nach links //#define LCD_ 0x1F //Display und Cursorbewegung nach rechts //Interface: #define LCD_4BIT_1Z_5x7 0x20 //4bit-Datenbus,einzeiliges Disolay,5x7Punktmatrix //Interface: #define LCD_4BIT_1Z_5x10 0x24 //4bit-Datenbus,einzeiliges Disolay,5x10Punktmatrix //Interface: #define LCD_4BIT_2Z_5x7 0x28 //4bit-Datenbus,zweizeiliges Disolay,5x7Punktmatrix //Interface: #define LCD_4BIT_2Z_5x10 0x2C //4bit-Datenbus,zweizeiliges Disolay,5x10Punktmatrix //Interface: #define LCD_8BIT_1Z_5x7 0x30 //8bit-Datenbus,einzeiliges Disolay,5x7Punktmatrix //Interface: #define LCD_8BIT_1Z_5x10 0x34 //8bit-Datenbus,einzeiliges Disolay,5x10Punktmatrix //Interface: #define LCD_8BIT_2Z_5x7 0x38 //8bit-Datenbus,zweizeiliges Disolay,5x7Punktmatrix //Interface: #define LCD_8BIT_2Z_5x10 0x3C //8bit-Datenbus,zweizeiliges Disolay,5x10Punktmatrix //Instuction/Data #define LCD_CTRL 0 //RS=0 #define LCD_DATA 1 //RS=1 //Charakter-RAM-Adresse 0x40..0x7F; #define LCD_CGRAM (0 | (1<<6)) //0x40 //Anzeigen-RAM-Adresse (0x80...0xFF) für LCD4x20: #define LCD_DDRAM_Line_1 (0 | (1<<7)) //0x80 ... 0x93 #define LCD_DDRAM_Line_2 (64 | (1<<7)) //0xC0 ... 0xD3 #define LCD_DDRAM_Line_3 (20 | (1<<7)) //0x94 ... 0xA7 #define LCD_DDRAM_Line_4 (84 | (1<<7)) //0xD4 ... 0xE7 //Ausgänge fur LCD-Steuerleitungen: #define LCD_RS (1<<0) //Bit0 #define LCD_RW (1<<1) //Bit1 #define LCD_E (1<<2) //Bit2 #define LCD_set_RS() (PORTK |= LCD_RS) #define LCD_set_RW() (PORTK |= LCD_RW) #define LCD_set_E() (PORTK |= LCD_E) #define LCD_clear_RS() (PORTK &= ~LCD_RS) #define LCD_clear_RW() (PORTK &= ~LCD_RW) #define LCD_clear_E() (PORTK &= ~LCD_E) //Definitionen für serielle Schnittstelle #define CLOCK 14745600 //Oszillatorfrequenz 14,7456MHz //Globale Variablendeklaration*********************************** unsigned int Time1=0; static volatile unsigned char RxIndex; //Temperaturwert Variablen************************************* uint8_t temp_lsb,temp_msb;//Byte0 und 1 Scratchpad (MSB und LSB) uint8_t cr; //Byte6 Scratchpad (Count Remain) int dezist,absst; //Vor- und Nachkommastelle Tempwert bool vorzeichen; //Vorzeichen der Temperatur "0" = + / "1" = - //Funktionsprototypen für wichtige Funktionen******************** void Init_Devices(void);//Initialisierung CPU void LCD_enable(void);//Enable-Impuls void LCD_busy(void);//Warten solange LCD-Display Busy void Put_char_to_LCD(char Data,char RS);//Zeichen auf LCD-Display ausgeben void LCD_init(void);//Initialisierung LCD-Display void LCD_special_sign (void);//8 benutzerdefinierte Sonderzeichen schreiben void Transmit_string_to_LCD(unsigned char row_adress,unsigned char *buffer);//LCD void Delay (unsigned int time);//Zeitverzögerung, Wert in ms //Interrupt Vectoren******************************************** ISR(INT0_vect) { //Taste 4 } ISR(INT1_vect) { //Taste 1 } ISR(INT2_vect) { } ISR(INT3_vect) { } ISR(INT4_vect) { } ISR(INT5_vect) { } ISR(INT6_vect) { } ISR(INT7_vect) { } ISR(PCINT0_vect) { } ISR(PCINT1_vect) { } ISR(PCINT2_vect) { } ISR(WDT_vect) { } ISR(TIMER2_COMPA_vect) { } ISR(TIMER2_COMPB_vect) { } ISR(TIMER2_OVF_vect) { } ISR(TIMER1_CAPT_vect) { } ISR(TIMER1_COMPA_vect) { } ISR(TIMER1_COMPB_vect) { } ISR(TIMER1_COMPC_vect) { } ISR(TIMER1_OVF_vect) { //TIMER1 has overflowed TCNT1H= 0xF8; //reload counter high value TCNT1L= 0xCD; //reload counter low value ++Time1; } ISR(TIMER0_COMPA_vect) { } ISR(TIMER0_COMPB_vect) { } ISR(TIMER0_OVF_vect) { } ISR(SPI_STC_vect) { } ISR(USART0_RX_vect) { } ISR(USART0_UDRE_vect) { } ISR(USART0_TX_vect) { } ISR(ANALOG_COMP_vect) { } ISR(ADC_vect) { } ISR(EE_READY_vect) { } ISR(TIMER3_CAPT_vect) { } ISR(TIMER3_COMPA_vect) { } ISR(TIMER3_COMPB_vect) { } ISR(TIMER3_COMPC_vect) { } ISR(TIMER3_OVF_vect) { } ISR(USART1_RX_vect) { } ISR(USART1_UDRE_vect) { } ISR(USART1_TX_vect) { } ISR(TWI_vect) { } ISR(SPM_READY_vect) { } ISR(TIMER4_CAPT_vect) { } ISR(TIMER4_COMPA_vect) { } ISR(TIMER4_COMPB_vect) { } ISR(TIMER4_COMPC_vect) { } ISR(TIMER4_OVF_vect) { } ISR(TIMER5_CAPT_vect) { } ISR(TIMER5_COMPA_vect) { } ISR(TIMER5_COMPB_vect) { } ISR(TIMER5_COMPC_vect) { } ISR(TIMER5_OVF_vect) { } ISR(USART2_RX_vect) { } ISR(USART2_UDRE_vect) { } ISR(USART2_TX_vect) { } ISR(USART3_RX_vect) { } ISR(USART3_UDRE_vect) { } ISR(USART3_TX_vect) { } //Zeitverzögerung********************************************** //ms----------------------------------------------------------- void delay_ms(unsigned int ms) { unsigned int zaehler; while (ms) { zaehler = F_CPU / 5000; while (zaehler) { asm volatile("nop"); zaehler--; } ms--; } } //Initialisierung der Ports*************************************** void port_init(void) //Ports für Kommunikation, Tastatur, Display, Tempsensor setzen //Nicht verwendete Ports Ausgang "low" { DDRA = (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7); //PortA Eingang/Ausgang setzen PORTA &= ~( (1<<PA3) | (1<<PA4) | (1<<PA5) | (1<<PA6) | (1<<PA7)); //PortB Pullup/Pegel setzen DDRB = (1 << DDB4) | (1 << DDB5) | (1 << DDB6) | (1 << DDB7); //PortB Eingang/Ausgang setzen PORTB &= ~( (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7) ); //PortB Pullup/Pegel setzen DDRC = 0b11110000; //PortC Eingang/Ausgang PORTC = 0b00000000; //Pullup/Pegel setzen DDRD = (0 << DDD0) | (0 << DDD1) | (0 << DDD4) | (0 << DDD5) | (0 << DDD6) | (0 << DDD7); //PortD Eingang/Ausgang setzen PORTD &= ~( (1<<PD0) | (1<<PD1) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7) ); //PortD Pullup/Pegel setzen DDRE = (1 << DDE2) | (1 << DDE3) | (1 << DDE4) | (1 << DDE5) | (1 << DDE6) | (1 << DDE7); //PortE Eingang/Ausgang setzen PORTE &= ~( (1<<PE2) | (1<<PE3) | (1<<PE4) | (1<<PE5) | (1<<PE6) | (1<<PE7) ); //PortE Pullup/Pegel setzen DDRF = (1 << DDF0) | (1 << DDF1) | (1 << DDF2) | (1 << DDF3); //PortF Eingang/Ausgang setzen PORTF &= ~( (1<<PF0) | (1<<PF1) | (1<<PF2) | (1<<PF3) ); //PortF Pullup/Pegel setzen DDRG = 0b111111; //PortG Eingang/Ausgang PORTG = 0b000000; //Pullup/Pegel setzen DDRH = (1 << DDH2) | (1 << DDH3) | (1 << DDH4) | (1 << DDH5) | (1 << DDH6) | (1 << DDH7); //PortH Eingang/Ausgang setzen PORTH &= ~( (1<<PH2) | (1<<PH3) | (1<<PH4) | (1<<PH5) | (1<<PH6) | (1<<PH7) ); //PortH Pullup/Pegel setzen DDRJ = (1 << DDJ2) | (1 << DDJ3) | (1 << DDJ4) | (1 << DDJ5) | (1 << DDJ6) | (1 << DDJ7); //PortJ Eingang/Ausgang setzen PORTJ &= ~( (1<<PJ2) | (1<<PJ3) | (1<<PJ4) | (1<<PJ5) | (1<<PJ6) | (1<<PJ7) ); //PortJ Pullup/Pegel setzen DDRK = 0b11111111; //PortK Eingang/Ausgang PORTK = 0b00000000; //Pullup/Pegel setzen DDRL = 0b00111111; //PortL Eingang/Ausgang PORTL = 0b00000000; //Pullup/Pegel setzen } //*************************************************************** //*********************** D I S P L A Y************************** //*************************************************************** //Chattabelle zur Erzeugung eigener benutzerdefinierter Zeichen unsigned char chartab[64] = {0x11,0x04,0x0A,0x11,0x1F,0x11,0x11,0x00,//Ä 0x11,0x0E,0x11,0x11,0x11,0x11,0x0E,0x00,//Ö 0x11,0x00,0x11,0x11,0x11,0x11,0x0E,0x00,//Ü 0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,//"Strichpunktlinie" 0x00,0x00,0x1F,0x1F,0x1F,0x00,0x00,0x00,//"Strich fett" 0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x00,//Kästchen leer 0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,//Kästchen voll 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//leer //siehe mehrdimensionale Vectoren [S. 107 Programmieren in C Kerninghan/Ritchie] //********************************************************************** **** //TIMER1 initialize - prescale:8 // WGM: 0) Normal, TOP=0xFFFF // desired value: 1mSec // actual value: 1,000mSec (0,0%) void timer1_init(void) { //TCCR1B = 0x01; //start TCNT1H = 0xF8; //setup TCNT1L = 0xCD; OCR1AH = 0x07; OCR1AL = 0x33; OCR1BH = 0x07; OCR1BL = 0x33; OCR1CH = 0x07; OCR1CL = 0x33; ICR1H = 0x07; ICR1L = 0x33; TCCR1A = 0x00; TCCR1B = 0x00; //stop Timer } //---------------------------------------------------------------------- --------- void Init_Devices(void) { //stop errant interrupts until set up cli(); //disable all interrupts // XDIV = 0x00; //xtal divider XMCRA = 0x00; //external memory port_init(); timer1_init(); MCUCR = 0x00; EICRA = 0x00; //extended ext ints EICRB = 0x00; //extended ext ints EIMSK = 0x00; // TIMSK = 0x04; //timer interrupt sources // ETIMSK = 0x00; //extended timer interrupt sources sei(); //re-enable interrupts //all peripherals are now initialized } //---------------------------------------------------------------------- --------- //---------------------------------------------------------------------- --------- //Ablauf Displaycontroller HD44780 void LCD_init(void) { delay_ms(16); //SW Reset Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7 Matrix delay_ms(5); Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7 Matrix delay_ms(1); Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7 Matrix Put_char_to_LCD(LCD_ON,LCD_CTRL);//Display ON Put_char_to_LCD(LCD_INC,LCD_CTRL);//Display auf Inkrement, kein Displayshift Put_char_to_LCD(LCD_RETURN_HOME,LCD_CTRL);//LCD_RETURN_HOME Put_char_to_LCD(LCD_CLEAR,LCD_CTRL);//Display löschen } //**************************************************************** //8 benutzerdefinierte Sonderzeichen schreiben //0x40+(0...7) Adresse CG-RAM 1.Zeichen //0x40+(8...5) Adresse CG-RAM 2.Zeichen //0x40+(16...23) Adresse CG-RAM 3.Zeichen //0x40+(24...31) Adresse CG-RAM 4.Zeichen //0x40+(32...39) Adresse CG-RAM 5.Zeichen //0x40+(40...47) Adresse CG-RAM 6.Zeichen //0x40+[48...55) Adresse CG-RAM 7.Zeichen //0x40+[56...63) Adresse CG-RAM 8.Zeichen void LCD_special_sign (void) { unsigned char Index=0; Put_char_to_LCD (LCD_CGRAM,LCD_CTRL);//Display CG-RAM-Adresse für 1.Zeichen /*Durch interne Autoincrementfunktion des CG-RAM-Adresszählers im Display braucht dieser nicht extra incrementiert werden!*/ do { Put_char_to_LCD(chartab[Index],LCD_DATA); ++Index; }while(Index < 64);//Anzahl 8Zeichen x 8Bytes/Zeichen } //****************************************** // Funktion gibt ein Zeichen auf Data- oder Ctrl-Register aus void Put_char_to_LCD(char Data, char RS) { LCD_clear_RW(); if(RS)//RS=1? {//ja RS=1,RW=0 Data Register LCD_set_RS(); } else {//nein RS=0,RW=0 Ctrl Register LCD_clear_RS(); } //4bit-Modus PORTK = ( (Data&0xF0)|(PORTK&0x0F) );//H-Byte LCD_enable();//H-Byte senden PORTK = ( (((Data&0x0F)<<4)&0xF0)|(PORTK&0x0F) );//L-Byte LCD_enable();//L-Byte senden LCD_busy();//4bit-Modus und 8bit-Modus } //****************************************** void LCD_enable (void) { nop();//67,8ns (>60ns) LCD_set_E();//E=1 (>300ns) nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns LCD_clear_E();//E=0 (>366ns) nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns } //****************************************** // Funktion wartet solange Display bereit ist bzw. fertig ist void LCD_busy(void) { unsigned char Busy; LCD_clear_RS();//RS=0 LCD_set_RW();//RW=1 DDRK &= 0x0F;//4bit-Modus, PortK H-Byte Eingänge //DDRA = 0x00;//8bit-Modus, PortK Eingänge do { nop();//67,8ns bei 14,7456MHz (>60ns) LCD_set_E();//E=1 nop();//67,8ns (>300ns) nop();//67,8ns nop();//67,8ns nop();//67,8ns Busy = PINK;//PortK einlesen,Busyflag lesen (>190ns) nop();//67,8ns LCD_clear_E();//E=0 (>366ns) nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns nop();//67,8ns //noch einen Enable-Impuls senden, keine Busy-Flag Auswertung LCD_enable ();//4bit-Modus }while(Busy & 0x80);//Busy-Flag auswerten DDRK |= 0xF0;//4bit-Modus, PortK H-Byte Ausgänge LCD_clear_RW();//RW=0 } //****************************************** void Transmit_string_to_LCD (unsigned char row_adress,unsigned char *buffer)//Info { Put_char_to_LCD(row_adress,LCD_CTRL);//Display Zeile 1 while (*buffer != '\0')//NULL, 0x00, 0, '\0' Endmarkierung eines Strings, //oder EOF, 0xFF, -1 (End of a File) { Put_char_to_LCD(*buffer++,LCD_DATA); } }
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.