我正在尝试为我的 arduino uno 编写低级 SPI 写入/传输协议。但是我的逻辑分析仪上不断出现超调值 (ascii - 255)。
我真的很感激能帮助我理解我可能错在哪里。
我还注意到关闭(在 SPCR 中重置 SPE)会导致它在下一次迭代的写入/传输过程中随机冻结。
/* SPI Slave Demo
*
* SPI pin numbers:
* SCK 13 // Serial Clock.
* MISO 12 // Master In Slave Out.
* MOSI 11 // Master Out Slave In.
* SS 10 // Slave Select . Arduino SPI pins respond only if SS pulled low by the master
*
*/
#include<stdint.h>
// SPI port available at port B
#define SPI_SCK 5 // 13
#define SPI_MISO 4 // 12
#define SPI_MOSI 3 // 11
#define SPI_SS 2 // 10
// SPI control register bits
#define MSTR 4
#define SPE 6
// SPI status register bits
#define SPIF 7
#define ENABLE 0x1U
// Buffer to hold data
char dataBuff[500];
// initialize the pins to the modes that support their functionality
void pin_init(){
Serial.println("PIN init");
// output pins
// Set the Direction of the SCLk and MOSI pins as output
DDRB |= (ENABLE << SPI_SCK) | (ENABLE << SPI_MOSI);
if( (0x1 & (DDRB >> SPI_SCK) ) && ( 0x1 & (DDRB >> SPI_MOSI) )){
Serial.println("Output Pins set");
}
// Input pins
// Set the direction of the MISO and SS pins as Outputs
DDRB &= ~((ENABLE << SPI_MOSI) | (ENABLE << SPI_SS));
if( ~( (0x1 & (DDRB >> SPI_MOSI) ) && ( 0x1 & (DDRB >> SPI_SS) ) ) ){
Serial.println("Input Pins set");
}
// Enable Pull up for these pins
PORTB |= (ENABLE << SPI_MOSI) | (ENABLE << SPI_SS);
}
// Initialize the SPI port
uint8_t spi_init(){
Serial.println("SPI init");
// Set the SPI mode as master
SPCR |= (ENABLE << MSTR);
// Enable the SPI bit
SPCR |= (ENABLE << SPE);
if( ( 0x1 & (SPCR >> SPE) ) ){
Serial.println("SPI opened successfully");
}
// return the state of the master setting bit
return (0x1 & (SPCR >> MSTR));
}
// Write to the SPI data buffer
void writeData(uint8_t* data, uint16_t len){
Serial.println("In write!");
// Repeat until all bytes sent
while(len > 0){
// write to the DR register
Serial.print("Writing...\t Amount left: ");
SPDR = *data++;
// decrement length
len--;
Serial.println(len);
// Wait for the SPIF bit to be set to indicate
while(!(SPSR & (1<<SPIF)));
}
}
// read from the data register
// { #TODO }
// Close the SPI port
void spi_close(){
// Disable the SPI bit
SPCR &= ~(ENABLE << SPE);
if( ! ( 0x1 & (SPCR >> SPE) ) ){
Serial.println("SPI closed successfully");
}
}
void setup(){
// Clear global interrupts
// cli();
// Instantiate serial comm
Serial.begin(9600);
// Initilize the GPIO Pins
pin_init();
// initialize the SPI protocol
while( !spi_init() ){
Serial.println("Error in SPI initialization");
}
Serial.println("Setup Done!");
}
void loop(){
// char* data[10] = {"Hello", "from", "Alex"};
char* data = "Hello";
uint16_t dataLen = strlen(data);
// write
writeData((uint8_t*) data, dataLen);
}