Ich raube mir schon seit einiger Zeit die Haare darüber. Ich versuche nur, eine grundlegende SPI-Transaktion durchzuführen – ein Byte zu senden – auf dem ATtiny441 , aber ich bekomme nichts auf den SCK- und MOSI-Leitungen. Zuerst sind hier meine Sicherungseinstellungen und Pinbelegung (in Rot): Die wahrscheinlich nützlichste Information hier ist, dass ich den internen 8-MHz-Oszillator verwende und nicht durch 8 teile. Beachten Sie, dass ich die SPI-Pins neu zuordne, damit ich kann Lassen Sie meinen Logikanalysator eingeschaltet, während Sie mit den Standardpins programmieren.
Hier ist meine main.c
Datei:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define SCK 3
#define MOSI 1
#define CSN 2
uint8_t data = 0;
uint8_t reg = 0;
int main(void)
{
PRR = 0; // turn off power reduction
REMAP |= (1<<SPIMAP); // remap SPI pins
// set SCK, MOSI, CSN as outputs:
DDRA = (1<<SCK) | (1<<MOSI) | (1<<CSN);
// enable SPI, set as master, use f_clkIO/16 (500kHz):
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
reg = SPSR;
reg = SPDR;
while(1)
{
PORTA &= ~(1 << CSN); // clear CSN
SPDR = data++; // send byte
while( !(SPSR & (1<<SPIF)) ); // wait for flag to set
PORTA |= (1 << CSN); // set CSN
_delay_ms(10);
}
return 0;
}
Ich lese die SPSR
und SPDR
registriert vor der while
Schleife auf Empfehlung von Atmels AVR151 App Note (Seite 11).
Wenn ich den Code ausführe, bleibt die CSN
Zeile niedrig, zusammen mit SCK
und MOSI
, was darauf hindeutet, dass sie in dem while( !(SPSR & (1<<SPIF)) );
Abschnitt hängen bleibt, der darauf wartet, dass SPIF
gesetzt wird. Wenn ich diese Zeile auskommentiere, CSN
geht die Zeile für ~ 25 us auf Low und dann wieder auf High, was erwartet wird. Ich habe auch versucht, die Ausgänge manuell hoch zu setzen , um sicherzustellen, dass es sich nicht um ein Pin-Verbindungsproblem handelt, und sie haben gut funktioniert SCK
.MOSI
Frage: Sieht jemand den Fehler in meinen Wegen? Ich habe das Gefühl, dass irgendwo ein kleiner, dummer Fehler ist.
Bearbeiten: Ich möchte auch erwähnen, dass ich es mit und ohne gesetztem Taktteiler (durch 8) Sicherungsbit und mit und ohne Neuzuordnung der SPI-Pins von der Standardposition versucht habe (dh Programmieren, Programmierleitungen entfernen, Logiksondenleitungen anbringen) .
Eureka! Es stellt sich heraus, dass das SPIMAP
Bit falsch zugeordnet ist!
/usr/local/CrossPack-AVR-20131216/avr/include/avr/iotn441.h:377:0: note: this is the
location of the previous definition
#define SPIMAP 0
^
(Es sollte Bit 1 sein.) Daher schlug die Zeilenneuzuordnung der SPI-Pins fehl! Dies wird korrigiert, indem ein #define SPIMAP 1
in den #define
Abschnitt eingefügt wird.
BEARBEITEN: Wie Martin betonte, verwende ich tatsächlich eine alte Version von avr-libc. Ich habe die neueste Version von CrossPack verwendet , die heute fast 4 Jahre alt ist. Die neueste Version hat diesen Fehler behoben.
Martin
Kalzium3000
while
auskommentierten Zeile.Kalzium3000