Forum: Compiler & IDEs Problem Displayansteuerung ATMEGA1280


von Peter Steinert (Gast)


Lesenswert?

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

von Elektro G. (e_g)


Lesenswert?

Naja, da haste wohl was Falsch gemacht!

von Elektro G. (e_g)


Lesenswert?

Schick doch mal Schaltplan und Programm, sonst wird dir hier wohl 
niemand helfen können.

von Peter Steinert (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.