PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit SPI



G3tzR@zor
15.02.2012, 18:08
Hallo,
ich habe mal wieder angefangen mich mit uC Programmierung zu beschäftigen. Am Ende will ich über mehrere 74HC595 über UDN2981 Ein LED bild ansteuern.

Leider hackt es mal wieder bei der Programmierung. Versuche nun schon seit Tagen das SPI im Atmega 8 zum laufen zu bekommen, leider ohne erfolg.
Im Netz stoße ich bei meiner Suche immer nur auf Bascom oder ASM.



//************************************************** ***************************
//* ATmega8 @ 8 MHz interner OC
//* LED Ansteuerung für Skorpion LED Bild mit Sternen
//* 34 Reihen a 5 Low Current LEDs Grün
//* 12 Reihen a 5 Ultrahelle LEDs 3mm(Rot Gelb) 5mm (Weiß Blau)
//* Anteuerung der LEDs über 74HC595 und UDN2981A
//* UDN2981 VSS 12V
//*
//************************************************** ************************

#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>

uint16_t i;

void my_delay(uint16_t milliseconds) {
for(; milliseconds>0; milliseconds--)
_delay_ms(1);
}

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB2);
DDRB &= ~(1<<DDB4);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL);
}

void SPI_MasterTransmit(uint8_t cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
return SPDR;
}

int main(void)
{
SPI_MasterInit();


while(1)
{
SPI_MasterTransmit(0xFF);
PORTB |=(1<<PB2);
my_delay(10);
PORTB &= ~(1<<PB2);
my_delay(2000);
SPI_MasterTransmit(0xAA);
PORTB |=(1<<PB2);
my_delay(10);
PORTB &= ~(1<<PB2);
my_delay(2000);
SPI_MasterTransmit(0x55);
PORTB |=(1<<PB2);
my_delay(10);
PORTB &= ~(1<<PB2);
my_delay(2000);
}


return 0;
}


Wenn ich diesen Code in der Simulation des AVR Studio 5 laufen lasse, wird kein Wert in SPDR übernommen????
Flashe ich den Code auf meinen Mega8 und lasse ihn in meiner Testschaltung auf den Breadboard laufen lasse tut sich auch NICHTS.
Ich habe zur Kontolle des RCK an PB2 eine LED angeschlossen. Diese Leuchtet dauerhaft schwach.
Wenn ich mich nicht irre sollte diese nach der übertragung für die jeweilige Anzeigedauer des Musters aus sein???

Ich weis nicht mehr weiter ich bin für jede Hilfe dankbar.

MfG G3tzR@zor

ePyx
15.02.2012, 18:28
An RCK/SCK liegt der Clock an. Der sollte nicht aus sein. Wenn dann der Chipselect (SS) da der invertierend angesprochen wird.

G3tzR@zor
15.02.2012, 19:17
Hallo danke für deine Antwort, leider verstehe ich nicht ganz was du meinst.
RCK an PB2(SS)
SCK an PB5(SCK)
SI an PB3(MOSI)
PB4 (MISO) als Eingang da Master
Wenn ich das Datenblatt des 74HC595 richtig verstanden habe brauche ich immer ein L-->H Flanke um die Daten nach der Übertragung auf die Ausgänge zu legen.

Was meinst du genau mit "Der sollte nicht aus sein"? Ich schalte den PB2 immer aus um dann nach der nächsten Übertragung direkt wieder eine L-->H Flanke zu bekommen.
MfG

ePyx
15.02.2012, 19:28
Hab nicht mit bekommen, dass es sich um ein 74xx59 handelt. Sorry. Hast du G auf Low gelegt ?

G3tzR@zor
15.02.2012, 19:38
Ja, G liegt auf Low und SCLR auf VSS.
Hab gerade mal versucht SPDR durch PORTB auszutauschen. Im Simulator übernimmt er die Daten in PORTB. Nur wenn ich die Daten in den SPDR schreiben will, werden diese nicht übernommen. Oder zeigt mir der AVR Studio 5 Simulator dies nur nicht an?

Also Anstatt SPDR = cData --> PORTB = cData
nur zum Testen im Simulator!

ePyx
15.02.2012, 19:57
Hab letztens http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister#Ansteuerung_per_SPI-Modul ausprobiert und eigentlich funktionierte auch alles. Dort wird ja SS/RCK auch gesetzt und anschließend wieder gelöscht.

G3tzR@zor
15.02.2012, 20:13
Danke für deinen Link, leider kann ich mit Assambler nicht wirklich viel anfangen. Werde mal versuchen die SPI in Software zu proggen. Mal sehen was dann meine LEDs machen.

MfG

markusj
15.02.2012, 21:24
Der Simulator kann auch Bugs haben/unvollständig sein, nur so als Hinweis am Rande. Es ist nicht ungewöhnlich, dass Teile der Funktionalität (noch) nicht abgedeckt werden.

Du setzt CPOL, das ist falsch. Der 74HC595 liest das anliegende Bit laut Datenblatt bei steigender Taktflanke ein, CPOL=1 und CPHA=0 aktiviert aber gerade genau das gegenteilige Verhalten beim µC.
Außerdem ist f/16 unnötig, der 74HC595 kann (zumindest laut dem mir vorliegenden Datenblatt von Philips/NXP) bis zu 100MHz.

mfG
Markus

G3tzR@zor
16.02.2012, 20:45
Hallo,
danke für deinen Hinweis auf CPOL. Habe in irgend einem Forum gelesen, dass CPOL gesetzt sein muss und habs übernommen ohne ins Datenblatt des Mega 8 zu schauen.

Hab mir ein Testprogramm geschrieben in dem ich die Signale "Manuell" schalte und hatte dabei vorerst auch nicht den erwünschten Erfolg. Bis ich zufällig an den Leitungen auf dem Breadboard gewackelt habe. Also Leitungen nochmal neu gesteckt und siehe da es funktioniert. Auch mein SPI läuft nun mit diesem Prog.


//************************************************** ***************************
//* ATmega8 @ 8 MHz interner OC
//* LED Ansteuerung für Skorpion LED Bild mit Sternen
//* 34 Reihen a 5 Low Current LEDs Grün
//* 12 Reihen a 5 Ultrahelle LEDs 3mm(Rot Gelb) 5mm (Weiß Blau)
//* Anteuerung der LEDs über 74HC595 und UDN2981A
//************************************************** ************************

#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>

void my_delay(uint16_t milliseconds) {
for(; milliseconds>0; milliseconds--)
_delay_ms(1);
}

void SPI_MasterInit(void)
{
/* Set MOSI, SCK and SS output, all others input */
DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB2);
DDRB &= ~(1<<DDB4);
/* Enable SPI, Master */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(uint8_t cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
return SPDR;
}

int main(void)
{
SPI_MasterInit();

while(1)
{
SPI_MasterTransmit(0b11111111);
PORTB |=(1<<PB2);
PORTB &= ~(1<<PB2);
my_delay(2000);

SPI_MasterTransmit(0b10101010);
PORTB |=(1<<PB2);
PORTB &= ~(1<<PB2);
my_delay(2000);

SPI_MasterTransmit(0b01010101);
PORTB |=(1<<PB2);
PORTB &= ~(1<<PB2);
my_delay(2000);
}


return 0;
}



Ich habe versucht f/4 zu setzen, dann kommen aber nur wirre Daten am 74HC595 an. (Liegt wohl am Breadboard Versuchaufbau :-) )