我正在尝试在8位ATMEL微控制器和闪存AT45DB081E之间建立SPI通信。第一步,我必须通过发送操作码 0x9F 并接收所需信息来读取闪存的制造商 ID 和设备 ID。问题是我只得到等于 0xFF 的响应,这表明使用 SPI 时有问题。现在,我深入研究我的代码和更多细节。
所需代码的 flash spi 接口支持所选的 MCU 中的频率!
闪存作为从机,支持spi 模式 0 和 3。所以我决定只使用其中一种模式 主控(MCU)。我不知道是否应该在从属端进行一些设置 用于选择 spi 模式!
从机选择引脚将从高到低有效,连接到 MCU 的 PORTB0
SCK 在 PORTB1 上,MOSI 在 PORTB2 上,MISO 在 PORTB3 上
这是我的代码:
#include <avr/io.h>
void spi_init(){
// Set MOSI, SCK, and SS as output
DDRB |= (1 << DDB2) | (1 << DDB0) | (1 << DDB1);
PORTB |= (1 << PB0);
// Enable SPI, set as Master, set clock rate to F_CPU/16 and set the interrupt
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
uint8_t spi_transfer(uint8_t data){
// Start transmission
SPDR = data;
// Wait for transmission complete
while (!(SPSR & (1 << SPIF))){
}
// Return received data
return SPDR;
}
uint8_t CEval_flash::ReadManfacturer(){
PORTB &= ~(1 << PB0); // Set SS low
for(int i=0;i<10;i++){}
spi_transfer(0x9F);
volatile uint8_t man_id =spi_transfer(0xFF); // 0xFF is sent as dummy to get response
volatile uint8_t device_id1 =spi_transfer(0xFF); // (Not returned / Just for Debug)
volatile uint8_t device_id2 =spi_transfer(0xFF); // (Not returned / Just for Debug)
volatile uint8_t ext_d_len =spi_transfer(0xFF); // (Not returned / Just for Debug)
volatile uint8_t ext_d =spi_transfer(0xFF); // (Not returned / Just for Debug)
// Release SS
PORTB |= (1 << PB0); // Set SS
return man_id;
}
int main(){
spi_init();
uint8_t cha1 = ReadManfacturer();
}
现在正如我所说,内部变量 man_id、device_id 等。我只得到 0xFF,但是根据内存数据表,它们应该是特定值!
经过多次尝试,终于发现问题出在闪存的复位引脚上。由于它是低电平有效闪存,因此我必须在操作过程中对其进行设置。然而我已经断开了它!