Forum: Mikrocontroller und Digitale Elektronik SPI Tut nichts


von Sascha712 (Gast)


Lesenswert?

Hallo,

hab mal zum Atmega32 gewechselt und versuche grad nen ST7920 
anzusteuern.

Komischerweise tut mein SPI gar nichts. Wenn ich den uC programmiere 
tauchen irgendwelche Grafiken auf dem LCD auf. Aber wenn ich den uC und 
das Display vom strom trenne und wieder verbinde, passiert nichts.

Ich hab auch zum testen ne LED an die SCK Leitung angeschlossen. Wenn 
ich den uC programmiere, dann leuchtet diese auch und das flashen klappt 
weiterhin. Nur beim strom trennen und verbinden, zeigt auch die LED 
keinerlei reaktion vom SPI bzw. SCK.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
//SPI Definitionen
5
#define DDR_SPI DDRB
6
#define DD_MOSI DDB5
7
#define DD_SCK DDB7
8
9
void SPI_Init(void)
10
{
11
  //MOSI und SCK als Output
12
  DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK);
13
  /*SPI Einschalten / Konfiguration als Master /
14
  bei 8MHz Systemtakt -> 500KHz SPITakt (Teiler von 16)*/
15
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); //|(1<<CPOL)|(1<<CPHA)
16
}
17
void SPI_Send(unsigned char Data1)
18
{
19
  //Data in den SPI-Sende-Register schreiben
20
  SPDR = Data1;
21
  //Warten bis die Übertragung abgeschlossen ist
22
23
}
24
void SendCommand(unsigned char Data)
25
{
26
  //Zu sendende Daten in zwei variabeln schreiben
27
  unsigned char H_Data = Data;
28
  unsigned char L_Data = Data;
29
  //Löschen der 4 niederwertigen Bits bei H_Data
30
  H_Data &= 0x0F;
31
  //Löschen der 4 höherwertigen Bits von L_Data
32
  L_Data &= 0xF0;
33
  /*verschieben um 4 bits nach links
34
  00001111 wird somit zu 11110000 */
35
  L_Data <<= 4;
36
  //Senden das ein Kommando folgt
37
  SPI_Send(0xF8);
38
  //Senden der 4 höherwertigen Bits von H_Data
39
  SPI_Send(H_Data);  
40
  //Senden der jetzt 4 höherwertigen Bits von L_Data
41
  SPI_Send(L_Data);
42
}
43
void SendData(unsigned char Data)
44
{
45
  //Zu sendende Daten in zwei variabeln schreiben
46
  unsigned char H_Data = Data;
47
  unsigned char L_Data = Data;
48
  //Löschen der 4 niederwertigen Bits bei H_Data
49
  H_Data &= 0x0F;
50
  //Löschen der 4 höherwertigen Bits von L_Data
51
  L_Data &= 0xF0;
52
  /*verschieben um 4 bits nach links
53
  00001111 wird somit zu 11110000 */
54
  L_Data <<= 4;
55
  //Senden das Daten folgen
56
  SPI_Send(0xFA);
57
  //Senden der 4 höherwertigen Bits von H_Data
58
  SPI_Send(H_Data);  
59
  //Senden der jetzt 4 höherwertigen Bits von L_Data
60
  SPI_Send(L_Data);
61
}
62
63
int main(void)
64
{  
65
66
  SPI_Init();
67
  
68
69
  _delay_ms(200);
70
  SendCommand(0x30);
71
  _delay_ms(50);
72
  SendCommand(0x30);
73
  _delay_ms(50);
74
  SendCommand(0x0F);
75
  _delay_ms(50);
76
  SendCommand(0x01);
77
  _delay_ms(50);
78
  SendCommand(0x06);
79
  _delay_ms(50);
80
  
81
}

von holger (Gast)


Lesenswert?

//Warten bis die Übertragung abgeschlossen ist

Wo ist der Code dafür? Und schalte den SS Pin auf Ausgang.

von holger (Gast)


Lesenswert?

Ohne CS am Display wird das auch nichts.
Nimm am besten gleich den SS Pin dafür.

von Sascha712 (Gast)


Lesenswert?

while(!(SPSR & (1<<SPIF)))
;
ist der code fürs warten, hab den erstmal ausgelassen, damit ich sehe ob 
SCK überhaupt was macht.

hab CS dauerhauft auf +5volt.

aber trotzdem müsste SPI doch was durchgeben? auch ohne CS? der Atmega 
ist ja als Master konfiguriert.

von holger (Gast)


Lesenswert?

>ist der code fürs warten, hab den erstmal ausgelassen, damit ich sehe ob
>SCK überhaupt was macht.

Was für eine bescheuerte Idee.

>hab CS dauerhauft auf +5volt.

Ist das der aktiv Pegel für CS? Oder wars doch low?

>aber trotzdem müsste SPI doch was durchgeben? auch ohne CS? der Atmega
>ist ja als Master konfiguriert.

Ohne SS Pin als Ausgang bleibt der das aber nicht lange;)

von holger (Gast)


Lesenswert?

>>hab CS dauerhauft auf +5volt.
>
>Ist das der aktiv Pegel für CS? Oder wars doch low?

Ok, high ist der aktiv Pegel.

von Sascha712 (Gast)


Lesenswert?

jetz blinkt die LED schonmal, wenn SCK aktiv ist. plinkt 5 mal kurz.
aufm display noch nichts zu sehen, da sollte eig nen blinkender kursor 
auftauchen.
Hab ich evtl irgendwelche Pausen vergessen? während ich die hohen und 
niedrigen bits sende? daran wirds bestimmt liegen=
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
//SPI Definitionen
5
#define DDR_SPI DDRB
6
#define DD_MOSI DDB5
7
#define DD_SCK DDB7
8
#define DD_CS DDB4
9
#define CS_PORT PORTB
10
#define CS PINB4
11
12
void SPI_Init(void)
13
{
14
  //MOSI und SCK als Output
15
  DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_CS);
16
  /*SPI Einschalten / Konfiguration als Master /
17
  bei 8MHz Systemtakt -> 500KHz SPITakt (Teiler von 16)*/
18
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); //|(1<<CPOL)|(1<<CPHA)
19
}
20
void SPI_Send(unsigned char Data1)
21
{
22
  //CS auf Hogh
23
  CS_PORT |= (1<<CS);
24
  
25
  //Data in den SPI-Sende-Register schreiben
26
  SPDR = Data1;
27
  //Warten bis die Übertragung abgeschlossen ist
28
  while(!(SPSR & (1<<SPIF)))
29
  {
30
    ;
31
  }
32
  CS_PORT &= ~(1<<CS);
33
}
34
void SendCommand(unsigned char Data)
35
{
36
  //Zu sendende Daten in zwei variabeln schreiben
37
  unsigned char H_Data = Data;
38
  unsigned char L_Data = Data;
39
  //Löschen der 4 niederwertigen Bits bei H_Data
40
  H_Data &= 0x0F;
41
  //Löschen der 4 höherwertigen Bits von L_Data
42
  L_Data &= 0xF0;
43
  /*verschieben um 4 bits nach links
44
  00001111 wird somit zu 11110000 */
45
  L_Data <<= 4;
46
  //Senden das ein Kommando folgt
47
  SPI_Send(0xF8);
48
  //Senden der 4 höherwertigen Bits von H_Data
49
  SPI_Send(H_Data);  
50
  //Senden der jetzt 4 höherwertigen Bits von L_Data
51
  SPI_Send(L_Data);
52
}
53
void SendData(unsigned char Data)
54
{
55
  //Zu sendende Daten in zwei variabeln schreiben
56
  unsigned char H_Data = Data;
57
  unsigned char L_Data = Data;
58
  //Löschen der 4 niederwertigen Bits bei H_Data
59
  H_Data &= 0x0F;
60
  //Löschen der 4 höherwertigen Bits von L_Data
61
  L_Data &= 0xF0;
62
  /*verschieben um 4 bits nach links
63
  00001111 wird somit zu 11110000 */
64
  L_Data <<= 4;
65
  //Senden das Daten folgen
66
  SPI_Send(0xFA);
67
  //Senden der 4 höherwertigen Bits von H_Data
68
  SPI_Send(H_Data);  
69
  //Senden der jetzt 4 höherwertigen Bits von L_Data
70
  SPI_Send(L_Data);
71
}
72
73
int main(void)
74
{  
75
76
  SPI_Init();
77
  
78
79
  _delay_ms(200);
80
  SendCommand(0x30);
81
  _delay_ms(50);
82
  SendCommand(0x30);
83
  _delay_ms(50);
84
  SendCommand(0x0F);
85
  _delay_ms(50);
86
  SendCommand(0x01);
87
  _delay_ms(50);
88
  SendCommand(0x06);
89
90
  
91
  
92
93
  
94
}

von holger (Gast)


Lesenswert?

Du darfst CS nicht bei jedem Byte rauf und runter ziehen.

von holger (Gast)


Lesenswert?

>  //Löschen der 4 niederwertigen Bits bei H_Data
>  H_Data &= 0x0F;

Nö. Da wird was anderes gelöscht.

>  //Löschen der 4 höherwertigen Bits von L_Data
>  L_Data &= 0xF0;

Wie oben nur umgekehrt.

von Sascha712 (Gast)


Lesenswert?

Habs so gemacht, das CS nun bei SendCommand und bei SendDate am anfang 
hoch und am ende runtergezogen wird.

LCD immer noch leer.

von Sascha712 (Gast)


Lesenswert?

Wie da wird das anderes gelöscht??

von Sascha712 (Gast)


Lesenswert?

void SendData(unsigned char Data)
{
  //Zu sendende Daten in zwei variabeln schreiben
  unsigned char H_Data = Data;
  unsigned char L_Data = Data;
  //Löschen der 4 niederwertigen Bits bei H_Data
  H_Data &= ~0x0F;
  //Löschen der 4 höherwertigen Bits von L_Data
  L_Data &= ~0xF0;
  /*verschieben um 4 bits nach links
  00001111 wird somit zu 11110000 */
  L_Data <<= 4;
  //CS auf High
  CS_PORT |= (1<<CS);
  //Senden das Daten folgen
  SPI_Send(0xFA);
  //Senden der 4 höherwertigen Bits von H_Data
  SPI_Send(H_Data);
  //Senden der jetzt 4 höherwertigen Bits von L_Data
  SPI_Send(L_Data);
  CS_PORT &= ~(1<<CS);
  _delay_ms(1);
}

hab die ~ vergessen..jetz gehts :D

Vielen viele Dank :D Das Forum ist echt klasse :)

von Sascha712 (Gast)


Angehängte Dateien:

Lesenswert?

Muss das hier nochmal ankratzen:

Irgendwie will es nicht so richtig klappen.

Ich muss zb. um ein zeichen zu schreiben
0xFA <-befehl zum daten senden
0xFA <-der sollte eigentlich überflüssig sein.
0x2A <-erstes zeichen
0x2B <-zweites zeichen

aber wenn ich es wie im Bild zu sehen sende, dann funktioniert es nicht.
7 ist SCK
8 ist MOSI
11 ist ChipSelect Leitung

Der Befehl, den ich sende ist auf dem Bild:
0xF8
0x30

Da das Display im SPI quasi im 4 Bit Modus anzusprechen ist
schicke ich:
SendCMD...4higbit...4lowbit..
0xF8......0x"3"0....0x"0"0
11111000..00110000..00000000

Meiner Meinung nach sollte das doch auch auf dem Bild stimmen?
Oder brauch ich Pausen zwischen den einzelnen Byte Paketen?

Was mich stutzig macht ist das kurze High bei der fallenden flanke von 
SCK.

Mit freundlichem Gruß

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.