mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega64 SPI Problem


Autor: Christoph S. (mcseven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi *,

ich bin langsam am verzweifeln, mein SPI am mega64 will keine Bits 
ausspucken (SCK/MOSI kein signal am Ozsi). PORTB ist komplett als Out 
konfiguriert, mein SPCR=0x0b01011000, SPSR=0x00.

Ich kann in SPDR genau ein Byte reinschreiben, dann geht er nach 
"while(!(SPSR & 0b1000000))" eins weiter, aber danach will SPIF nicht 
mehr auf eins gehen und das Programm bleibt hängen.

Die SPI Fuse ist auf enabled gesetzt, sonst könnte ich ja nix reinladen. 
Aber ich hab nirgendwo gesehen, dass ich mit der Fuse enabled das SPI im 
regulären Betrieb nicht benutzen kann...

Gibts da sonst noch Fallstricke?

Danke

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Fehler ist in Programmzeile 42.

Autor: Christoph S. (mcseven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast natürlich recht :) ist schon spät.... here comes:
#include <mega64.h>
#include <delay.h>

void main(void) {
PORTA=0x00; //DEBUG LEDS
DDRA=0xFF;

PORTB=0x00; //SPI PORT
DDRB=0xFF;

TIMSK=0x00;
ETIMSK=0x00;

SPCR=0x0b01011000;
SPSR=0x00;

while (1) {
  PORTA = 0xFF; //LEDs aus
  SPDR = 0x40;
  while(!(SPSR & (1<<8))) {}
  PORTA.0 = 0; //1. LED an
  delay_ms(1000);
  SPDR = 0xA1;
  while(!(SPSR & (1<<8))) {}
  PORTA.1 = 0; //2. LED an
  delay_ms(1000);
};
}

ich messe hier mir dem oszi an SCK und MOSI, aber da rührt sich (außer 
beim Programmieren) nichts. Wohl aber ändert SCK die Ruhepolarität, wenn 
ich die Polarität im SPCR ändere. Er kommt aus der ersten While Warte 
Schleife nicht raus, und ich kann mir nicht erklären, weshalb. Quarz ist 
16MHz, Compiler ist CodeVision, neueste Version.

Hab ich etwas übersehen?

Danke.

Autor: S. Seegel (energizer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MISO darf nicht als Ausgang gesetzt werden, nur SS, MOSI und SCK.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>MISO darf nicht als Ausgang gesetzt werden, nur SS, MOSI und SCK.

Bei MasterMode ist kann und sollte der als Ausgang geschaltet sein.

ich vermute folgendes:
while (1)
{
  SPDR = 0x40;
  while(!(SPSR & (1<<8)));

  delay_ms(1000);

  SPDR = 0xA1;
  while(!(SPSR & (1<<8)));
  delay_ms(1000);
}
lt deinen Einstelungen sendest du mit clk/4. ergibt bei 16MHz eine 
Sendedauer von 2µsek!
Und das wird alle 1'000'000µsek  gesendet! Das ist ohne geeignete 
Triggerung nicht "zu finden".
Vorschlag:
Lass mal beide Delays weg, somit müsste der einfach die zwei Bytes 
rausblasen.
Fehler im Code finde ich nicht. Mal abgesehen, dass man einiges schöner 
schreiben kann:
while(!(SPSR & (1<<SPIF)));
...

Autor: Christoph S. (mcseven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ist ohne geeignete Triggerung nicht "zu finden".
hab ein tds 2014, das findet alles =)

Egal, hier war der Fehler:
while(!(SPSR & (1<<SPIF)));
kennt codevision nicht.
 while(!(SPSR & (1<<8))); 
verursachte einen deadlock
 while(!(SPSR & 0b1000000)); 
tut jetzt und mit timebase 1us schön sichtbar :)

Danke euch und gn8

Autor: S. Seegel (energizer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>MISO darf nicht als Ausgang gesetzt werden, nur SS, MOSI und SCK.
>Bei MasterMode ist kann und sollte der als Ausgang geschaltet sein.

Hm, du meinst wohl eher Eingang, wenn wir von MISO im Mastermode 
sprechen ?
Wie auch immer, im Datenblatt heist es dass MISO sowieso fest auf 
Eingang geschaltet wird wenn der SPI Mastermode aktiviert wird. Der Rest 
(MOSI, SCK und SS) sind "user defined" und sollten auf Ausgang 
geschaltet werden, was er auch schön getan hat.

>ich messe hier mir dem oszi
Da würde ich mich mal Matthias anschließen. Dieser Peak-Tech Logic-Probe 
(früher sagte man da mal Logiktester) tut für sowas hervorragende 
Dienste, weil du damit auch sehr kurze Impulse sichtbar machen kannst.

Autor: S. Seegel (energizer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, mein Betrag war ein paar Sekunden zu spät um sinnvoll zu sein :-)
while(!(SPSR & (1<<8)));

Hoppla, da fällt es mir wie Schuppen von den Haaren. 1<<8 ist das neunte 
Bit, aber SPSR hat nur 8 :-)

Das hier sollte es dann tun:
while(!(SPSR & (1<<7)));

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph Söllner wrote:
> ich messe hier mir dem oszi an SCK und MOSI, aber da rührt sich (außer
> beim Programmieren) nichts.
Wieso ändert sich beim Programmieren was an MOSI? Du hast doch nicht 
etwa den ISP-Anschluss an MOSI und MISO angeschlossen? Wenn dem so wäre, 
dürftest Du den µC allerdings überhaupt nicht programmieren können.

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.