这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+同事tek示波器调试spi解析

共6条 1/1 1 跳转至

【换取手持数字示波器】+同事tek示波器调试spi解析

工程师
2024-03-20 19:59:57   被打赏 50 分(兑奖)     打赏

 这篇来说SPI的解析,下面先看我理解的理论。

SPI(Serial Peripheral Interface)是一种串行通信协议,通常用于微控制器和外设之间的数据交换。SPI通常包括四根线:片选(CS,Chip Select)、主设备输出从设备输入(MOSI,Master Out Slave In)、主设备输入从设备输出(MISO,Master In Slave Out)以及时钟(SCK,Serial Clock)。

SPI支持全双工通信,但通常配置为一主多从模式。

测试平台主要是用的STM32F4的开发板,所使用的示波器是泰克的。

下面看一下连线,因为测试SPI屏,所以线接的有一些乱。

image.png

上电后,抓到的波形如下:

image.png

主代码,为了看的清楚,我特意注释了一下:

// 调用函数获取SPI Flash设备的ID,并存储在IDNUMS变量中  
IDNUMS = W25QCheck();  
  
// 初始化CAN通信模块  
CANInit();  
  
// 初始化远程输入模块,设置频率为1MHz,周期为10ms  
REMOTEInit(167,10000);   
  
// 通过串口打印SPI Flash设备的ID  
printf("\r\nTHE ID OF W25Q IS: %X",IDNUMS);  
printf("\r\n");  
  
// 设置LCD上显示的颜色为红色  
POINT_COLOR = RED;  
  
// 在LCD上显示字符串"SPI TEST"  
LCD_ShowString(30,40,200,24,24,"SPI TEST ");  
  
// 在LCD上显示字符串"@lanning"  
LCD_ShowString(30,70,200,16,16,"@lanning ");  
  
// 在LCD上显示操作说明,包括按键KEY0用于写入数据,按键KEY1用于读取数据  
LCD_ShowString(30,100,300,16,16,"KEY0 : write  KEY1 : read");  
  
// 清空SPI Flash的指定页(这里清空的是第一页)  
W25QErasePage(0x000000);  
  
// 主循环  
while(1)  
{  
    // 延时10毫秒  
    delay_ms(10);  
      
    // 扫描按键状态  
    KEY = KEY_Scan(0);  
      
    // 再次检查SPI Flash设备ID,可能是为了监控设备是否在线  
    IDNUMS = W25QCheck();  
      
    // 如果按下KEY0键  
    if(KEY == KEY0_PRES)  
    {  
        // 向SPI Flash写入数据,从Databuf缓冲区开始,写入到地址0x000000,长度为len  
        W25QWrite(Databuf, 0x000000, len);  
          
        // 在LCD上显示"write finished!"字符串  
        LCD_ShowString(30,120,300,16,16,"write finished!\r\n");  
          
        // LED1状态翻转,可能用于指示正在写入数据  
        LED1 = ~LED1;  
          
        // 发送CAN消息  
        CANSendmessage(sendbuffer);  
          
        // 延时1毫秒  
        delay_ms(1);  
          
        // 接收CAN数据  
        MDCL = CANReceiveData(receivebuffer);  
          
        // 打印接收到的CAN数据  
        for(i = 0; i < MDCL; i++)  
        {  
            printf("the num %d is %x\r\n", i+1, receivebuffer[i]);  
            receivebuffer[i] = 0; // 清空缓冲区,为下一次接收做准备  
        }  
    }  
      
    // 如果按下KEY1键  
    if(KEY == KEY1_PRES)  
    {  
        // 从SPI Flash读取数据到receivebuf缓冲区,从地址0x000000开始,长度为len  
        W25QRead(receivebuf, 0x000000, len);  
          
        // 在LCD上显示读取到的数据  
        LCD_ShowString(30,120,300,16,16,receivebuf);  
          
        // 通过串口打印读取到的数据  
        printf(receivebuf);  
        printf("\r\n");  
          
        // LED1状态翻转,可能用于指示正在读取数据  
        LED1 = ~LED1;  
    }  
      
    // 扫描遥控器输入  
    key = REMOTEScan();  
      
    // 如果扫描到遥控器输入  
    if(key)  
    {  
        // 在LCD上显示"THE KEY VALUE:"和"THE KEY NUMS:"字符串  
        LCD_ShowString(30,140,200,16,16,"THE KEY VALUE:");  
        LCD_ShowString(30,160,200,16,16,"THE KEY NUMS:");  
          
        // 在LCD上显示按键值和按键次数  
        LCD_ShowNum(140,140,key,3,16);  
        LCD_ShowNum(140,16


框架:

image.png

调试时波形图:

image.png

总结:

说一下当时出现的问题点。

SPI容易产生的问题点主要可以总结为以下几个方面:

  1. 接线错误:这是最常见的问题之一。SPI通信涉及MOSI、MISO和SCK等多条线路,如果这些线路接错或交叉连接,会导致通信失败。主机的MOSI和从机的MOSI应该相连,而不是交叉相连,同样MISO也是如此。因为当时同事硬件的不是很厉害,一直调不出来,所以我当时给了一点帮助。

  2. 配置问题:主机和从机之间的时钟极性(CPOL)和采样方式(CPHA),以及数据发送顺序(高位先行或低位先行)必须设置一致。通信双方如果不是特别细心和理解可能会对数据产生差异,导致数据不一致。

  3. NSS(片选信号)控制不当:对于NSS硬件模式的从机,主机在发送时钟信号前必须确保从机的NSS引脚被拉低,通信结束后需要等待Busy信号后再拉高NSS。如果NSS控制不当,可能会导致从机接收的时钟脉冲数量不正确,进而影响到数据的接收。我给他的意见就是NSS就是个片选信号,要拉的就时候就要拉,不能犹豫。

  4. 初始化顺序问题:主机在SPI初始化时不应立刻使能SPI,而应在NSS拉低后再使能。否则,从机可能会少接收一个时钟脉冲,导致接收的数据出现错误,这个问题很着键,当初我自己写的时候也是一下不使能了,没有来个先后顺序。

  5. 软件配置问题:有时,主机可能不使用NSS引脚,而是选择使用任意的GPIO普通引脚来片选从机。在这种情况下,如果软件配置不当,没有正确设置NSS为软件模式,或者对NSS的处理不当,都可能导致通信问题。

  6. 硬件故障:SPI通信的硬件故障,线路断裂、接触不良或芯片损坏等,也可能导致通信问题,特别是屏的排线,还有杜邦线,上一秒用的还好好的,结果只是换了个位置就不通了。



工程师
2024-03-23 11:17:13     打赏
2楼

学习了。谢谢分享


专家
2024-03-26 00:32:19     打赏
3楼

谢谢分享


专家
2024-03-31 09:11:43     打赏
4楼

tek啊,你同事真有钱啊。


高工
2024-03-31 09:16:08     打赏
5楼

谢谢分享


高工
2024-03-31 09:19:11     打赏
6楼

谢谢分享


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]