OpenEdv-开源电子网

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

关于求算6路方波频率的问题,求助,谢谢先!

[复制链接]

7

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-8-18
在线时间
28 小时
发表于 2016-10-12 16:22:27 | 显示全部楼层 |阅读模式
1金钱
信号源是6路50hz市电信号,正定后变成50hz方波进的IO口,常规思路是每路IO方波来一个上升沿后中断独立触发一个定时器,直至下一个方波上升沿进来,得出周期时间求出频率。但是6路IO用6路定时器,资源不够了。就改成独立一个50us的定时器做中断,查算两个上升沿之间有多少个50us的中断,最后中断个数*50us就是周期时间。
写完程序后发现频率数值偶尔会有大幅度的跳变,然后用进中断和出中断做标记的办法,用示波器看中断程序的执行时间,发现偶尔会有暂停情况,感觉是某些优先级冲突?
程序里面一共使用了3组定时器,按照优先级别故意错开,不知是什么暂停了中断呢,求教思路和线索,谢谢!
定时器配置如下:
[mw_shl_code=c,true]void TIM2_Int_Init(u16 arr,u16 psc)  //2016929新增频率计算
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(  //使能或者失能指定的TIM中断
                TIM2, //TIM2
                TIM_IT_Update ,
                ENABLE  //使能
                );
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设
                                                         
}


//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(  //使能或者失能指定的TIM中断
                TIM3, //TIM3
                TIM_IT_Update ,
                ENABLE  //使能
                );
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
                                                         
}

//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM5_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(  //使能或者失能指定的TIM中断
                TIM5, //TIM5
                TIM_IT_Update ,
                ENABLE  //使能
                );
        NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM5中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM5, ENABLE);  //使能TIMx外设
                                                         
}[/mw_shl_code]


main中定义的时间如下:
                TIM2_Int_Init(49,71);      
                TIM3_Int_Init(199,71);   
                TIM5_Int_Init(3332,719);   


测量执行TIM2和TIM5的波形会有暂停,感觉被什么给打断了一下
QQ图片20161012162138.jpg QQ图片20161012162134.jpg

最佳答案

查看完整内容[请看2#楼]

50Hz,很慢的频率。 直接用外部中断搞定啊。。。。 50*6,最快也就300Hz的频率,完全没有压力。。。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-10-12 16:22:28 | 显示全部楼层
50Hz,很慢的频率。
直接用外部中断搞定啊。。。。
50*6,最快也就300Hz的频率,完全没有压力。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13100
金钱
13100
注册时间
2012-11-26
在线时间
3811 小时
发表于 2016-10-12 16:49:40 | 显示全部楼层
你这个用捕获就好了吧
回复

使用道具 举报

7

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-8-18
在线时间
28 小时
 楼主| 发表于 2016-10-12 16:54:28 | 显示全部楼层
jermy_z 发表于 2016-10-12 16:49
你这个用捕获就好了吧

捕获的话需要6个定时器,不够用了
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
757
金钱
757
注册时间
2015-10-27
在线时间
180 小时
发表于 2016-10-13 20:11:18 | 显示全部楼层
直接用6个普通的外部中断,进一次中断加1,然后使用一个定时器,每秒读一次数,然后清零
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
757
金钱
757
注册时间
2015-10-27
在线时间
180 小时
发表于 2016-10-13 20:12:30 | 显示全部楼层
g753388438 发表于 2016-10-13 20:11
直接用6个普通的外部中断,进一次中断加1,然后使用一个定时器,每秒读一次数,然后清零

我测试的是100以内最多1个误差
10kHz最多也就10hz
回复

使用道具 举报

7

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-8-18
在线时间
28 小时
 楼主| 发表于 2016-10-19 09:22:14 | 显示全部楼层
正点原子 发表于 2016-10-12 16:22
50Hz,很慢的频率。
直接用外部中断搞定啊。。。。
50*6,最快也就300Hz的频率,完全没有压力。。。。

请教原子哥,我不熟悉您指的“直接用外部中断”,麻烦您有空时候指教一下程序的关键字和思路,谢谢您!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-24 02:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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