Forum: Mikrocontroller und Digitale Elektronik ATmega32 sendet nicht auf SPI


von Tycho (Gast)


Lesenswert?

Hallo allerseits,
ich habe den unten angeführten Code geflasht, sehe allerdings mit dem 
Oszi nichts auf SCLK, MOSI und MISO. Die Schaltung und ATmega32 
funktionieren, ein anderes Code mit USART-Kommunikation lief und 
kommunizierte mit dem PC.
Ich habe die SPI-Funktionalität auf das Minimum reduziert, also nur ein 
Interrupt, der jedesmal ein Byte der Form 0x10101010b rausschiebt.
Auch der AVR-Simulator macht das Richtige, auf PINB7 und PINB5 sieht man 
die Clock und das Signal.
Ich kann mir vorstellen, dass vielleicht der Systemtakt (16MHz) für SPI 
zu hoch ist, es muss mit 16MHz/16=1MHz takten, oder aber meine 
SPI-Initialisierungsroutine ist nicht korrekt, wobei die an das 
Datenblatt angelehnt ist, ich musste nur noch den SS als Ausgang machen 
(physikalisch nirgends angeschlossen, hängt also in der Luft, hier das 
Problem?), sonst hat die Simulation nicht funktioniert.
1
.NOLIST
2
.INCLUDE "m32def.inc" ; Header fuer ATMEGA32
3
.LIST
4
5
6
.equ BAUD  = 250000                            ; Baudrate
7
8
.equ F_CPU = 16000000                            ; Systemtakt in Hz
9
10
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
11
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
12
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
13
 
14
.if ((BAUD_ERROR>1) || (BAUD_ERROR<-1))       ; max. +/-1 Promille Fehler
15
  .error "Systematischer Fehler der Baudrate grösser 1 Promille und damit zu hoch!"
16
.endif
17
18
19
20
; ============================================
21
; R E G I S T E R D E F I N I T I O N E N
22
; ============================================
23
.DEF MehrZweckRegister = R16 
24
25
; ============================================
26
; R E S E T U N D I N T V E K T O R E N
27
; ============================================
28
;
29
.CSEG
30
.ORG $0000
31
jmp Main ; Reset Vektor
32
33
reti ; Int Vektor 2
34
nop
35
36
reti ; Int Vektor 3
37
nop
38
39
reti ; Int Vektor 4
40
nop
41
42
reti ; Int Vektor 5
43
nop
44
45
reti ; Int Vektor 6
46
nop
47
48
reti ; Int Vektor 7
49
nop
50
51
reti ; Int Vektor 8
52
nop
53
54
reti ; Int Vektor 9
55
nop
56
57
reti ; Int Vektor 10
58
nop
59
60
reti ; Int Vektor 11
61
nop
62
63
reti ; Int Vektor 12
64
nop
65
66
rjmp int_SPI ; Int Vektor 13 Serial Transfer Complete
67
nop
68
69
reti ; Int Vektor 14
70
nop
71
72
reti ; Int Vektor 15 
73
nop
74
75
reti ; Int Vektor 16
76
nop
77
78
reti ; Int Vektor 17
79
nop
80
81
reti ; Int Vektor 18
82
nop
83
84
reti ; Int Vektor 19
85
nop
86
87
reti ; Int Vektor 20
88
nop
89
90
reti ; Int Vektor 21
91
nop
92
93
;
94
; ============================================
95
; I N T E R R U P T S E R V I C E
96
; ============================================
97
int_SPI:
98
  
99
  push    MehrZweckRegister    
100
  in    MehrZweckRegister, SREG                
101
  push  MehrZweckRegister
102
  
103
  ldi MehrZweckRegister, 170
104
  out SPDR, MehrZweckRegister
105
106
  pop   MehrZweckRegister
107
  out   SREG, MehrZweckRegister
108
  pop     MehrZweckRegister                              
109
reti
110
;
111
; ============================================
112
; U N T E R F U N K T I O N E N
113
; ============================================
114
InitRegister:
115
  clr MehrZweckRegister  
116
ret
117
118
119
InitSPI:
120
121
    ; PB4 SS, PB5 MOSI, PB6 MISO, PB7 SCLK
122
  ldi MehrZweckRegister, (1<<DDB4)|(1<<DDB5)|(1<<DDB7)
123
  out DDRB,MehrZweckRegister
124
  ; Enable SPI, Master, set clock rate fck/16, cpol=1, cpha=1
125
  ldi MehrZweckRegister, (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL)|(1<<CPHA)
126
  out SPCR,MehrZweckRegister  
127
  
128
ret
129
130
131
; ============================================
132
; H A U P T - P R O G R A M M I N I T
133
; ============================================
134
Main:
135
        
136
  ldi MehrZweckRegister,high(RAMEND) ; Main program start
137
  ldi MehrZweckRegister,high(RAMEND) ; Main program start
138
  out SPH,MehrZweckRegister ; Set Stack Pointer to top of RAM
139
  ldi MehrZweckRegister,low(RAMEND)
140
  out SPL,MehrZweckRegister
141
142
  RCall  InitRegister  
143
  Rcall  InitSPI
144
145
146
  ldi MehrZweckRegister,1<<SE ; Enable sleep mode
147
  out MCUCR,MehrZweckRegister
148
149
  sei ; schalte Ints ein;
150
151
  ldi MehrZweckRegister,1<<SPIF ;Enable SPI
152
  out SPSR, MehrZweckRegister
153
  
154
155
  ; ============================================
156
  ; P R O G R A M M – S C H L E I F E
157
  ; ============================================
158
  ;
159
Loop:
160
  sleep ; schlafen legen
161
  nop ; Dummy fuer Aufwachen
162
  
163
  rjmp loop ; zurueck in die Schlafposition

von spess53 (Gast)


Lesenswert?

Hi

>  ldi MehrZweckRegister,1<<SPIF ;Enable SPI
>  out SPSR, MehrZweckRegister

Lt. Datenblatt ist das SPI-Flag Read-Only. Demzufolge ist das 
wirkungslos.

MfG Spess

von Tycho (Gast)


Lesenswert?

Ja, daran lag es :)
Ich wäre selbst nie drauf gekommen, Simulation lief ja. Du ersparst mir 
dutzende Stunden der Suche, anschliessende Frustration und Kapitulation.
Vielen herzlichen Dank!

Grüße
Tycho

von Tycho (Gast)


Lesenswert?

Und eine ganz kurze Nachfrage hinterher: braucht man dieses nop nach 
sleep überhaupt?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Tycho schrieb:
> braucht man dieses nop nach
> sleep überhaupt?

Nö.

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.