CxiaobaiLN 2023-07-24 10:04 采纳率: 0%
浏览 12

硬件IIC主机中断收发如何测试程序可稳定运行

手里有GD32开发板,逻辑分析仪,写了一个主机中断收发的程序,但是不知道用什么方法去测试写好的程序是否可以稳定运行

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-07-24 12:06
    关注
    • 你可以看下这个问题的回答https://ask.csdn.net/questions/7790962
    • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:GD32 笔记 08:如何使用串口中断接收不定长数据,并用串口中断以非阻塞的方式发送数据
    • 除此之外, 这篇博客: GD32F407之硬件IIC(从机模式)中的 将发送和接收数据整合在一起,整合一定要注意接收和发送的标志位不同, 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • oid Si2c_Transfer_Data(uint32_t i2c_periph,BYTE Channel)
      {
          /* wait until ADDSEND bit is set */
          if(i2c_flag_get(i2c_periph, I2C_ADDSEND)){
              ADDSEND_FLAG=1;
              /* clear ADDSEND bit */
              i2c_flag_clear(i2c_periph, I2C_ADDSEND);
          }
          if(ADDSEND_FLAG){
              if(i2c_flag_get(i2c_periph, I2C_RBNE) && (SRFalg ==0)){
                  /*  Receive register  addr*/
                  SReceAddrBuffer[Channel] = i2c_receive_data(i2c_periph);
                  SRFalg = 1;
              }
              if(SReceAddrBuffer[Channel] != 0XFF){
                  if(i2c_flag_get(i2c_periph, I2C_TBE)){
                      /* Send a word data */
                      MatchAdd_SendData(i2c_periph,SReceAddrBuffer[Channel]);
                      ADDSEND_FLAG=0;
                      SRFalg = 0;
                  }
      
                  if((SRFalg==1) && i2c_flag_get(i2c_periph, I2C_RBNE)){
                      /*Receive a byte data */
                      SReceDataBuffer[Channel] = i2c_receive_data(i2c_periph);
                      MatchAdd_ReceData(SReceAddrBuffer[Channel],SReceDataBuffer[Channel]);
                  }
      
                  if(i2c_flag_get(i2c_periph, I2C_STPDET)){
                      /* Receive mode clear the STPDET bit */
                      ic20Flag = 2;
                      SRFalg = 0;
                      ADDSEND_FLAG=0;
                      i2c_enable(i2c_periph);
                      i2c_interrupt_disable(i2c_periph, I2C_CTL1_ERRIE | I2C_CTL1_BUFIE | I2C_CTL1_EVIE);
                  }
                  if(ic20Flag == 2){
                      i2c_interrupt_enable(i2c_periph, I2C_CTL1_ERRIE | I2C_CTL1_BUFIE | I2C_CTL1_EVIE);
                      ic20Flag = 0;
                  }
              }
          }
      }

      注意:首先我们知道,,一般的IIC从设备都是有很多寄存器地址的,所以我们主机肯定也会发一个寄存器地址过来,官方源码里面是没有做处理的就当做(0x00),所以在整合的代码里面我有两次接收数据一个是寄存器地址放到地址数组和一个是数据放到了数据数组中。

      5、接收发送处理函数

      接收一个WORD数据

      void MatchAdd_ReceData(BYTE Cmd,BYTE Data)
      { 
          if (Cmd == 0x02)
          {   /* Currently system power state. */
              PwrState.byte = Data;
          } 
          else if (Cmd == 0xB3)
          {   /* button event state */
              ButtState.byte = Data;
          }
          else if (Cmd == 0xB4)
          {   /* button event number */
              SCINumber = Data;
          }
              
          else if (Cmd == 0xB5)
          {  
              HeartBeatEnable = Data;
          } 
          else if (Cmd == 0xB6)
          {  
              HeartBeatTimer = Data;
          }
          else if (Cmd == 0xB7)
          {  
              HeartBeatFlag = Data;
          }
      }

      发送一个WORD数据

      void MatchAdd_SendData(uint32_t i2c_periph ,BYTE Cmd)
      {
          WORD rval = 0;
          WORD *pntr;
          if (Cmd == 0x02)
          {   /* Currently system power state. */
              rval = (WORD) PwrState.byte;
          } 
          else if (Cmd == 0xB3)
          {   /* button event state */
              rval = (WORD) ButtState.byte;
          }
          else if (Cmd == 0xB4)
          {   /* button sci event number */
              rval = (WORD) SCINumber;
          }
      
          i2c_transmit_worddata(i2c_periph,rval);
      }

      注意:接受和发送的寄存器其实是同一个地址,通俗说就是从机有一个0x00--0xFF的地址的寄存器来让主机读写

      官方里面没有发送一个Word数据函数,修改如下

      void i2c_transmit_worddata(uint32_t i2c_periph, uint16_t Data)
      {
          /* send a data byte */
          I2C_DATA(i2c_periph) = Data;
          I2C_DATA(i2c_periph) = Data>>8;
      }

      6、中断函数

      void I2C0_EV_IRQHandler(void)
      {
          //DEBUG(0XAA);
          Si2c_Transfer_Data(I2C0,0);
      }

      到此GD32F407硬件IIC就结束了,其实硬件模式的从机还是比主机简单很多,主要是文档非常详细。

       

    • 以下回答由chatgpt基于相关博客总结生成:

      要测试硬件IIC主机中断收发程序的稳定性,可以通过以下步骤进行测试:

      1. 准备工作:

      2. 确保逻辑分析仪的触发器配置正确,能够正确触发IIC总线上的信号。

      3. 连接逻辑分析仪的信号探针到GD32开发板的IIC总线上。

      4. 修改代码:

      5. 确认代码中的发送和接收数据整合部分已经正确实现。

      6. 可以根据参考资料中的代码修改发送和接收数据的处理函数,根据需要将数据打印到终端或者通过其他方式验证正确性。

      7. 添加逻辑分析仪信号采集点:

      8. 在代码的关键位置添加逻辑分析仪的信号采集点,以便观察IIC总线上的信号。

      9. 运行测试:

      10. 使用主机程序发送数据到相应的从机设备,并观察逻辑分析仪上的信号波形。

      11. 可以通过逻辑分析仪软件提供的分析工具,如协议解析器和数据包解析器,来验证发送和接收的数据是否符合预期。

      12. 反复测试:

      13. 反复运行测试,观察是否存在丢包、错误数据等情况。

      14. 如果出现问题,可以根据逻辑分析仪提供的数据分析功能,找出问题所在,并对代码进行适当修改。

      下面是一个简单的代码示例,用于测试硬件IIC主机中断收发程序的稳定性:

      #include "gd32f4xx.h"
      
      void I2C0_EV_IRQHandler(void)
      {
          // TODO: 硬件IIC中断处理函数
      }
      
      void Si2c_Transfer_Data(uint32_t i2c_periph, BYTE Channel)
      {
          // TODO: 发送和接收数据整合的代码
      }
      
      void MatchAdd_ReceData(BYTE Cmd, BYTE Data)
      {
          // TODO: 接收数据处理函数
      }
      
      void MatchAdd_SendData(uint32_t i2c_periph, BYTE Cmd)
      {
          // TODO: 发送数据处理函数
      }
      
      void i2c_transmit_worddata(uint32_t i2c_periph, uint16_t Data)
      {
          // TODO: 发送一个WORD数据
      }
      
      int main(void)
      {
          // 初始化IIC总线和相关硬件
      
          // 启用IIC总线中断
          i2c_interrupt_enable(I2C0, I2C_CTL1_ERRIE | I2C_CTL1_BUFIE | I2C_CTL1_EVIE);
      
          while (1)
          {
              // TODO: 添加发送数据到从机的代码
      
              // 等待接收数据完成
      
              // TODO: 添加校验收到的数据的代码
          }
      }
      

      这是一个简单的示例代码,你可以根据实际情况进行修改和完善。其中的TODO部分需要根据参考资料中的代码进行相应的修改。注意在主函数中,你可以添加更多的测试代码来验证硬件IIC主机中断收发程序的稳定性。

      希望这个回答能对你有所帮助,如果还有问题请随时提问。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月24日

悬赏问题

  • ¥66 比特币地址如何生成taproot地址
  • ¥20 数学建模数学建模需要
  • ¥15 关于#lua#的问题,请各位专家解答!
  • ¥15 什么设备可以研究OFDM的60GHz毫米波信道模型
  • ¥15 不知道是该怎么引用多个函数片段
  • ¥30 关于用python写支付宝扫码付异步通知收不到的问题
  • ¥50 vue组件中无法正确接收并处理axios请求
  • ¥15 隐藏系统界面pdf的打印、下载按钮
  • ¥15 基于pso参数优化的LightGBM分类模型
  • ¥15 安装Paddleocr时报错无法解决