【发布时间】:2019-05-02 05:54:52
【问题描述】:
所以我为 AVR 编写了一个 bitbang SPI 示例代码(这样我可以更好地理解使用 SPI 并欣赏 SPI 硬件),我对某些事情有点困惑。
根据我在 SPI 上阅读的内容,您首先将 LSB 从主机移出....但我不确定该怎么做?我的意思是本质上我想关闭 LSB 并将新的 8 位二进制值设置为之前但 LSB 弹出
(我在一个循环中执行此操作,获取一个无符号字符,然后希望在每个循环中发送 LSB)。
这是我目前所拥有的:
unsigned char transmit_byte(unsigned char data_byte)
{
int i;
char ret_data;
enable_SPI(); /* Set up correct Data Direction Ports */
_delay_ms(100);
ss_low(); /* Set SS Low */
_delay_ms(100);
/* SCLK Currently holding low, MOSI is low, SS is low */
for (i = 0; i <= 7; i++)
{
if (0x80 & SPI_PORT)
{
mosi_high();
}
else
{
mosi_low();
}
/* MOSI Value is latched in */
_delay_ms(10); // Probably unnecessary
//something here?
}
}
我可以直接将其移出吗?然后我将读取 MISO 行并检查 1 或 0 并设置一个新的字符变量,但这是在每次迭代之后。
【问题讨论】:
-
您的退货单在哪里?
-
如果这是主代码,为什么要读取端口?主机负责同时生成 MOSI 和时钟 - 它们必须在同一个端口上,以便您同时写入它们。当然取决于时钟相位 - SPI 允许在该相位后期发送数据,并且还允许不同的时钟极性。
-
您必须意识到的另一件事是 SPI 是全双工的。您在发送的同时接收 - 它实际上只是一个连接到一个 rx 数据寄存器和一个 tx 数据寄存器的美化移位寄存器。所以如果你想bit bang SPI,你必须在设置MOSI后不久(~100ns)读取MISO。
-
x >>= 1;是您“弹出 LSB 并将新的 8 位二进制值设置为之前但弹出 LSB”的方式。所有剩余的位都向右移动一个点,最左边的点变为 0。 -
首先,你有它倒退。 SPI 传统上是 MSB 优先,而异步 UART 传统上是 LSB 优先。