野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15288|回复: 7

TIM定时器计数问题

[复制链接]
发表于 2019-7-17 23:45:11 | 显示全部楼层 |阅读模式
[td]

[/td]

请问一下为什么我的程序用两个外部中断触发时,一个中断触发计数一个关闭计数时,我的读取到的计数值是错误的,还有每次显示的值都是一样的,我已经清零了,我试过两个外部中断的触发是正常的,一个外部中断触发时开显示器,另一个触发时关闭显示器,用这个检测到外部中断触发是正常的,但是不知道为什么我的计数值就是不对,定时器的配置跟例程的定时配置是一样的,还有一个为什么有时候我用整形时赋值给0出来的结果显示值为1,给一显示值其实为2的,有时候又是正常的值,请求知道的大佬解答一下,谢谢了


代码
time=TIM_GetCounter(TIMX);   //获取计数器值
time+=(TIME_A_B)*60000;      //定时器3中断计数值一次最大计数为60000us,计算出总时间
time=time*0.000001;          //转换单位为  s               
testCNT3 =time;
sprintf(dispBuff3 ,"TIME= %f s",testCNT3);  //使用c标准库把变量转化成整形
display_string_5x8_1(7,1,dispBuff3 );        //dispBuff为转换后的整形




//#define   TIMX                                                      TIM3
//#define   TIM_RCC_APB1Periph_TIMX                     RCC_APB1Periph_TIM3   
//#define   TIM_RCC_APB1PeriphClockCmd                 RCC_APB1PeriphClockCmd
//#define   TIMX_IRQ                                              TIM3_IRQn
//#define   BASE_TIMX_IRQHandle                           TIM3_IRQHandler


static void BASIC_TIM_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    // 设置中断组为2
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               
                // 设置中断来源.
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQ ;        
                // 设置主优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0x02;         
          // 设置抢占优先级为3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;        
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}




static void BASIC_TIM_Config(uint16_t ARR,uint16_t PSC)
{
                TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
               
                // 开启定时器时钟,即内部时钟CK_INT=72M
    TIM_RCC_APB1PeriphClockCmd(TIM_RCC_APB1Periph_TIMX,ENABLE);
        
                // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = ARR;        
    TIM_TimeBaseStructure.TIM_Prescaler= PSC;// 时钟预分频数为
                // 时钟分频因子
    TIM_TimeBaseStructure.TIM_ClockDivision=0;
                // 计数器计数模式向上计数
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    //初始化定时器
    TIM_TimeBaseInit(TIMX, &TIM_TimeBaseStructure);
        
//                 // 清除计数器中断标志位
//     TIM_ClearFlag(TIMX, TIM_FLAG_Update);
        
                 // 开启计数器中断
     TIM_ITConfig(TIMX,TIM_IT_Update,ENABLE);
        
           BASIC_TIM_NVIC_Config();//调用NVIC设置
        
     TIM_Cmd(TIMX, DISABLE);        // 暂时关闭计数器
}

void BASIC_TIM_Init(void)
{
        BASIC_TIM_Config(59999,71);//最大为60000us
}



//TIM3的中断服务函数
void BASE_TIMX_IRQHandle(void )
{
  if (TIM_GetITStatus(TIMX,TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                 {
                         TIME_A_B++;  //记录发生了多少次中断
                         TIM_ClearITPendingBit(TIM3,TIM_IT_Update );  //清除TIMx的中断待处理位:TIM 中断源
                        }
}


//外部中断3服务程序
void KEY2_IRQHandler(void)
{
  TIM_SetCounter(TIMX,0); //定时器3计数器清零
        if(KEY2==0)         //按键KEY2     
         {        
                  time=0;  //时间清零
//                  TIM_SetCounter(TIM3,0); //定时器3计数器清零
                        TIME_A_B=0;                                           //溢出中断标志位清零
                        TIM_Cmd(TIM3, ENABLE); //使能TIM3                        
                        EXTIx_KEY2=1;               
                 
         }        

        EXTI_ClearITPendingBit(KEY2_EXTI_LINE);  //清除LINE3上的中断标志位  
}




void KEY1_IRQHandler(void)
{  

        if(KEY1==0)         //按键KEY1      
        {        
                TIM_Cmd(TIM3, DISABLE);  //失能TIMx外设
                EXTIx_KEY1=1;        
        }        

        EXTI_ClearITPendingBit(KEY1_EXTI_LINE);  //清除LINE4上的中断标志位  
}








回复

使用道具 举报

发表于 2019-7-17 23:58:51 | 显示全部楼层
兄啊,你这怎么看啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-18 07:59:45 | 显示全部楼层
请问一下为什么我的程序用两个外部中断触发时,一个中断触发计数一个关闭计数时,我的读取到的计数值是错误的,还有每次显示的值都是一样的,我已经清零了,我试过两个外部中断的触发是正常的,一个外部中断触发时开显示器,另一个触发时关闭显示器,用这个检测到外部中断触发是正常的,但是不知道为什么我的计数值就是不对,定时器的配置跟例程的定时配置是一样的,还有一个为什么有时候我用整形时赋值给0出来的结果显示值为1,给一显示值其实为2的,有时候又是正常的值,请求知道的大佬解答一下,谢谢了

代码
time=TIM_GetCounter(TIMX);   //获取计数器值
time+=(TIME_A_B)*60000;      //定时器3中断计数值一次最大计数为60000us,计算出总时间
time=time*0.000001;          //转换单位为  s               
testCNT3 =time;
sprintf(dispBuff3 ,"TIME= %f s",testCNT3);  //使用c标准库把变量转化成整形
display_string_5x8_1(7,1,dispBuff3 );        //dispBuff为转换后的整形




//#define   TIMX                                                      TIM3
//#define   TIM_RCC_APB1Periph_TIMX                     RCC_APB1Periph_TIM3   
//#define   TIM_RCC_APB1PeriphClockCmd                 RCC_APB1PeriphClockCmd
//#define   TIMX_IRQ                                              TIM3_IRQn
//#define   BASE_TIMX_IRQHandle                           TIM3_IRQHandler


static void BASIC_TIM_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    // 设置中断组为2
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               
                // 设置中断来源.
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQ ;        
                // 设置主优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0x02;         
          // 设置抢占优先级为3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;        
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}




static void BASIC_TIM_Config(uint16_t ARR,uint16_t PSC)
{
                TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
               
                // 开启定时器时钟,即内部时钟CK_INT=72M
    TIM_RCC_APB1PeriphClockCmd(TIM_RCC_APB1Periph_TIMX,ENABLE);
        
                // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = ARR;        
    TIM_TimeBaseStructure.TIM_Prescaler= PSC;// 时钟预分频数为
                // 时钟分频因子
    TIM_TimeBaseStructure.TIM_ClockDivision=0;
                // 计数器计数模式向上计数
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    //初始化定时器
    TIM_TimeBaseInit(TIMX, &TIM_TimeBaseStructure);
        
//                 // 清除计数器中断标志位
//     TIM_ClearFlag(TIMX, TIM_FLAG_Update);
        
                 // 开启计数器中断
     TIM_ITConfig(TIMX,TIM_IT_Update,ENABLE);
        
           BASIC_TIM_NVIC_Config();//调用NVIC设置
        
     TIM_Cmd(TIMX, DISABLE);        // 暂时关闭计数器
}

void BASIC_TIM_Init(void)
{
        BASIC_TIM_Config(59999,71);//最大为60000us
}



//TIM3的中断服务函数
void BASE_TIMX_IRQHandle(void )
{
  if (TIM_GetITStatus(TIMX,TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                 {
                         TIME_A_B++;  //记录发生了多少次中断
                         TIM_ClearITPendingBit(TIM3,TIM_IT_Update );  //清除TIMx的中断待处理位:TIM 中断源
                        }
}


//外部中断3服务程序
void KEY2_IRQHandler(void)
{
  TIM_SetCounter(TIMX,0); //定时器3计数器清零
        if(KEY2==0)         //按键KEY2     
         {        
                  time=0;  //时间清零
//                  TIM_SetCounter(TIM3,0); //定时器3计数器清零
                        TIME_A_B=0;                                           //溢出中断标志位清零
                        TIM_Cmd(TIM3, ENABLE); //使能TIM3                        
                        EXTIx_KEY2=1;               
                 
         }        

        EXTI_ClearITPendingBit(KEY2_EXTI_LINE);  //清除LINE3上的中断标志位  
}




void KEY1_IRQHandler(void)
{  

        if(KEY1==0)         //按键KEY1      
        {        
                TIM_Cmd(TIM3, DISABLE);  //失能TIMx外设
                EXTIx_KEY1=1;        
        }        

        EXTI_ClearITPendingBit(KEY1_EXTI_LINE);  //清除LINE4上的中断标志位  
}
回复 支持 反对

使用道具 举报

发表于 2019-7-18 09:47:56 | 显示全部楼层
LHM 发表于 2019-7-18 07:59
请问一下为什么我的程序用两个外部中断触发时,一个中断触发计数一个关闭计数时,我的读取到的计数值是错误 ...

>>>sprintf(dispBuff3 ,"TIME= %f s",testCNT3);  //使用c标准库把变量转化成整形

转化成整形为什么用%f  用%d
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-18 10:03:45 | 显示全部楼层
WishWish 发表于 2019-7-18 09:47
>>>sprintf(dispBuff3 ,"TIME= %f s",testCNT3);  //使用c标准库把变量转化成整形

转化成整形为什么用 ...

整形出问题的不是这个程序,
sprintf(dispBuff3 ,"TIME= %f s",testCNT3); 这个定义的就是这种类型,这个类型没有用错。
回复 支持 反对

使用道具 举报

发表于 2019-7-18 11:28:48 | 显示全部楼层
TIME_A_B这是什么类型的,看着怎么像宏定义?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-18 11:48:54 | 显示全部楼层
非谢家之宝树 发表于 2019-7-18 11:28
TIME_A_B这是什么类型的,看着怎么像宏定义?

不是宏定义  是这个uint32_t TIME_A_B=0;//中断次数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-20 13:24:11 | 显示全部楼层
搞定了,新建一个工程把那些文件都复制过去就可以了,但是不知道为什么会这样的
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 17:57 , Processed in 0.045223 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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