为什么要在此语法中使用 &? SPI寄存器的问题
Why should I use & in this syntax? Problem with SPI register
我正在编写 LPC2109/2 和 MCP4921 之间的 SPI 通信程序。这是一个任务
在学习上。我的导师问我一个问题,为什么这行必须有“&”?在这一行中,我们等待 SPI 传输结束。哪个答案应该是正确的?
#define SPI_SPIF_bm (1<<7)
...
while((S0SPSR & SPI_SPIF_bm) == 0){}
- 我们使用“&”作为逻辑 AND,例如:(0000 & 1000) 给我们 0000 而不是 (0000 | 1000) 给我们 1000。
- 我可以只使用这行代码吗:
while((S0SPSR) == 0){}
?在我看来-不。我们需要将寄存器 S0SPSR
中的值与位 SPIF SPI_SPIF_bm
. 进行比较
是否有不同的解决方案?
附件
LPC2129/01 用户手册:https://www.nxp.com/docs/en/user-guide/UM10114.pdf
LPC2109/2 的 SPI 外围设备根据实际发生的事件设置 S0SPSR
的不同位,这可能取决于外部环境。例如,如果 SPI 线上发生写冲突,它会设置 WCOL
位而不是 SPIF
.
如果您使用 while((S0SPSR) == 0){}
,它将一直等到事务成功或发生错误,因为如果设置了 S0SPSR
的任何位,它将退出循环。
while((S0SPSR & SPI_SPIF_bm) == 0){}
只检查交易是否成功完成。检查错误位也是一个好习惯,因为如果出现错误,您将永远陷入此循环,因为永远不会设置 SPIF
。
为了获得可靠的解决方案,我会采用这样的方法:
while(S0SPSR == 0) {}
if (S0SPSR & SPI_SPIF_bm) { /* SPI_SPIF_bm remains set until data register has not been accessed */
/* Success, read the data register, return data, etc. */
} else {
/* Handle error */
}
如果您对特定类型的错误感兴趣,您需要在每个循环中将 S0SPSR
存储在一个变量中,因为这些位在读取 S0SPSR
时被清除。如果在合理的时间内设置了 none 标志,您还应该向循环添加计数器或更复杂的超时解决方案以退出。
您可能认为这些错误永远不会发生,因为您的电路很简单,但它们确实会在现实生活中发生,因此值得进行适当的错误处理。
我正在编写 LPC2109/2 和 MCP4921 之间的 SPI 通信程序。这是一个任务 在学习上。我的导师问我一个问题,为什么这行必须有“&”?在这一行中,我们等待 SPI 传输结束。哪个答案应该是正确的?
#define SPI_SPIF_bm (1<<7)
...
while((S0SPSR & SPI_SPIF_bm) == 0){}
- 我们使用“&”作为逻辑 AND,例如:(0000 & 1000) 给我们 0000 而不是 (0000 | 1000) 给我们 1000。
- 我可以只使用这行代码吗:
while((S0SPSR) == 0){}
?在我看来-不。我们需要将寄存器S0SPSR
中的值与位 SPIFSPI_SPIF_bm
. 进行比较
是否有不同的解决方案?
附件
LPC2129/01 用户手册:https://www.nxp.com/docs/en/user-guide/UM10114.pdf
LPC2109/2 的 SPI 外围设备根据实际发生的事件设置 S0SPSR
的不同位,这可能取决于外部环境。例如,如果 SPI 线上发生写冲突,它会设置 WCOL
位而不是 SPIF
.
如果您使用 while((S0SPSR) == 0){}
,它将一直等到事务成功或发生错误,因为如果设置了 S0SPSR
的任何位,它将退出循环。
while((S0SPSR & SPI_SPIF_bm) == 0){}
只检查交易是否成功完成。检查错误位也是一个好习惯,因为如果出现错误,您将永远陷入此循环,因为永远不会设置 SPIF
。
为了获得可靠的解决方案,我会采用这样的方法:
while(S0SPSR == 0) {}
if (S0SPSR & SPI_SPIF_bm) { /* SPI_SPIF_bm remains set until data register has not been accessed */
/* Success, read the data register, return data, etc. */
} else {
/* Handle error */
}
如果您对特定类型的错误感兴趣,您需要在每个循环中将 S0SPSR
存储在一个变量中,因为这些位在读取 S0SPSR
时被清除。如果在合理的时间内设置了 none 标志,您还应该向循环添加计数器或更复杂的超时解决方案以退出。
您可能认为这些错误永远不会发生,因为您的电路很简单,但它们确实会在现实生活中发生,因此值得进行适当的错误处理。