mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zeichen ausgeben (SPI)


Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo liegt mein Gedankenfehler?
.INCLUDE "m88def.inc"

.def Dummy1     = r16

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.org 0x000     ; kommt ganz an den Anfang des Speichers

rjmp RESET ; Interruptvektoren überspringen und zum Hauptprogramm

reti           ; $001 External Interrupt Request 0
reti           ; $002 External Interrupt Request 1
reti           ; $003 Pin Change Interrupt Request 0
reti           ; $004 Pin Change Interrupt Request 0
reti           ; $005 Pin Change Interrupt Request 1
reti           ; $006 Watchdog Time-out Interrupt
reti           ; $007 Timer/Counter2 Compare Match A
reti           ; $008 Timer/Counter2 Compare Match A
reti           ; $009 Timer/Counter2 Overflow
reti           ; $00A Timer/Counter1 Capture Event
reti           ; $00B Timer/Counter1 Compare Match A
reti           ; $00C Timer/Counter1 Compare Match B
reti           ; $00D Timer/Counter1 Overflow
reti           ; $00E TimerCounter0 Compare Match A
reti           ; $00F TimerCounter0 Compare Match B
reti           ; $010 Timer/Couner0 Overflow
reti           ; $011 SPI Serial Transfer Complete
reti           ; $012 USART Rx Complete
reti           ; $013 USART, Data Register Empty
reti           ; $014 USART Tx Complete
reti           ; $015 ADC Conversion Complete
reti           ; $016 EEPROM Ready
reti           ; $017 Analog Comparator
reti           ; $018 Two-wire Serial Interface
reti           ; $019 Store Program Memory Read

RESET:         ; Hier beginnt das Hauptprogramm 

; Stackpointer initialisieren
ldi Dummy1, high(RAMEND) 
out SPH,Dummy1           
ldi Dummy1, low(RAMEND)
out SPL,Dummy1

; ***********************************************************************
; * Port instaliesieren                                                 *
; *   Ports alle auf Ausgang                                            *
; ***********************************************************************
ldi  Dummy1, 0b11111111
out DDRC,Dummy1 ; Port-C Ausgang
out DDRB,Dummy1 ; Port-B Ausgang
out DDRD,Dummy1 ; Port-D Ausgang 

; ***********************************************************************
; * SPI Modul konfigurieren                                             *
; ***********************************************************************
ldi   Dummy1, (1<<SPE) | (1<<MSTR) ; keine Interrupts, MSB first, Master
out   SPCR, Dummy1                 ; CPOL = 0, CPHA =0
                                   ; SCK Takt = 1/2 XTAL
  
ldi   Dummy1, (1<<SPI2X)           ; double speed aktivieren
out   SPSR, Dummy1                 ; Dummy Daten, um SPIF zu setzen
out   SPDR, Dummy1    

; ***********************************************************************
; * Alle Interrups aus                                                  *
; ***********************************************************************
cli


ldi   zl,low(SPIString*2) ; Z Pointer laden
ldi   zh,high(SPIString*2)


SPIOut:
      lpm                  ; nächstes Byte aus dem Flash laden
      adiw    zl:zh,1      ; Zeiger erhöhen
      and     r0,r0        ; = Null? 
      brne    SPIraus      ; wenn nein, -> raus damit 


Loop:
      rjmp Loop

; ***********************************************************************
; * R0 über SPI ausgeben                                                *
; ***********************************************************************
SPIraus:
    in      Dummy1, SPSR       ; prüfe ob eine alte Übertragung beendet ist 
    sbrs    Dummy1, SPIF  
    rjmp    SPIraus
    out     SPDR, r0           ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch
    rjmp    SPIOut


SPIString:      .db "SPI TestString vom ATMega88",13,10,0

Auf dem SPI kommt nix raus

PB3=Daten
PB5=Clock

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Auf dem SPI kommt nix raus

Woran erkennst du das?

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe jetzt
; ***********************************************************************
; * SPI Modul konfigurieren                                             *
; * 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                                      *
; ***********************************************************************
ldi   Dummy1, (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0) ; keine Interrupts, MSB first, Master
out   SPCR, Dummy1                             
                                     
  
ldi   Dummy1, 0                    ; double speed deaktivieren
out   SPSR, Dummy1                 

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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.