Forum: Mikrocontroller und Digitale Elektronik Schieberegister am ATMega8


von Luigi A. (spok)


Angehängte Dateien:

Lesenswert?

Hallo zusammen, ich habe ein Schieberegister an meinem ATMega8 
angeschlossen.(wie im Anhang dargestellt)
Steuerung via SPI funktioniert enínwandfrei.

Wenn ich jedoch einen Schiebevorgang stand alone losjage verändert sich 
das LED Muster nicht :-(

Codeauschnitt:

bis hier hin steht der Code via SPI Modul und das Muster 0b00000011 wird 
an die LED´s ausgegeben.

....
       cbi schiebe_port, SIN
       sbi schiebe_port, SCK
       cbi schiebe_port, SCK
       sbi schiebe_port, RCK
       cbi schiebe_port, RCK
....

der Code sollte doch ein Schiebevorgang verursachen und das Muster 
0b00000110

erzeugen oder?

Danke für eure Unterstüzung.

von Karl H. (kbuchegg)


Lesenswert?

Luigi A. schrieb:

> Codeauschnitt:
>
> bis hier hin steht der Code via SPI Modul und das Muster 0b00000011 wird
> an die LED´s ausgegeben.
>
> ....
>        cbi schiebe_port, SIN
>        sbi schiebe_port, SCK
>        cbi schiebe_port, SCK
>        sbi schiebe_port, RCK
>        cbi schiebe_port, RCK
> ....
>
> der Code sollte doch ein Schiebevorgang verursachen


ja sollte er.

Bist du zb sicher, dass du nicht anderwärtig gleich danach wieder das 
urspüngliche Muster drüber jagst?
/Genau deswegen haben wir hier keine Freude mit Code-Schnipseln. Man 
sieht einfach nicht, was sonst noch so alles passiert und welche 
Nebenbedingungen existieren.

von Luigi A. (spok)


Lesenswert?

Hi kbuchegg,

hier der gesamte code:
den Passus findest du kurz unter main:

1
.include "m8def.inc"
2
.def temp1 = r16
3
.def temp2 = r17
4
.def temp3 = r18
5
6
; Die Definitionen müssen an den jeweiligen AVR angepasst werden
7
 
8
.equ SCHIEBE_DDR  = DDRB
9
.equ SCHIEBE_PORT = PORTB
10
.equ RCK          = PB2     ; SS
11
.equ SCK          = PB5     ; SCK
12
.equ SIN          = PB3     ; MOSI
13
 
14
    ldi   temp1, LOW(RAMEND)     ; Stackpointer initialisieren
15
    out   SPL, temp1
16
    ldi   temp1, HIGH(RAMEND)
17
    out   SPH, temp1  
18
;
19
; SCK, MOSI, SS als Ausgänge schalten
20
;
21
    in    temp1, SCHIEBE_DDR
22
    ori   temp1, (1<<SIN) | (1<<SCK) | (1<<RCK) 
23
    out   SCHIEBE_DDR,temp1     
24
;
25
; SPI Modul konfigurieren
26
;
27
    ldi   temp1, (1<<SPE) | (1<<MSTR)
28
    out   SPCR, temp1           ; keine Interrupts, MSB first, Master
29
                                ; CPOL = 0, CPHA =0
30
                                ; SCK Takt = 1/2 XTAL
31
    ldi   temp1, (1<<SPI2X)
32
    out   SPSR, temp1           ; double speed aktivieren
33
    out   SPDR, temp1           ; Dummy Daten, um SPIF zu setzen
34
35
    
36
; LED alle aus
37
  rcall led_all_off
38
39
main:
40
41
  ldi   temp1, 0b00000011
42
  rcall Schiebe               ; Daten schieben
43
  rcall SchiebeOut            ; Daten in Ausgangsregister übernehmen
44
   
45
  
46
47
  rcall wait1s        ;1 Sekunde waten
48
49
  sbi schiebe_port, SCK
50
  cbi schiebe_port, SCK
51
  sbi   SCHIEBE_PORT, RCK
52
    cbi   SCHIEBE_PORT, RCK
53
  
54
loop:
55
    rjmp  loop
56
 
57
;-----------------------------------------------------------------------------
58
;
59
; Die Daten im Schieberegister in das Ausgaberegister übernehmen
60
;
61
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen
62
;
63
SchiebeOut:
64
    sbis  SPSR, SPIF            ; prüfe ob eine alte Übertragung beendet ist
65
    rjmp  SchiebeOut
66
    sbi   SCHIEBE_PORT, RCK
67
    cbi   SCHIEBE_PORT, RCK
68
    ret
69
 
70
;-----------------------------------------------------------------------------
71
;
72
; 8 Bits aus temp1 an das Schieberegister ausgeben
73
;
74
Schiebe:
75
    sbis    SPSR, SPIF      ; prüfe ob eine alte Übertragung beendet ist
76
    rjmp    Schiebe
77
    out     SPDR, temp1     ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch
78
    ret
79
80
81
82
83
84
;-----------------------------------------------------------------------------
85
;
86
;Warteschleife 1s über 16 Bit Zähler
87
;Bei 4Mhz Prozessortakt ca 1sec Dauer
88
;Formel Zeit=[(5+(3*(mk-1)+1+2))*(dl1-1)+2] * (1/OSCfreq)
89
;mit dl1(Anfangsstand 16 Bit Zähler) und mk(Verlängerung der Takte) kann die Zeit verändert werden
90
91
.equ dl1 = 0xffff
92
.equ mk = 19
93
94
wait1s:
95
  push temp1
96
  
97
  
98
  ldi r25, high(dl1)  ;1 Takt
99
  ldi r24, low(dl1)  ;1 Takt
100
  
101
102
loop1:
103
  ldi temp1, mk  ;1 Takt
104
  sbiw r24, 1    ;2 Takte
105
  brne loop2    ;2 Takte, wenn Z=0 dann 1 Takt
106
  rjmp end1    ;2 Takte
107
108
109
loop2:
110
  dec temp1    ;1 Takt
111
  brne loop2    ;2 Takte, wenn Z=0 dann 1 Takt
112
  rjmp loop1    ;2 Takte
113
114
115
end1:
116
  pop temp1
117
  ret
118
119
120
;-----------------------------------------------------------------------------
121
;
122
;LED alle aus
123
124
LED_all_off:
125
  push temp1
126
127
  ldi   temp1, 0b0000000
128
    rcall Schiebe               ; Daten schieben
129
  ldi   temp1, 0b0000000
130
    rcall Schiebe               ; Daten schieben
131
  ldi   temp1, 0b0000000
132
    rcall Schiebe               ; Daten schieben
133
  ldi   temp1, 0b0000000
134
    rcall Schiebe               ; Daten schieben
135
    rcall SchiebeOut            ; Daten in Ausgangsregister übernehmen  
136
  
137
  pop temp1
138
  ret

von Felix A. (madifaxle)


Lesenswert?

So beim Überfliegen würde ich sagen, dass es deshalb nicht geht, weil du 
nach Init des SPI keinen Zugriff mehr auf die IO-Pins SCK und MOSI hast.

Wenn du nach derinem Wait1s den SPI deaktivierst, sollte sich was 
ändern.

von Luigi A. (spok)


Lesenswert?

Felix A. schrieb:

> Wenn du nach derinem Wait1s den SPI deaktivierst, sollte sich was
> ändern.

Hallo Felix,

danke genau das war es gewesen.
:-)

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.