Forum: Mikrocontroller und Digitale Elektronik Zeichen ausgeben (SPI)


von Holger P. (Gast)


Lesenswert?

Wo liegt mein Gedankenfehler?
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1     = r16
4
5
.equ F_CPU = 8000000                            ; Systemtakt in Hz
6
.org 0x000     ; kommt ganz an den Anfang des Speichers
7
8
rjmp RESET ; Interruptvektoren überspringen und zum Hauptprogramm
9
10
reti           ; $001 External Interrupt Request 0
11
reti           ; $002 External Interrupt Request 1
12
reti           ; $003 Pin Change Interrupt Request 0
13
reti           ; $004 Pin Change Interrupt Request 0
14
reti           ; $005 Pin Change Interrupt Request 1
15
reti           ; $006 Watchdog Time-out Interrupt
16
reti           ; $007 Timer/Counter2 Compare Match A
17
reti           ; $008 Timer/Counter2 Compare Match A
18
reti           ; $009 Timer/Counter2 Overflow
19
reti           ; $00A Timer/Counter1 Capture Event
20
reti           ; $00B Timer/Counter1 Compare Match A
21
reti           ; $00C Timer/Counter1 Compare Match B
22
reti           ; $00D Timer/Counter1 Overflow
23
reti           ; $00E TimerCounter0 Compare Match A
24
reti           ; $00F TimerCounter0 Compare Match B
25
reti           ; $010 Timer/Couner0 Overflow
26
reti           ; $011 SPI Serial Transfer Complete
27
reti           ; $012 USART Rx Complete
28
reti           ; $013 USART, Data Register Empty
29
reti           ; $014 USART Tx Complete
30
reti           ; $015 ADC Conversion Complete
31
reti           ; $016 EEPROM Ready
32
reti           ; $017 Analog Comparator
33
reti           ; $018 Two-wire Serial Interface
34
reti           ; $019 Store Program Memory Read
35
36
RESET:         ; Hier beginnt das Hauptprogramm 
37
38
; Stackpointer initialisieren
39
ldi Dummy1, high(RAMEND) 
40
out SPH,Dummy1           
41
ldi Dummy1, low(RAMEND)
42
out SPL,Dummy1
43
44
; ***********************************************************************
45
; * Port instaliesieren                                                 *
46
; *   Ports alle auf Ausgang                                            *
47
; ***********************************************************************
48
ldi  Dummy1, 0b11111111
49
out DDRC,Dummy1 ; Port-C Ausgang
50
out DDRB,Dummy1 ; Port-B Ausgang
51
out DDRD,Dummy1 ; Port-D Ausgang 
52
53
; ***********************************************************************
54
; * SPI Modul konfigurieren                                             *
55
; ***********************************************************************
56
ldi   Dummy1, (1<<SPE) | (1<<MSTR) ; keine Interrupts, MSB first, Master
57
out   SPCR, Dummy1                 ; CPOL = 0, CPHA =0
58
                                   ; SCK Takt = 1/2 XTAL
59
  
60
ldi   Dummy1, (1<<SPI2X)           ; double speed aktivieren
61
out   SPSR, Dummy1                 ; Dummy Daten, um SPIF zu setzen
62
out   SPDR, Dummy1    
63
64
; ***********************************************************************
65
; * Alle Interrups aus                                                  *
66
; ***********************************************************************
67
cli
68
69
70
ldi   zl,low(SPIString*2) ; Z Pointer laden
71
ldi   zh,high(SPIString*2)
72
73
74
SPIOut:
75
      lpm                  ; nächstes Byte aus dem Flash laden
76
      adiw    zl:zh,1      ; Zeiger erhöhen
77
      and     r0,r0        ; = Null? 
78
      brne    SPIraus      ; wenn nein, -> raus damit 
79
80
81
Loop:
82
      rjmp Loop
83
84
; ***********************************************************************
85
; * R0 über SPI ausgeben                                                *
86
; ***********************************************************************
87
SPIraus:
88
    in      Dummy1, SPSR       ; prüfe ob eine alte Übertragung beendet ist 
89
    sbrs    Dummy1, SPIF  
90
    rjmp    SPIraus
91
    out     SPDR, r0           ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch
92
    rjmp    SPIOut
93
94
95
SPIString:      .db "SPI TestString vom ATMega88",13,10,0

Auf dem SPI kommt nix raus

PB3=Daten
PB5=Clock

von spess53 (Gast)


Lesenswert?

Hi

>Auf dem SPI kommt nix raus

Woran erkennst du das?

MfG Spess

von Holger P. (Gast)


Lesenswert?

Habe den AVR USB LAB als SPI-Logger geflasht. Bei einem Gerät welches 
zeichen aussendet zeigt er die Zeichen an. Nur bei mir nicht.

Habe ich da was falsch verstanden?

von spess53 (Gast)


Lesenswert?

Hi

>Habe den AVR USB LAB als SPI-Logger geflasht. Bei einem Gerät welches
>zeichen aussendet zeigt er die Zeichen an. Nur bei mir nicht.

>Habe ich da was falsch verstanden?

Weiss ich nicht. Aber auf einem ATMega48 läuft das Programm. Vielleicht 
bist du einfach zu schnell.

MfG Spess

von Holger P. (Gast)


Lesenswert?

Du hast das ( mein ) Programm am laufen?? WOW Wie wo stelle ich die 
Geschwindigkeit ein.

Die Pins sind also auch richtig

PB3=Daten ( MOSI )
PB5=Clock ( SCK )

Und GND mehr brauch ich doch nicht oder

von spess53 (Gast)


Lesenswert?

Hi

>Du hast das ( mein ) Programm am laufen??

Daten und Takt sind an den Pins vorhanden.

> WOW Wie wo stelle ich die Geschwindigkeit ein.

Mit den SPI2X-, SPR1-, SPR0-Bits in SPCR

>Die Pins sind also auch richtig

>PB3=Daten ( MOSI )
>PB5=Clock ( SCK )

Ja.

Und GND mehr brauch ich doch nicht oder

Brauchst du unbedingt.

MfG Spess

von Holger P. (Gast)


Lesenswert?

ich habe nun mal

ldi   Dummy1, 0                    ; double speed aktivieren
out   SPSR, Dummy1                 ; Dummy Daten, um SPIF zu setzen
out   SPDR, Dummy1

somit habe ich doch die Geschwindigkeit verringert.

Würdest du mir mal die Register erklären oder sagen wo ich das in 
deutsch nachlesen kann?

spess53 schrieb:
>>PB3=Daten ( MOSI )
>
>>PB5=Clock ( SCK )
>
>
>
> Ja.
>
>
>
> Und GND mehr brauch ich doch nicht oder
>
>
>
> Brauchst du unbedingt.

Wie meinst du das?

von Holger P. (Gast)


Lesenswert?

Ich habe den Internen-Takt von 8MHz

SPI2X, SPR1 und  SPR0 habe ich alle auf 0

geht aber noch nicht

SPR1 und SPR0 sind das teiler?
SPI2X verstehe ich als doppelten Takt nehmen. oder?

Ich finde hier kein Tutorial darüber

********


Bis jetzt habe ich nur herrausbekommen:

Wenn SPI2X, SPR1 und SPR0 alle auf 0 sind ist f_SCK = f_osc/4
Wenn SPI2X auf 1 ist ins fosc/2

So hatte ich wohl am anfang 8Mhz/2=4Mhz
Jetzt habe ich SPI2X auf 0 also 8Mhz/4=2Mhz

Ist wohl auch noch zu schnell.

Wie wende ich SPR1 und SPR0 an?

von Holger P. (Gast)


Lesenswert?

Ok habe jetzt durch die Info die es so im Netz gibt folgende Tabelle 
gemacht

SPR1=0 SPR0=0 SPI2X=0 = CPU/4
SPR1=0 SPR0=0 SPI2X=1 = CPU/2
SPR1=0 SPR0=1 SPI2X=0 = CPU/16
SPR1=0 SPR0=1 SPI2X=1 = CPU/8
SPR1=1 SPR0=0 SPI2X=0 = CPU/64
SPR1=1 SPR0=0 SPI2X=1 = CPU/32
SPR1=1 SPR0=1 SPI2X=0 = CPU/128
SPR1=1 SPR0=1 SPI2X=1 = CPU/64

So werde ich es nun mal mit SPR1=1 SPR0=0 SPI2X=0 = CPU/64 versuchen

von spess53 (Gast)


Lesenswert?

Hi

>somit habe ich doch die Geschwindigkeit verringert.

Ja aber der SPI-Takt darf nicht grösser wie 1/4 der Taktfrequenz der 
Empfängers sein. Und die kenne ich nicht.

Die Registerbeschreibung findest du im Datenblatt unter '18.5 Register 
Description' S.167. Das ist allerdings in Englisch. Aber da must du 
durch.

>Wie meinst du das?

Masseverbindung muss sein.

MfG Spess

von Holger P. (Gast)


Lesenswert?

Habe jetzt
1
; ***********************************************************************
2
; * SPI Modul konfigurieren                                             *
3
; * SPR1=0 SPR0=0 SPI2X=0 = CPU/4                                       *
4
; * SPR1=0 SPR0=0 SPI2X=1 = CPU/2                                       *
5
; * SPR1=0 SPR0=1 SPI2X=0 = CPU/16                                      *
6
; * SPR1=0 SPR0=1 SPI2X=1 = CPU/8                                       *
7
; * SPR1=1 SPR0=0 SPI2X=0 = CPU/64                                      *
8
; * SPR1=1 SPR0=0 SPI2X=1 = CPU/32                                      *
9
; * SPR1=1 SPR0=1 SPI2X=0 = CPU/128                                     *
10
; * SPR1=1 SPR0=1 SPI2X=1 = CPU/64                                      *
11
; ***********************************************************************
12
ldi   Dummy1, (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0) ; keine Interrupts, MSB first, Master
13
out   SPCR, Dummy1                             
14
                                     
15
  
16
ldi   Dummy1, 0                    ; double speed deaktivieren
17
out   SPSR, Dummy1                 
18
19
out   SPDR, Dummy1                 ; Dummy Daten, um SPIF zu setzen

also 62,5Khz bei einem CPUtakt von 8 MHz richtig?

Es kommen nun auch teile an. Nehme mal an as der AVR USB LAB zu langsam 
ist. Mein Code müsste aber stimmen. Also bin ich auf dem richtigen weg. 
Möchte halt nur mal die Grundlagen verstehen.

von spess53 (Gast)


Lesenswert?

Hi

>also 62,5Khz bei einem CPUtakt von 8 MHz richtig?

Ja, stimmt. Allerdings brauchst du es nicht so langsam machen. Mit 
welcher Taktfrequenz läuft denn das AVR USB LAB. Evtl. ist ein Quarz 
drauf, von dem du das ablesen kannst. Davon maximal 1/4.

>Es kommen nun auch teile an. Nehme mal an as der AVR USB LAB zu langsam
>ist. Mein Code müsste aber stimmen. Also bin ich auf dem richtigen weg.
>Möchte halt nur mal die Grundlagen verstehen.

Was kommt denn von deinem Text an? Möglicherweise stimmt der SPI-Mode 
nicht. Du könntest mal mit den CPOL-/CPHA-Bits (siehe S.166) spielen. 
Oder du machst mal ein Delay (zu Test) zwischen die Zeichenausgabe.

Noch was:

      lpm                  ; nächstes Byte aus dem Flash laden
      adiw    zl:zh,1      ; Zeiger erhöhen

geht einfacher

     lpm rxy,Z+

MfG Spess

von Holger P. (Gast)


Lesenswert?

Nun habe ich alles mögliche hin und her versucht und die Tatsache das 
jenes Programm läuft wie hier getippt wurde lässt mich nun auf die Idee 
lpmmen das ich eventuell ein ein Hardwareproblem habe.

Muss ich ihrgendetwas beachten. Oder reicht es wenn ich Data und Clock 
direkt verbinde?

Habe nix an dem ATMega dran rein gar nix und Data und Clock direkt 
verbunden.

Ich bekomme zwar nun das Zeichen welches ich aussende aber nicht immer. 
Das programm springt zwar alle Sekunde in die Routine sendet auch was 
aus aber angezeigt bekomme ich es nicht immer. In den seltensten fälle 
etwas falsches. Ich sende ein H aus.

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.