查看: 4248|回复: 11

[求助] 如何通过KL26 TPM的output compare进行精确定时?

[复制链接]
  • TA的每日心情
    奋斗
    2016-11-29 19:14
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    20

    主题

    405

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1529
    最后登录
    1970-1-1
    发表于 2015-10-29 23:44:51 | 显示全部楼层 |阅读模式
    本帖最后由 blue_blue 于 2015-11-4 21:54 编辑

    void  tpm_delay (void)
    {
            
            TPM0_C0V = TPM0_CNT + 50000;
            while((TPM0_C0SC&TPM_CnSC_CHF_MASK) != TPM_CnSC_CHF_MASK) {};
            TPM0_C0SC = TPM0_C0SC&(uint32_t)0xff;
            
    }
    通过这个函数进行延时,每当第二次调用这个函数时,程序就死在里面了!这是怎么回事?有知道的大哥可以解释一下吗?谢谢!
    我知道答案 目前已有11人回答
    回复

    使用道具 举报

    该用户从未签到

    7

    主题

    107

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    444
    最后登录
    2019-3-7
    发表于 2015-10-30 08:48:53 | 显示全部楼层
    不是有PIT模块吗,为什么非要使用TPM模块
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    145

    主题

    4926

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    9267
    最后登录
    1970-1-1
    发表于 2015-10-30 09:54:08 | 显示全部楼层
    你等CHF置位之后,要先清除,然后可以可以把TPM的通道关掉。
    等你要继续定时的时候,再开启通道等待写入比较值等待。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-11-29 19:14
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    20

    主题

    405

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1529
    最后登录
    1970-1-1
     楼主| 发表于 2015-10-30 21:00:36 | 显示全部楼层
    FSL_TICS_ZJJ 发表于 2015-10-30 09:54
    你等CHF置位之后,要先清除,然后可以可以把TPM的通道关掉。
    等你要继续定时的时候,再开启通道等待写入比 ...

    按你说的操作了,但还是会出现这样的问题!调用延时函数几次后,就一直等待,死在while中了,这是什么问题了?把延时时间减少之后,这个函数调用多次之后就死在while里了。比方说,原先 TPM0_C0V = TPM0_CNT + 50000;这样调用一次之后就死在while里了,但我改成 TPM0_C0V = TPM0_CNT + 10000;这样,调用5次之后才死在while里,这与看门狗有关系吗?还是TPM模块的时钟设置有问题,我觉得这与看门狗是没有关系的,因为首先看门狗是关闭的,其次程序是死在while中了,芯片并没有复位,而是一直在while中执行死循环!你对这个问题有什么看法吗?谢谢
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-6 07:38
  • 签到天数: 736 天

    连续签到: 1 天

    [LV.9]以坛为家II

    21

    主题

    3486

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    5093
    最后登录
    2024-1-7
    发表于 2015-10-31 12:13:36 | 显示全部楼层
    帮顶一下
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-11-29 19:14
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    20

    主题

    405

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1529
    最后登录
    1970-1-1
     楼主| 发表于 2015-11-1 23:08:28 | 显示全部楼层
    FSL_TICS_ZJJ 发表于 2015-10-30 09:54
    你等CHF置位之后,要先清除,然后可以可以把TPM的通道关掉。
    等你要继续定时的时候,再开启通道等待写入比 ...

    谢谢你!之前的问题解决了!但是我又遇到了新的问题!延时的时间出现了问题!我暂时不知道问题的原因!改变TPM0_C0V =TPM0_CNT + 10;或 TPM0_C0V = TPM0_CNT + 1000;延时的时间依据很短暂,延时的长短基本上没多大改变!下面是TPM的初始化以及延时的代码!系统时钟模块是参照KL26的例程!
    void  tpmInit (void)
    {
            SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_TPMSRC(1);         
                                               /*          MCGFLLCLK/2  = 24M        */
            SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;
            TPM0_CNT = 0;                        //   24M/18750/128 = 10 hz
            TPM0_MOD = 0X493e;
            TPM0_C0SC = TPM_CnSC_MSA_MASK;
            TPM0_SC |= TPM_SC_PS(7);
            TPM0_SC |= TPM_SC_CMOD(1);                //Æô¶¯tpmʱÖÓ
           
    }

    void  tpm_delay (void)
    {
            TPM0_SC = TPM_SC_CMOD(0);
            TPM0_C0V = TPM0_CNT + 1000;
            TPM0_SC = TPM_SC_CMOD(1);
            while((TPM0_C0SC&TPM_CnSC_CHF_MASK) != TPM_CnSC_CHF_MASK)
            {
                                                                      printf("waiting\r\n");
            }
            TPM0_C0SC = TPM0_C0SC&(uint32_t)0xff;
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6020
    最后登录
    2020-9-28
    发表于 2015-11-2 09:23:43 | 显示全部楼层
    blue_blue 发表于 2015-11-1 23:08
    谢谢你!之前的问题解决了!但是我又遇到了新的问题!延时的时间出现了问题!我暂时不知道问题的原因!改 ...

    请问楼主将TPM0配置成哪种Output Compare模式了?为什么tpmInit初始化里只看到将TPM0_C0SC的MSA位置1,而没有ELSnB:ELSnA的选择呢。
    Mode.jpg

    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-11-29 19:14
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    20

    主题

    405

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1529
    最后登录
    1970-1-1
     楼主| 发表于 2015-11-2 20:15:53 | 显示全部楼层
    本帖最后由 blue_blue 于 2015-11-2 22:33 编辑
    FSL_TICS_Robin 发表于 2015-11-2 09:23
    请问楼主将TPM0配置成哪种Output Compare模式了?为什么tpmInit初始化里只看到将TPM0_C0SC的MSA位置1,而 ...

    谢谢你的帮助!我之前是这样想的,使用TPM延时,并没有必要在输出的TPM端口输出电平,那就使用Software compare呗!但是不能实现功能!然后我按你说的也改过了通过输出比较的方式,也加上了一些必要的设置,比如你说的ELSnB ELSnA位以及IO端口的功能选择!但是我发现TPM还是无法实现功能,无法延时!然后我在while中,while之前,以及清除标志位后,都将TPM0_C0SC打印出来,查看CHF位,接着就知道原因了!CHF位一直是被置位的(为1),那为什么,我无法擦除标志位了?然后我又换了一下TPM_STATUS_CH0F,在擦除前后对这一位进行查看,但是还是一样没有擦除!那问题出在哪儿了!难道是初始化错了!或者说擦除的方式错了!或是更新TPM0_C0V 的方式有问题!但是我清楚的记得,向标志位写1就可以清除标志位的!void  tpmInit (void)
    {

            SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_TPMSRC(1);         /*      MCGPLLCLK/2  = 24M        */
            SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;          //tpm0 clock  enable                           
            
            SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;   
            PORTE_PCR24 |= PORT_PCR_MUX(3);               /* TPM0_CH0*/
            
            TPM0_CNT = 0;                                                                                                                                                                                                                                                                                            //   24M/18750/128 = 10 hz
            TPM0_MOD = 0X493e;                                      //                18750
            TPM0_C0SC = TPM_CnSC_MSA_MASK|TPM_CnSC_ELSA_MASK;
            TPM0_SC |= TPM_SC_PS(7);                             //prescaler= 128
            TPM0_SC |= TPM_SC_CMOD(1);                      //start
            printf("%x 00000\r\n",TPM0_C0SC);

    }

    void  tpm_delay (void)
    {
            TPM0_SC = TPM_SC_CMOD(0);                     //stop tpm0,then refresh TPM0_C0V
            TPM0_C0V = TPM0_CNT + 1000;
            TPM0_SC = TPM_SC_PS(7)|TPM_SC_CMOD(1); //start
      printf("%x 111\r\n",TPM0_C0SC);
            while((TPM0_C0SC&((uint32_t)TPM_CnSC_CHF_MASK)) != (uint32_t)TPM_CnSC_CHF_MASK)
            {
                    printf("%x 222\r\n",TPM0_C0SC);
            }
            TPM0_C0SC = TPM0_C0SC&(uint32_t)0xff;
            printf("%x 333\r\n",TPM0_C0SC);
    }

    除此之外,不在tpm_delay 中更新TPM0_C0V 的值,而在tpmInit 中初始化,这样尝试之后,TPM0_C0SC 的CHF位是可以擦除的,但是延时的时间有出问题了,不管我在tpmInit 中初始化        TPM0_C0V = TPM0_CNT + 1000;或        TPM0_C0V = TPM0_CNT + 5000;延时的时间都比较短。while中打印的数字222的次数都是一样的!然后我尝试使用PIT Module进行延时,PIT模块能准确的延时!但是KL26得PIT资源是有限的,在PIT的资源用完的情况下!我觉得有必要使用TPM进行延时,我不知道到底我的设置除了什么问题!谢谢!


    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-11-29 19:14
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    20

    主题

    405

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1529
    最后登录
    1970-1-1
     楼主| 发表于 2015-11-3 23:04:24 | 显示全部楼层
    难道就没有一个人可以为我解答一下吗?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6020
    最后登录
    2020-9-28
    发表于 2015-11-4 10:14:56 | 显示全部楼层
    blue_blue 发表于 2015-11-2 20:15
    谢谢你的帮助!我之前是这样想的,使用TPM延时,并没有必要在输出的TPM端口输出电平,那就使用Software co ...

    请问你是想要用TPM的多个TPMx_CnV实现多组定时中断吗?
    另外 TPM0_C0V = TPM0_CNT + 1000;这种毫秒级的延时,尽量不要用串口打印字符串数量来判断。因为这会受到串口波特率快慢,字符串长短的影响。
    如果有示波器还是尽量直接测TPM输出引脚或反转IO口的电平时间。
    如果没示波器就将串口波特率尽量提高,字符串长度尽量减短,两次TPM0_C0V的差值尽量大。再来判断打印字符的数量。

    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-27 09:03 , Processed in 0.109541 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表