OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 21131|回复: 14

STM32中断计数的问题

[复制链接]

41

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
342
金钱
342
注册时间
2011-5-3
在线时间
25 小时
发表于 2011-6-1 21:14:29 | 显示全部楼层 |阅读模式

 最近做了一个引脚中断计数的问题,就是两个方波接在两个引脚上,计数一秒有多少脉冲,即是频率,外部测频

程序如下:

////定时器3中断服务程序 
void TIM3_IRQHandler(void)
{                 
 if(TIM3->SR&(1<<0))//溢出中断 UIF,位0:更新中断标志位置位
 {
  FLOW2 = COUNT1; 
  COUNT1 = 0; 
  FLOW1 = COUNT0; 
  COUNT0 = 0;
  flag = 1;
//  BUZZER=!BUZZER;//蜂鸣器鸣响                             
 }      
 TIM3->SR&=~(1<<0);//清除中断标志位
    
}
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void Timer3_Init(u16 arr,u16 psc)
{
 RCC->APB1ENR|=1<<1;//TIM3时钟使能  kb  
  TIM3->ARR=arr;  //设定计数器自动重装值//刚好0.1ms   
 TIM3->SC=psc;  //预分频器7200,得到10Khz的计数时钟    计数器时钟频率=fosc/(预分频+1)
 //这两个东东要同时设置才可以使用中断
 TIM3->DIER|=1<<0;   //允许更新中断    
 TIM3->DIER|=1<<6;   //允许触发中断
              
 TIM3->CR1|=0x01;    //使能定时器3
   MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2 
}

 

//TIM4 PWM部分
//正点原子@ALIENTEK
//2011/5/28 

//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void PWM_Init(u16 arr,u16 psc)
{        
 //此部分需手动修改IO口设置
 RCC->APB1ENR|=1<<2;       //TIM4时钟使能   
    
 GPIOB->CRH&=0XFFFFFFF0;//PB8输出
 GPIOB->CRH|=0X0000000B;//复用功能推挽输出 ,50MHZ  
 GPIOB->ODR|=1<<8;//端口复位后为下拉为0,此处PB8上拉 

 TIM4->ARR=arr;//设定计数器自动重装值
 TIM4->SC=psc;//预分频器不分频
 
 TIM4->CCMR2|=7<<4;  //CH3 PWM2模式  
 TIM4->CCMR2|=1<<3; //CH3预装载使能   

 TIM4->CCER |= 1<<8;   //OC3 输出使能,低电平有效
// TIM4->CCER &= ~(1<<8);   //OC3 输出使能,高电平有效    

 TIM4->CR1 |= 1<<7;   //ARPE使能
 TIM4->CR1 |= 1<<0;    //使能定时器4            

//外部中断初始化程序
//初始化PA3,PB0为中断输入.
void EXTIX_Init(void)
{
 RCC->APB2ENR|=1<<2;      //使能PORTA时钟
 GPIOA->CRL&=0XFFFF0FFF;  //PA3设置成输入  
 GPIOA->CRL|=0X00008000;
 GPIOA->ODR|=1<<3;      //PA3上拉

 RCC->APB2ENR|=1<<3;      //使能PORTB时钟
 GPIOB->CRL&=0XFFFFFFF0;  //PB0设置成输入  
 GPIOB->CRL|=0X00000008;     
 GPIOB->ODR|=1<<0;      //PB0上拉

// Ex_NVIC_Config(GPIO_A,0,FTIR); //下升沿触发
 Ex_NVIC_Config(GPIO_A,3,FTIR);//下降沿触发
 Ex_NVIC_Config(GPIO_B,0,FTIR);//下降沿触发

 MY_NVIC_Init(2,1,EXTI0_IRQChannel,2);    //抢占2,子优先级2,组2
 MY_NVIC_Init(2,2,EXTI3_IRQChannel,2);//抢占2,子优先级1,组2   
}


//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
 COUNT0++;
/// FA1 =!FA1;
 EXTI->R=1<<0;  //清除LINE0上的中断标志位 
}

//外部中断0服务程序
void EXTI3_IRQHandler(void)
{
 COUNT1++;
// FA2=!FA2;
 EXTI->R=1<<3;  //清除LINE3上的中断标志位 
}

  FLOW2 = COUNT1; 
  FLOW1 = COUNT0; 
FLOW1,FLOW2在主函中用printf打印在串口中显示,
现在的问题是,FLOW1,FLOW2两个频率不相同,FLOW2比FLOW1多一倍,前提两个引脚的脉冲是一样的,

各位大侠帮我看下啊,

常常被模仿,从未被超越
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-6-1 21:23:41 | 显示全部楼层
回复【楼主位】lion204:
---------------------------------
你分开测试一下,再看看count1和count0合得上不.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

41

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
342
金钱
342
注册时间
2011-5-3
在线时间
25 小时
 楼主| 发表于 2011-6-1 21:45:22 | 显示全部楼层
还是不行,COUNT1就是大于COUNT0  二倍啊,
常常被模仿,从未被超越
回复 支持 反对

使用道具 举报

6

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2011-11-18
在线时间
3 小时
发表于 2011-11-18 14:26:16 | 显示全部楼层
才写程序的吧,一看就知道你是菜鸟
回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-7-31 21:35:25 | 显示全部楼层
回复【4楼】figureyang:
---------------------------------
菜鸟+1
我也遇到这个问题了,请问该怎么改?
回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-7-31 21:36:01 | 显示全部楼层
回复【楼主位】lion204:
---------------------------------
我也遇到这个问题了,请问你改好了吗?
回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-7-31 21:42:52 | 显示全部楼层

 我也遇到类似问题了

用两个外部中断,一个定时器中断测两个波形的频率,总是有一个为真值的两倍。           

//定时器3中断服务程序 ///////////////////////////////////////////////
void TIM3_IRQHandler(void)
{                 
 if(TIM3->SR&0X0001)//溢出中断
 {
 
   get_frequency_CH1=frequency_CH1*10;  //*10与test.c中的100ms相对应
   frequency_CH1=0;
   get_frequency_CH2=frequency_CH2*10;
   frequency_CH2=0;                        
 }      
 TIM3->SR&=~(1<<0);//清除中断标志位
}


 

//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
 frequency_CH1 ++;  //PA0    B0
 EXTI->R=1<<0;  //清除LINE0上的中断标志位 
}

//外部中断13服务程序
void EXTI15_10_IRQHandler(void)
{   
 frequency_CH2 ++;  //PA13
 EXTI->R=1<<13;      //清除LINE13上的中断标志位
}
//外部中断初始化程序
//初始化PA0 PA13为中断输入.
void EXTIX_Init(void)
{
 RCC->APB2ENR|=1<<2;     //使能PORTA时钟

 JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD  

 GPIOA->CRL&=0XFFFFFF0F;//PB0设置成输入  
 GPIOA->CRL|=0X00000080;

 GPIOA->CRH&=0XFF0FFFFF;//PA13设置成输入  
 GPIOA->CRH|=0X00800000;       
 GPIOA->ODR|=1<<13;    //PA13上拉,PA0默认下拉

 Ex_NVIC_Config(GPIO_A,0,RTIR);//XIAJIANG沿触发
 Ex_NVIC_Config(GPIO_A,13,RTIR);//XIAJIANG沿触发

 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);    //抢占2,子优先级2,组2
 MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2   

}

我是哪里设置错了吗?谢谢!

回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-7-31 21:43:31 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我也遇到类似问题了
 

用两个外部中断,一个定时器中断测两个波形的频率,总是有一个为真值的两倍。            

//定时器3中断服务程序 /////////////////////////////////////////////// 
void TIM3_IRQHandler(void)
 {                  
 if(TIM3->SR&0X0001)//溢出中断
  {
   
   get_frequency_CH1=frequency_CH1*10;  //*10与test.c中的100ms相对应
    frequency_CH1=0; 
   get_frequency_CH2=frequency_CH2*10;
    frequency_CH2=0;                        
  }       
 TIM3->SR&=~(1<<0);//清除中断标志位
 }
 

 
 
//外部中断0服务程序
 void EXTI0_IRQHandler(void)
 {
  frequency_CH1 ++;  //PA0    B0
  EXTI->R=1<<0;  //清除LINE0上的中断标志位  
}
 
//外部中断13服务程序
 void EXTI15_10_IRQHandler(void)
 {   
  frequency_CH2 ++;  //PA13
  EXTI->R=1<<13;      //清除LINE13上的中断标志位 
}
 //外部中断初始化程序
 //初始化PA0 A13为中断输入.
 void EXTIX_Init(void)
 {
  RCC->APB2ENR|=1<<2;     //使能PORTA时钟
 
 JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD   

 GPIOA->CRL&=0XFFFFFF0F;//PB0设置成输入   
 GPIOA->CRL|=0X00000080; 

 GPIOA->CRH&=0XFF0FFFFF;//PA13设置成输入   
 GPIOA->CRH|=0X00800000;        
 GPIOA->ODR|=1<<13;    //PA13上拉,PA0默认下拉
 
 Ex_NVIC_Config(GPIO_A,0,RTIR);//XIAJIANG沿触发
  Ex_NVIC_Config(GPIO_A,13,RTIR);//XIAJIANG沿触发
 
 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);    //抢占2,子优先级2,组2
  MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2    

}
 


我是哪里设置错了吗?谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-1 10:41:02 | 显示全部楼层
回复【8楼】jasonWU:
---------------------------------
在中断服务函数里面,先判断中断标志位(SR)再执行加操作试试.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-8-1 13:41:41 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
这个问题刚刚解决了,我是这么弄的。
将外部中断服务函数中的两句话调换顺序为:先标志位清零变量再自增1

void EXTI0_IRQHandler(void)    //
{
EXTI->R=1<<0;  //清除LINE0上的中断标志位  
frequency_CH1 ++;  //
}
谢谢原子哥啦!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-1 21:49:34 | 显示全部楼层
回复【10楼】jasonWU:
---------------------------------
谢谢分享。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2013-7-24
在线时间
0 小时
发表于 2013-8-5 17:01:48 | 显示全部楼层
大家都是高手,学习 。
回复 支持 反对

使用道具 举报

41

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
342
金钱
342
注册时间
2011-5-3
在线时间
25 小时
 楼主| 发表于 2013-10-6 21:34:51 | 显示全部楼层
回复【10楼】jasonWU:
---------------------------------
为什么先清除再增加就没有问题?
常常被模仿,从未被超越
回复 支持 反对

使用道具 举报

0

主题

26

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-10-1
在线时间
0 小时
发表于 2013-11-20 15:32:39 | 显示全部楼层
回复【13楼】lion204:
---------------------------------
我也不太明白……
回复 支持 反对

使用道具 举报

3

主题

6

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2013-8-29
在线时间
0 小时
发表于 2014-9-4 03:14:06 | 显示全部楼层
回复【10楼】jasonWU:
---------------------------------
我的计数到9又变成0,是怎么回事
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-1 19:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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