Gast
#1658569
Es soll die Temperatur auf ein Display ausgegeben werden. TS: SMT 160-30 MC: ATMega 16 STK 500 Display mit HD44780 - Controller leider gibt das Display nur hieroglyphen aus. Kann jemand helfen, da wir den Fehler nicht finden??? ***MAIN*** #include <stdlib.h> #include <stdio.h> #include <avr/io.h> #include <inttypes.h> #include "lcd-routines.h" #define F_CPU 16000000 #include <util/delay.h> // #include "lcd-routines.c" #include <avr/interrupt.h> #include <math.h> uint16_t ueber_puls=0; uint16_t ueber_per=0; uint16_t puls=0; uint16_t periode=0; uint32_t puls1=0; uint32_t periode1=0; ISR(INT0_vect) // Steigende Flanke { periode=TCNT0+ueber_per; // Endzeit der Periode ermitteln ueber_puls=0; // Überlauf für Puls auf 0 setzen ueber_per=0; // Überlauf für Periode auf 0 setzen TCNT0=0; // Timer Register auf 0 setzen } ISR(INT1_vect) // Fallende Flanke { puls=TCNT0+ueber_puls; // Puls Zeit berechnen } ISR(TIMER0_OVF_vect) // Overflow T0 { ueber_puls=ueber_puls+255; // bei überlauf von T0 ueber_puls um 255 erhöhen ueber_per=ueber_per+255; // bei überlauf von T0 ueber_per um 255 erhöhen } int main(void) { // DDRB= 0b00001100; // Pin B2,B3 als Ausgang DDRD= 0b11110011; // Pin D2,D3 als Eingang PORTD=0b00001100; // Pull Up D2,D3 aktivieren lcd_init(/*LCD_DISP_ON*/); // LCD initialisieren char Buffer[20]; // Zeichenkette deklarieren double x; // Float Hilfsvariable x deklarieren MCUCR=0b00001011; // Steigende Flanke an D2 löst Int 0 aus, Fallende Flanke an D3 Int 1 GICR= 0b11000000; // Interrupt 0 und 1 aktivieren TIMSK |= (1<<TOIE0); // Timer 0 Overflow erlauben TCCR0 = 0b00000001; // Teiler Timer0 auf Cpu Takt while(1) { _delay_ms(200); // Wartezeit damit das LCD nicht flackert sei(); // Interrupts erlauben _delay_ms(20); // Messzeit cli(); // Interrupts sperren x=(((float)puls/periode)-0.32)*212.765957; lcd_clear(); sprintf( Buffer, "%i ",puls ); lcd_string(puls); sprintf( Buffer, "%i ",periode ); lcd_string(periode); lcd_data(x); periode=0; puls=0; } } ************************************************************************ ************** ***lcd-routines.c*** #include <avr/io.h> #include "lcd-routines.h" #include <util/delay.h> // sendet ein Datenbyte an das LCD void lcd_data(unsigned char temp1) { unsigned char temp2 = temp1; LCD_PORT |= (1<<LCD_RS); // RS auf 1 setzen temp1 = temp1 >> 4; temp1 = temp1 & 0x0F; LCD_PORT &= 0xF0; LCD_PORT |= temp1; // setzen lcd_enable(); temp2 = temp2 & 0x0F; LCD_PORT &= 0xF0; LCD_PORT |= temp2; // setzen lcd_enable(); _delay_us(42); } // sendet einen Befehl an das LCD void lcd_command(unsigned char temp1) { unsigned char temp2 = temp1; LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen temp1 = temp1 >> 4; // oberes Nibble holen temp1 = temp1 & 0x0F; // maskieren LCD_PORT &= 0xF0; LCD_PORT |= temp1; // setzen lcd_enable(); temp2 = temp2 & 0x0F; // unteres Nibble holen und maskieren LCD_PORT &= 0xF0; LCD_PORT |= temp2; // setzen lcd_enable(); _delay_us(42); } // erzeugt den Enable-Puls void lcd_enable(void) { // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16" LCD_PORT |= (1<<LCD_EN); _delay_us(1); // kurze Pause // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern // Beitrag "LCD -> Probleme mit Optimierungsgrad" LCD_PORT &= ~(1<<LCD_EN); } // Initialisierung: // Muss ganz am Anfang des Programms aufgerufen werden. void lcd_init(void) { LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN); // Port auf Ausgang schalten // muss 3mal hintereinander gesendet werden zur Initialisierung _delay_ms(15); LCD_PORT &= 0xF0; LCD_PORT |= 0x03; LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 lcd_enable(); _delay_ms(5); lcd_enable(); _delay_ms(1); lcd_enable(); _delay_ms(1); // 4 Bit Modus aktivieren LCD_PORT &= 0xF0; LCD_PORT |= 0x02; lcd_enable(); _delay_ms(1); // 4Bit 2 Zeilen 5x7 lcd_command(0x28); // Display ein Cursor aus kein Blinken lcd_command(0x0C); // inkrement / kein Scrollen lcd_command(0x06); lcd_clear(); } // Sendet den Befehl zur Löschung des Displays void lcd_clear(void) { lcd_command(CLEAR_DISPLAY); _delay_ms(5); } // Sendet den Befehl: Cursor Home void lcd_home(void) { lcd_command(CURSOR_HOME); _delay_ms(5); } // setzt den Cursor in Zeile y (1..4) Spalte x (0..15) void set_cursor(uint8_t x, uint8_t y) { uint8_t tmp; switch (y) { case 1: tmp=0x80+0x00+x; break; // 1. Zeile case 2: tmp=0x80+0x40+x; break; // 2. Zeile case 3: tmp=0x80+0x10+x; break; // 3. Zeile case 4: tmp=0x80+0x50+x; break; // 4. Zeile default: return; // für den Fall einer falschen Zeile } lcd_command(tmp); } // Schreibt einen String auf das LCD void lcd_string(char *data) { while(*data) { lcd_data(*data); data++; } } ************************************************************************ ************** ***lcd-routines.h*** void lcd_data(unsigned char temp1); void lcd_string(char *data); void lcd_command(unsigned char temp1); void lcd_enable(void); void lcd_init(void); void lcd_home(void); void lcd_clear(void); void set_cursor(uint8_t x, uint8_t y); #define F_CPU 16000000 // LCD Befehle #define CLEAR_DISPLAY 0x01 #define CURSOR_HOME 0x02 // Pinbelegung für das LCD, an verwendete Pins anpassen #define LCD_PORT PORTB #define LCD_DDR DDRB #define LCD_RS PD4 #define LCD_EN PD5 // DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden