跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YTM32B1H系列
  4. 关于Gpt时基无缘无故被清0的问题

关于Gpt时基无缘无故被清0的问题

已定时 已固定 已锁定 已移动 已解决 YTM32B1H系列
12 帖子 2 发布者 243 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • yxydoctorY 离线
    yxydoctorY 离线
    yxydoctor
    写于 最后由 yxydoctor 编辑
    #1

    Gpt包含两个通道:
    1 - 通道0:硬件IP为TMR-0;作为自由计数器使用;
    2 - 通道1:硬件IP为TMR-1;作为50ms周期定时器使用;

    初始化:
    // Gpt定时器配置,定时器时钟=50M)
    Gpt_Init(&Gpt_Config);
    Gpt_StartTimer(0, 0xffffffff); // 通道0:通用计数,不产生中断
    Gpt_StartTimer(1, 50*50000U); // 通道1:定时周期=50ms(定时器时钟=50M)
    Gpt_EnableNotification(1); // 使能定时器中断

    Gpt1中断回调:
    void Gpt_Tmr0Ch1Notification(void)
    {
    }

    Gpt0用于计数:
    uint32 precise_us_time(uint8 mode, uint32* stime)
    {
    uint32 temp=0;
    switch(mode){
    case 0: // 开始
    *stime = Gpt_GetTimeElapsed(0);
    break;
    case 1: // 停止
    temp = Gpt_GetTimeElapsed(0);
    if(temp >= *stime) temp = temp-*stime;
    else temp = 0xffffffff-(*stime-temp);
    temp = temp/50; // 1us(clk=50M)
    break;
    default:break;
    }
    return(temp);
    }

    其它Gpt操作代码:通道1重启50ms定时
    Gpt_StopTimer(1); // 停止计数
    // 。。。
    Gpt_StartTimer(1, 50*50000U); Gpt_EnableNotification(1);

    Gpt通道0计时:
    uint32_t debug_time[5];
    precise_us_time(0, &debug_time[0]);
    。。。。
    debug_time[1]=precise_us_time(1,&debug_time[0]);
    if(debug_time[1]>debug_time[2]) debug_time[2]=debug_time[1];

    怪异现象:
    Gpt0计时部分的代码理论时间不会超过10000us,但连续测试时,会偶发的出现一个极大数,跟踪发现:此现象均出现在结束点计数器值<起始点计数器值:如
    无标题.png

    这里的[1]为计算得到的代码时间开销,单位us。很明显出现85s是不对的。
    [3]: 起始点时基滴答值,单位1/50us
    [4]:结束点时基滴答值,单位1/50us

    IDE调试器肉眼观察看,[3]在未走到0xffffffff时,就自动从0重新计数了。

    这种现象属于偶发现象;测试1小时可能会出现一两次,绝大部分时间都正常。

    如果的确属于芯片问题或驱动问题,那就是及其严重的问题了。Gpt0还好毕竟只是内测使用;但如果Gpt1也存在这种问题,后果就非常严重了。

    1 条回复 最后回复
    0
    • zyqZ 离线
      zyqZ 离线
      zyq YunTu
      写于 最后由 编辑
      #2

      请问你的debug_time[3]与debug_time[4]是如何计算的?

      yxydoctorY 1 条回复 最后回复
      0
      • yxydoctorY 离线
        yxydoctorY 离线
        yxydoctor
        在 回复了 zyq 最后由 编辑
        #3

        zyq case 1: // 停止
        temp = Gpt_GetTimeElapsed(0);
        if(temp >= *stime) temp = temp-*stime;
        else temp = 0xffffffff-(*stime-temp);
        temp = temp/50; // 1us(clk=50M)

                    // 测试////////////////////////////
                    Gpt_StopTimer(1);                                                                   // 停止计数
                    Gpt_StartTimer(1, 50*50000U);  Gpt_EnableNotification(1); 
                
                
                if(temp>20000){
                    debug_time[3] = *stime;
                    debug_time[4] = Gpt_GetTimeElapsed(0);
                }
                /////////////////////////////////////
        
        zyqZ 1 条回复 最后回复
        0
        • zyqZ 离线
          zyqZ 离线
          zyq YunTu
          在 回复了 yxydoctor 最后由 zyq 编辑
          #4

          yxydoctor
          debug_time[3]走到多少时重新计数,你的代码是持续在查询着吗
          在你说的debug_time[3]异常时寄存器的CNT值有无异常?

          另外,你用的两个通道分别是TMR-0的0通道与TMR-0的1通道,还是TMR-0的0通道与TMR-1的0通道?

          yxydoctorY 1 条回复 最后回复
          0
          • yxydoctorY 离线
            yxydoctorY 离线
            yxydoctor
            在 回复了 zyq 最后由 yxydoctor 编辑
            #5

            zyq 是TMR0-1和TMR0-2这两个通道。
            其中TMR0-2为中断模式,有些时候会stop->start重启,这个应该是不影响时基的。

            现在把Gpt(0)映射到pTMR后,测试了一个小时,暂时是OK的。
            所以怀疑是TMR有问题。

            1 条回复 最后回复
            0
            • zyqZ 离线
              zyqZ 离线
              zyq YunTu
              写于 最后由 编辑
              #6

              建议看看出现问题时的寄存器状态,以便分析原因。

              yxydoctorY 1 条回复 最后回复
              0
              • yxydoctorY 离线
                yxydoctorY 离线
                yxydoctor
                在 回复了 zyq 最后由 编辑
                #7

                zyq 一俩小时才冒一个。很难捕捉。
                从切换到pTMR正常看,倒是建议官方排查一下。不然的话,另一路TMR也不敢用了。
                说真:调试到现在,出现了一些问题,但,智芯Z20平台下一概都没出现过,实话实说

                1 条回复 最后回复
                0
                • zyqZ 离线
                  zyqZ 离线
                  zyq YunTu
                  写于 最后由 编辑
                  #8

                  我这边按照你提供的代码片段运行,未出现你的现象。若要定位问题,需要提供更详细的信息。代码是否有其他部分会影响到Gpt计时,计时部分的代码是否可能存在异常 运行时间较长。

                  yxydoctorY 1 条回复 最后回复
                  0
                  • yxydoctorY 离线
                    yxydoctorY 离线
                    yxydoctor
                    在 回复了 zyq 最后由 编辑
                    #9

                    zyq 感谢回复. 梳理一下完整测试过程:
                    1 - gpt(0)为TMR0_1, 配置为自由计数器;
                    2 - gpt(1)为TMR0_2,配置为50ms中断定时器;
                    3 - 其它模块包括uart,can,fls,pwm,也包括几个os(threadx)线程;
                    4 - 测试环境: 以上位机作为软件模拟器, 模拟现场工况发送can,uart报文给32B1H;
                    5 - Gpt操作api见一楼, 为工程检索Gpt_关键词得到的所有代码;
                    6 - 以Gpt(0)对一段代码进行时间开销计算, 基本50ms会计算一次, 最大时间开销应<20ms
                    7 - 计时错误频率大致为一小时会捕捉到两三次;最初没留意; IDE观察到后尝试修改代码,无果;

                    目前的测试:
                    1 - gpt(0)改为pTMR0_1;
                    2 - gpt(1)改为pTMR0_2;
                    3 - 代码不做任何改动;
                    4 - 连续测试2个小时, 之前的问题不再出现.

                    结论: 怀疑是TMR有问题.

                    1 条回复 最后回复
                    0
                    • zyqZ 离线
                      zyqZ 离线
                      zyq YunTu
                      写于 最后由 Frankie 编辑
                      #10

                      由于TMR模块的4个通道共用一个中断向量,当进入TMR0-2的中断时,如果TMR0-1的中断标志被置起,可能会导致代码误判。建议尝试将TMR的中断服务函数修改为以下代码,观察问题是否得到改善。

                      GPT_FUNC void Gpt_Lld_Tmr_ChannelIrqProcess(uint8 Instance)
                      {
                          SchM_Enter_Gpt_GPT_EXCLUSIVE_AREA_19();
                      
                          /* Check which channel triggered the interrupt */
                          uint32 IntFlag;
                          uint32 Channel = TMR_CHANNEL_COUNT;
                          TMR_Type const volatile * Base = Tmr_Lld_Base[Instance];
                          for(uint32 ChannelId = 0; ChannelId < TMR_CHANNEL_COUNT; ++ChannelId)
                          {
                              IntFlag = TMR_REG_ADDR32_READ(TMR_BASE_ADDR32[Instance] + TMR_CH_INT_OFFSET32(ChannelId));
                              if ((1U == IntFlag) && (1U == (((Base->CH[ChannelId].CTRL) & TMR_CH_CTRL_CHIE_MASK) >> TMR_CH_CTRL_CHIE_SHIFT))) {
                                  Channel = ChannelId;
                                  break;
                              }
                          }
                      
                          if(Channel != TMR_CHANNEL_COUNT)
                          {
                              /* when one-shot mode, stop timer and transter channel state to expired */
                              if (TMR_CH_MODE_ONESHOT == Tmr_ChannelInfo[Instance][Channel].CountMode)
                              {
                                  /* stop timer */
                                  TMR_REG_ADDR32_CLEAR_BITS(TMR_BASE_ADDR32[Instance] + TMR_CH_CTRL_OFFSET32(Channel), TMR_CH_CTRL_CHEN_MASK);
                                  Tmr_ChannelInfo[Instance][Channel].State = TMR_CHANNEL_STATE_EXPIRED;
                              }
                              /* when continuous mode, update Stop time stamp and CMP register value */
                              else
                              {
                                  Gpt_Lld_Tmr_IrqCmpUpdate(Instance, Channel);
                              }
                              /* Clear flag */
                              TMR_REG_ADDR32_SET_BITS(TMR_BASE_ADDR32[Instance] + TMR_CH_INT_OFFSET32(Channel), TMR_CH_INT_CHIF_MASK);
                              SchM_Exit_Gpt_GPT_EXCLUSIVE_AREA_19();
                              /* Call Notifacation function */
                              if (TRUE == Tmr_ChannelInfo[Instance][Channel].IsNotificationEnabled)
                              {
                                  if (NULL_PTR != Tmr_ChannelInfo[Instance][Channel].NotificationPtr)
                                  {
                                      Tmr_ChannelInfo[Instance][Channel].NotificationPtr();
                                  }
                              }
                          }
                          else
                          {
                             SchM_Exit_Gpt_GPT_EXCLUSIVE_AREA_19();
                          }
                      }
                      

                      如果问题仍未解决,需要进一步排查。建议先排查TMR计数是否正常,确认是TMR计数受到了干扰,还是计算逻辑中存在未考虑到的情况。
                      也可以将工程文件发出来我测试看看。

                      yxydoctorY 1 条回复 最后回复
                      0
                      • yxydoctorY 离线
                        yxydoctorY 离线
                        yxydoctor
                        在 回复了 zyq 最后由 编辑
                        #11

                        zyq 确实是中断函数的问题:

                        现版TMR中断函数缺少对CTRL寄存器的判断,Gpt(1)触发的中断;在中断函数中会误判为Gpt(0)中断(虽然Gpt(0)并没有使能中断,但在CNT走到最大值时也会置位INT就寄存器)。

                        中断函数在误判Gpt(0)后,会更新CMP寄存器,而Gpt(0)调用Gpt_GetTimeElapsed(0)时,又会用到CMP值。

                        zyqZ 1 条回复 最后回复
                        0
                        • zyqZ 离线
                          zyqZ 离线
                          zyq YunTu
                          在 回复了 yxydoctor 最后由 编辑
                          #12

                          yxydoctor 好的,感谢反馈,下个版本修复这个问题。

                          1 条回复 最后回复
                          0
                          • EnweiE Enwei 将这个主题转为问答主题,在
                          • EnweiE Enwei 将这个主题标记为已解决,在

                        • 云途论坛规则/Yuntu Forum Rules

                          发帖前请查看

                        • YCT离线License申请流程

                          帮助没办法联网的电脑使用YCT

                        • YT CONFIG TOOL调查问卷

                          帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

                        • demo
                          12
                          can
                          9
                          lin stack
                          6
                          yt-link
                          5
                          vscode
                          3
                          adc模块
                          2
                          i2c
                          2
                          uuid
                          2
                          Online Users
                          • 登录

                          • 登录或注册以进行搜索。
                          • 第一个帖子
                            最后一个帖子
                          0
                          • 版块
                          • 最新
                          • 标签
                          • 热门