Me he estado tirando de los pelos por un tiempo con esto. Solo estoy tratando de hacer una transacción SPI básica, enviando un byte, en el ATtiny441 , pero no obtengo nada en las líneas SCK y MOSI. Primero, aquí están mis configuraciones de fusibles y pinout (en rojo): Probablemente la información más útil aquí es que estoy usando el oscilador interno de 8 MHz y no dividiendo por 8. Tenga en cuenta que estoy reasignando los pines SPI para que pueda deje mi analizador lógico encendido mientras programo con los pines predeterminados.
Aquí está mi main.c
archivo:
#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;
}
Estoy leyendo los registros SPSR
y SPDR
antes del while
bucle por recomendación de la nota de la aplicación AVR151 de Atmel (página 11).
Cuando ejecuto el código, la CSN
línea permanece baja, junto con SCK
y MOSI
, lo que sugiere que se está atascando en la while( !(SPSR & (1<<SPIF)) );
sección esperando que se SPIF
establezca. Cuando comento esta línea, la CSN
línea baja por ~ 25us y luego vuelve a subir, lo que se espera. Intenté configurar manualmente las salidas en alto SCK
y MOSI
, también, para asegurarme de que no se trata de un problema de conexión de clavijas y funcionaron bien.
Pregunta: ¿Alguien ve el error en mis caminos? Siento que hay un pequeño y estúpido error en alguna parte.
Editar: también quiero mencionar que lo probé con y sin el conjunto de bits de fusible del divisor de reloj (por 8), y con y sin reasignar los pines SPI desde la ubicación predeterminada (es decir, programar, quitar cables de programación, conectar cables de sonda lógica) .
¡Eureka! ¡Resulta que el SPIMAP
bit está mapeado incorrectamente!
/usr/local/CrossPack-AVR-20131216/avr/include/avr/iotn441.h:377:0: note: this is the
location of the previous definition
#define SPIMAP 0
^
(Debería ser el bit 1). Por lo tanto, ¡la línea que reasignaba los pines SPI estaba fallando! Esto se corrige colocando un #define SPIMAP 1
en la #define
sección.
EDITAR: Como señaló Martin, de hecho estoy usando una versión anterior de avr-libc. Estaba usando la última versión de CrossPack , que data de hace casi 4 años a partir de hoy. La versión más reciente tiene este error solucionado.
Martín
calcio3000
while
línea comentada.calcio3000