Forum: Mikrocontroller und Digitale Elektronik Probleme mit EADOGM204-4 und ATMEGA32


von Nico (nico123)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich habe ein Problem mit dem "EA DOGM204-A", einem 4x20 Zeichen LCD. Es 
läuft an einem ATMEGA32, der mit 16MHz läuft. Das Display ist über SID 
und SCLK (laut Datenblatt) an den µC angeschlossen und zusätzlich wird 
der Reset per µC gesteuert. Der ATMEGA läuft mit 5V und das Display mit 
3.3V, deshalb sind SID, SCLK und Reset über Spannungsteiler (1.8k + 
3.3k) angeschlossen.
Ich bekomme das LCD initialisiert und kann Zeichen darstellen.
Die Qualität der Daten- und Taktsignale ist gut und per Oszi 
kontrolliert. Der Takt läuft auf 125kHz.

ABER nun zum Problem: Wenn ich eine vierstellige Zahl hochzählen lasse 
auf dem Display, dann bleibt das Programm irgendwann stehen!
Meine erste Idee war, dass ich die Daten zu schnell ans LCD sende, da 
ich ja auch das Busy-Flag nicht abfrage. Aber selbst wenn ich die 
Wartezeiten nach dem Senden vergrößere ändert sich nichts am Fehler.
Wäre toll wenn Jemand 'ne Idee hat! :-)

Mein Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include <stdlib.h>
5
#include <avr/sleep.h>
6
7
void SPI_MasterInit(void)
8
{
9
  DDRB |= (1<<DDB5) | (1<<DDB7);                    //MOSI und SCKL als Ausgang setzen
10
  SPCR = (1<<SPE) | (1<<DORD) | (1<<MSTR) | (1<<CPOL) | (1<<CPHA) | (1<<SPR1) | (1<<SPR0);  //aktiviere SPI als Master mit 125kHz
11
  PORTB &= ~(1<<PB0);                          //LCD resetten
12
  _delay_ms(10);
13
  PORTB |= (1<<PB0);
14
  _delay_ms(10);
15
}
16
17
void SPI_Transmit(char Data)
18
{
19
  SPDR = Data;                            //Daten ins SPI-Register
20
  while(!(SPSR & (1<<SPIF)));                      //warte bis Daten weg sind
21
}
22
23
void LCD_Write_Instr(char instr)
24
{
25
  SPI_Transmit(0x1F);                          //sende 5 synchronisations-bits, RS = 0, R/W = 0
26
  SPI_Transmit(instr & 0x0F);                     //sende untere daten-bits
27
  SPI_Transmit((instr >> 4) & 0x0F);                   //sende obere daten-bits
28
  _delay_us(500);
29
}
30
31
void LCD_Write_Data(char data)
32
{
33
  SPI_Transmit(0x5F);                          //sende 5 synchronisations-bits, RS = 1, R/W = 0
34
  SPI_Transmit(data & 0x0F);                      //sende untere daten-bits
35
  SPI_Transmit((data >> 4) & 0x0F);                  //sende obere daten-bits
36
  _delay_us(500);
37
}
38
39
void SetPos(unsigned char Zeile, unsigned char Spalte)
40
{
41
  switch(Zeile)
42
  {
43
    case 1:    LCD_Write_Instr(0x80 + Spalte-1);
44
          break;
45
    case 2:    LCD_Write_Instr(0xA0 + Spalte-1);
46
          break;
47
    case 3:    LCD_Write_Instr(0xC0 + Spalte-1);
48
          break;
49
    case 4:    LCD_Write_Instr(0xE0 + Spalte-1);
50
          break;
51
    default:   LCD_Write_Instr(0x80);
52
          break;
53
  }
54
}
55
56
void ClrDisplay(void)
57
{
58
  LCD_Write_Instr(0x01);
59
  LCD_Write_Instr(0x80);
60
}
61
62
void LCD_Zahl(unsigned int daten)
63
{
64
  unsigned char byt=0;
65
  unsigned int stelle=1000;  
66
67
  while(stelle > 1)
68
  {
69
    byt = daten / stelle;
70
    daten = daten - (unsigned char) byt * stelle;
71
    LCD_Write_Data(byt + 48);
72
    stelle = stelle / 10;
73
  }
74
  LCD_Write_Data(daten + 48);
75
}
76
77
78
int main(void)
79
{
80
  DDRB |= (1<<DDB0) | (1<<DDB1);    //Reset fürs LCD und LED
81
  PORTB |= (1<<PB0) | (1<<PB1);
82
  
83
  ACSR |= (1<<ACD);          //Analog Komparator deaktivieren
84
85
  _delay_ms(1000);
86
  SPI_MasterInit();
87
88
  LCD_Write_Instr(0x3A);    //8-Bit data length extension Bit RE=1; REV=0
89
  LCD_Write_Instr(0x09);    //4 line display
90
  LCD_Write_Instr(0x06);    //Bottom view
91
  LCD_Write_Instr(0x1E);    //Bias setting BS1=1
92
  LCD_Write_Instr(0x39);    //8-Bit data length extension Bit RE=0; IS=1
93
  LCD_Write_Instr(0x1B);    //BS0=1 -> Bias=1/6
94
  LCD_Write_Instr(0x6E);     //Devider on and set value
95
  LCD_Write_Instr(0x57);     //Booster on and set contrast (BB1=C5, DB0=C4)
96
  LCD_Write_Instr(0x72);     //Set contrast (DB3-DB0=C3-C0)
97
  LCD_Write_Instr(0x38);     //8-Bit data length extension Bit RE=0; IS=0
98
  LCD_Write_Instr(0x0C);    //display on, cursor off, blink off
99
  LCD_Write_Instr(0x01);    //Clear Display
100
101
  unsigned int i=0;
102
103
  while(1)
104
  {
105
    SetPos(2,9);
106
    LCD_Zahl(i);
107
    if(i>9999) i=0;
108
    else i++;
109
110
    PORTB ^= (1<<PB1);
111
    _delay_ms(100);
112
  }
113
  return(0);
114
}

von dummy (Gast)


Lesenswert?

Schalte PB4/SS mal auf Ausgang.

von Nico (nico123)


Lesenswert?

PB4? Der µC ist doch der Master, dann brauche ich doch kein SlaveSelect! 
Oder was meinst Du?
Und an dem LCD gibt es kein ChipSelect.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Nico ... schrieb:
> PB4? Der µC ist doch der Master, dann brauche ich doch kein SlaveSelect!
> Oder was meinst Du?
> Und an dem LCD gibt es kein ChipSelect.

Ach wenn doch nur mal einer das Datenblatt lesen würde. Der Spi Master 
Mode springt sofort raus, wenn der SS-pin Eingang ist UND auf Low geht. 
Darum sollte man den Pin als Master immer als Ausgang schalten. Vor dem 
einschalten des Master Mode.

von Nico (nico123)


Lesenswert?

Hallo cyblord und vielen Dank für diese Information! Ich habe bis jetzt 
noch nicht mit der SPI-Schnittstelle des ATMEGA gearbeitet und diese 
Info ist mir im Datenblatt noch nicht aufgefallen.

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.