PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 32bit Schieberegister Ansteuerung...Wo ist der Fehler?



KonZ
19.09.2007, 20:08
Mit einem Atmega32 will ich folgendes 32bit Schieberegister ansteuern...
http://www.allegromicro.com/en/Products/Part_Numbers/6833/6833.pdf

Ich benutze die SPI des Atmegas und habe folgende Pinbelegung:

Data In vom a6833 geht an MOSI, also PB5,
CLLock geht an SCK, also PB7,
STrobe geht an SS, also PB4,

OE geht dauerhaft an 5V.

Hier ist mein Code:


#include <avr/io.h>
#include <stdint.h>

#ifndef F_CPU
# define F_CPU 16000000L
#endif


#define SPIPORT PORTB
#define SPIDDR DDRB
#define CSPORT SPIPORT
#define CSDDR DDRB
#define MISO PB6
#define MOSI PB5
#define SCK PB7
#define CS PB4

#define SETSTROBE() (CSPORT) |= (1<<CS)
#define CLRSTROBE() (CSPORT) &= ~(1<<CS)

void spi_init(void)
{
SPIDDR = (1<<MOSI)|(1<<SCK);
CSDDR = (1<<CS);
SPIPORT = (1<<MISO);

/*
* SPI als Master
* MSB zuerst
* SCK Ruhepegel ist im Datenblatt LOW!
SPCR = (1 << SPE) | (1 << MSTR);

}

void spi_put_byte( uint8_t data)
{
SPDR = data;
while(!(SPCR & (1<<SPIF)))
;
}

void set_a6833(uint32_t data)
{
int8_t i;
uint8_t tmp;
for(i=3;i >= 0; i--){
tmp = (data >> (8*i));
spi_put_byte(tmp);
}
SETSTROBE();

asm volatile ("nop");
CLRSTROBE();
}

int main(void)
{
spi_init();
set_a6833(0x5500ff0fL);
for(;;)
;
return 0;
}


leider leuchten nich die angeschlossenen Led's die sollen, nur immer andere, ohne erkennbares Muster:(
Kann mal jemand rübergucken und mir evtl.nen Tip geben?

MFG

Kons

blofeld486
19.09.2007, 21:22
Hallo KonZ!

Die beiden ersten Anweisungen in der Funktion "spi_init(void)" schreiben in das gleiche Register. Damit machst du zuerst MOSI und SCK zu Ausgängen und anschliessend überschreibst du DDRB wieder, und in PORTB ist nur noch CS ein Ausgang...

Wieso schreibst du nicht einfach
"DDRB = (1<<SCK) | (1<<MOSI) | (1<<CS);" ?

Gruß, Claus

KonZ
19.09.2007, 21:48
hmmm, das ändert leider nichts:( bist du dir sicher, dass es so nicht funktioniert?

blofeld486
19.09.2007, 22:32
Hab noch nen Fehler gefunden!

Die Warteschleife bis zum Ende der SPI-Übertragung muß
"while( !(SPSR & (1<<SPIF) ) );" lauten, und nicht
"while( !(SPCR & (1<<SPIF) ) );" !!!!

KonZ
20.09.2007, 12:51
hmm, leider bringt das auch kein Erfolg:( hat noch wer Ideen?

BASTIUniversal
20.09.2007, 16:19
...warum kann niemand seine AVR-Probleme ins Richtige Forum posten? Warum?

Verschoben

MfG
Basti

blofeld486
21.09.2007, 08:27
Hab deinen Code im Debugger getestet, und so wie er jetzt hier steht läuft er meiner Meinung nach einwandfrei!
Wenn es immer noch nicht geht, dann versuch es doch mal mit einer niedrigeren Übertragungsrate am SPI, um eventuelle Störungen auf den Leitungen auszuschliessen und mach mal das Strobe-Signal länger.

Gruß, Claus



#include <avr/io.h>
#include <stdint.h>

#ifndef F_CPU
# define F_CPU 16000000L
#endif


#define SPIPORT PORTB
#define SPIDDR DDRB
#define CSPORT SPIPORT
#define CSDDR DDRB
#define MISO PB6
#define MOSI PB5
#define SCK PB7
#define CS PB4

#define SETSTROBE() (CSPORT) |= (1<<CS)
#define CLRSTROBE() (CSPORT) &= ~(1<<CS)

void spi_init(void)
{
SPIDDR = (1<<MOSI)|(1<<SCK)|(1<<CS);
SPIPORT = (1<<MISO);


// SPI als Master
// MSB zuerst
// SCK Ruhepegel ist im Datenblatt LOW!

SPCR = (1 << SPE) | (1 << MSTR);

}

void spi_put_byte( uint8_t data)
{
SPDR = data;
while(!(SPSR & (1<<SPIF)))
;
}

void set_a6833(uint32_t data)
{
int8_t i;
uint8_t tmp;
for(i=3;i >= 0; i--){
tmp = (data >> (8*i));
spi_put_byte(tmp);
}
SETSTROBE();

asm volatile ("nop");

CLRSTROBE();
}

int main(void)
{
spi_init();

set_a6833(0x5500ff0fL);

for(;;)
;
return 0;
}