最近在调试GD32F527驱动XPT2046时,由于他的特殊时序,我采用软件模拟来实现spi通信,接收通信代码如下:
uint16_t XPT2046_recv_byte(void)
{ uint8_t i;
uint16_t data = 0;
XPT2046_SCK_LOW();
delay_5us();
for(i=0; i<12; i++)
{
XPT2046_SCK_HIGH();
delay_5us();
XPT2046_SCK_LOW();
data <<= 1;
if(XPT2046_MISO_READ())
{
data |= 0x01;
}
delay_5us();
}
rt_kprintf("recv data:%u\n",data);
return data&0x0FFF;
}delay_5us的函数如下:
void delay_5us(void)
{
for(uint8_t i=0; i<10; i++);
}我在使用编译优化等级为-O0时,读取的通信正常,但是在使用-O3时发现读取出来的数全是0x00,经过查找原因,是因此优化后,延时的时间不对,引起通信异常。
【解决方法】
为了避免过度优化,我修改延时函数如下:
static void delay_5us(void)
{
// 使用volatile变量确保循环不被优化掉
volatile uint32_t count;
// 根据实际硬件校准循环次数
for(count = 0; count < 20; count++)
{
__NOP(); // 空操作,确保指令执行
}
}而后通信就正常了。
同时我也修改了一下接收函数:
/* 从XPT2046接收12位数据 */
uint16_t XPT2046_recv_byte(void)
{
uint8_t i;
uint16_t data = 0;
// 确保变量不被编译器优化
volatile uint8_t miso_state;
// 对硬件操作添加内存屏障,防止编译器重排序
__asm volatile("" : : : "memory");
XPT2046_SCK_LOW();
delay_5us(); // 确保延迟函数在高优化下仍能正常工作
for(i = 0; i < 12; i++)
{
XPT2046_SCK_HIGH();
delay_5us();
XPT2046_SCK_LOW();
// 读取MISO引脚状态,用volatile变量存储防止优化
miso_state = XPT2046_MISO_READ();
data <<= 1;
if(miso_state)
{
data |= 0x01;
}
delay_5us();
// 内存屏障,确保时序操作按顺序执行
__asm volatile("" : : : "memory");
}
rt_kprintf("recv data:%u\n", data);
return data & 0x0FFF;
}这样修改后,读取数据就正常了:

我要赚赏金
