embedded - 如何解决使用 SPI 从从机传输到主机的数据?
问题描述
我尝试使用 SPI 在两个 AVR (ATmega128) 之间进行通信。
从主机到从机的数据正确传输,但从机到主机的数据传输错误,第一个采样位总是错误的。
从机向主机发送(0X7E),但接收到的数据是(0X3F)。
错误在哪里?
MASTER代码
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define ACK 0x7E
void spi_init_master(void)
{
DDRB = (1<<0)|(1<<1)|(1<<2); //Set MOSI, SCK, SS as Output
PORTB |= 1;
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master, Prescaler: Fosc/16
}
//Function to send and receive data
unsigned char spi_tranceiver(unsigned char data)
{
PORTB &= ~(1<<0);
SPDR = data; //Load data into the buffer
while (!(SPSR & (1<<SPIF) )); //Wait until transmission complete
PORTB |= (1<<0);
return (SPDR); //Return received data
}
int main(void)
{
spi_init_master(); //Initialize SPI Master
unsigned char data;
unsigned char ret;
while (1)
{
ret = spi_tranceiver(data);
}
}
奴隶代码
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define ACK 0x7E
void spi_init_slave(void)
{
DDRB = (1<<3); //MISO as OUTPUT
SPCR = (1<<SPE); //Enable SPI
}
//Function to send and receive data
unsigned char spi_tranceiver(unsigned char data)
{
SPDR = data; //Load data into buffer
while (!(SPSR & (1<<SPIF) )); //Wait until transmission complete
return (SPDR); //Return received data
}
int main(void)
{
spi_init_slave(); //Initialize slave SPI
unsigned char data;
while (1)
{
data = spi_tranceiver(ACK);
}
}
解决方案
也许问题在于重新加载数据寄存器@SLAVE。在您的代码中,这是通过轮询完成的。因此,如果您的时钟速度很高,则从机没有足够的时间来正确地重新加载寄存器。
重要通知:
从机上 SPI 的时钟速度必须为 F_CPU/4(参见第 168 页的数据表)
尝试在主人身上延迟。所以奴隶有时间重新加载寄存器:
#define F_CPU ?????????UL // Clock speed of system in Hz
unsigned char spi_tranceiver(unsigned char data);
#include <util/delay.h>
int main(void)
{
// ...
while (1)
{
ret = spi_tranceiver(data);
}
}
unsigned char spi_tranceiver(unsigned char data)
{
_delay_ms(10);
PORTB &= ~(1<<SS);
SPDR = data;
while (!(SPSR & (1<<SPIF)));
PORTB |= (1<<SS);
return (SPDR);
}
尝试在 master 启动之前启动 slave!
推荐阅读
- reactjs - 无法从 ; 解析模块 反应原生
- html - CSS code fails to make changes to HTML code
- function - 函数参数powershell的范围
- android - 应用程序关闭时警报管理器不工作。我正在使用安卓 10
- angular - 角度 9 - 异步最佳实践?
- aspectj - Spring AOP 围绕 Abstract 类的 Abstract 方法调用一些方法
- python-3.x - 安装 Anaconda-navigator 1.9.7 版后 Turtle 图形停止工作
- javascript - 我无法理解 props 在 reactjs 中的工作原理
- django - 带参数的 Django 自定义模型方法,NON DRY
- ios - 为什么我的 viewController 背景颜色永远是白色的?