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

YunTu Forum

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

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

已定时 已固定 已锁定 已移动 已解决 YTM32B1H系列
12 帖子 2 发布者 240 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 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
                      • 版块
                      • 最新
                      • 标签
                      • 热门