你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103VC 定时器和外部触发同步的问题

[复制链接]
cpev 提问时间:2018-1-16 17:32 /
我使用的单片机是STM32F103VC  外部芯片连接到单片机PB9(96脚 可复用为TIM4_CH4),正常情况下,外部芯片输出16.384KHz的时钟,有故障时输出高电平。用定时器如何做。但最好不要用1uS的定时器去检测PB9的电平高低。

自己的初步设想:
想用定时器和外部触发同步,在高电平时计数器计数,低电平是清零,当计数器大于30.5us时(16.384KHz的半个周期时间)触发中断。但一直没试成功。

有更好的方法,请赐教....

收藏 评论17 发布时间:2018-1-16 17:32

举报

17个回答
cpev 回答时间:2018-1-17 11:02:59
Inc_brza 发表于 2018-1-16 21:36
怎么想的呀,高电平故障不是吗,那就是上升沿开始计数,下降沿复位计数,你可以设置超时中断,只要不超时 ...

这样做:
Tim4_Init(void)
{                 GPIO_InitTypeDef GPIO_InitStructure;                TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;               
        TIM_ICInitTypeDef  TIM_ICInitStructure;       
        NVIC_InitTypeDef   NVIC_InitStructure;       

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);               
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOB,&GPIO_InitStructure);  //Max17830 Alarm
               RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);                       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
        TIM_TimeBaseStructure.TIM_Prescaler = 71;       
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;       
        TIM_TimeBaseStructure.TIM_Period = 49999;       
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;         //选择输入端 IC4映射到TI4上
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;  //上升沿下降沿都捕获
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI4上
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置输入分频,不分频
        TIM_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM4, &TIM_ICInitStructure);       
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;       
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);       
        TIM_ITConfig(TIM4,TIM_IT_CC4,ENABLE);//允许CC4IE捕获中断               
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//允许更新中断
        TIM_ClearITPendingBit(TIM4,TIM_IT_CC4);       
        TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
        TIM_Cmd(TIM4,ENABLE);
}
中断函数
void TIM4_IRQHandler(void)   
{  
   if(TIM_GetITStatus(TIM4,TIM_IT_CC4) != RESET)
   {
       TIM_SetCounter(TIM4,0);
       TIM_ClearITPendingBit(TIM4,TIM_IT_CC4);
   }

   if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)
   {      
      TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
   }
}


main函数里判断
if(TIM_GetCounter(TIM4) >= 32)  //   (1/16.384KHz)/2= 30.517578125us
{
           AlarmFlag = 1;  //  故障标志
}



上升沿和下降沿都清零计数器,只要计数器大于32即认为有故障。但开启了溢出中断的话(TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE)),会频繁导致看门狗复位。
Inc_brza 回答时间:2018-1-16 21:36:30
cpev 发表于 2018-1-16 19:40
用Tim4 输入捕获,当捕捉到上升沿就清零计数器, 当计数器值大于30.当计数器大于30.5us时(16.384KHz的半 ...

怎么想的呀,高电平故障不是吗,那就是上升沿开始计数,下降沿复位计数,你可以设置超时中断,只要不超时(16.384Khz的半周期很容易算出来),所以只要超时了不就是有故障了吗,不过频繁中断会对cpu的消耗很大,所以要根据应用场景来看是否需要这么严格,从而设计一个比较宽裕的条件!
最靠谱和比较渐变的方法就是统计脉冲数呀,例如按照你16.384Khz,1s有多少个脉冲数是固定的呀,加入允许点误差,就前后加一点点,如果出现了故障,最后的脉冲数肯定不会是你定义的正常的脉冲数呀.

评分

参与人数 1蝴蝶豆 +5 收起 理由
zero99 + 5

查看全部评分

Inc_brza 回答时间:2018-1-17 11:13:13
cpev 发表于 2018-1-17 11:02
这样做:
Tim4_Init(void)
{                 GPIO_InitTypeDef GPIO_InitStructure;                TIM_TimeBaseInitT ...

中断太频繁了,对你的系统压力太大~
你用脉冲数统计法吧,这样得话你只需要格一段时间去轮询脉冲数就行了,记住溢出的时候也要处理一下(复位一下继续统计)
feixiang20 回答时间:2018-1-16 17:42:20
来学习看看

评分

参与人数 1ST金币 -1 收起 理由
zero99 -1 警告

查看全部评分

wenyangzeng 回答时间:2018-1-16 17:54:53
本帖最后由 wenyangzeng 于 2018-1-16 17:58 编辑

其实楼主可以设置1个外部上下沿中断,下降沿中断计数值加1,上升沿中断如果超时下降沿中断未到来就读取当前计数值即可。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

cpev 回答时间:2018-1-16 18:48:54
wenyangzeng 发表于 2018-1-16 17:54
其实楼主可以设置1个外部上下沿中断,下降沿中断计数值加1,上升沿中断如果超时下降沿中断未到来就读取当前 ...

详细点
wenyangzeng 回答时间:2018-1-16 19:02:50

楼主在问题中的表达我的理解是楼主想对16.384KHz的时钟进行计数,这样可以用GPIO的外部中断,下降沿到来时触发外部中断,计数器加1.
Inc_brza 回答时间:2018-1-16 19:08:09
wenyangzeng 发表于 2018-1-16 19:02
楼主在问题中的表达我的理解是楼主想对16.384KHz的时钟进行计数,这样可以用GPIO的外部中断,下降沿到来 ...

之前在群里有说过这个问题,提出的解决方案如下:
1、采用输入捕获脉冲数,对一段时间内进行统计,如果数量不够,说明这段时间出现故障
2、采用上升沿计时,下降沿停止统计时间的方式实时监测出故障

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

cpev 回答时间:2018-1-16 19:12:31
wenyangzeng 发表于 2018-1-16 19:02
楼主在问题中的表达我的理解是楼主想对16.384KHz的时钟进行计数,这样可以用GPIO的外部中断,下降沿到来 ...

不用外部中断 就用Tim4 可以做到吗?
cpev 回答时间:2018-1-16 19:12:56
Inc_brza 发表于 2018-1-16 19:08
之前在群里有说过这个问题,提出的解决方案如下:
1、采用输入捕获脉冲数,对一段时间内进行统计,如果数 ...

不用外部中断,就用TIM4 可以做到吗?
Inc_brza 回答时间:2018-1-16 19:14:49
cpev 发表于 2018-1-16 19:12
不用外部中断,就用TIM4 可以做到吗?

输入捕获,不需要外部中断吧!
wenyangzeng 回答时间:2018-1-16 19:33:05
Inc_brza 发表于 2018-1-16 19:14
输入捕获,不需要外部中断吧!

我还是没弄明白你是要同步定时器还是要对外部脉冲进行计数?
cpev 回答时间:2018-1-16 19:40:04
Inc_brza 发表于 2018-1-16 19:14
输入捕获,不需要外部中断吧!

用Tim4 输入捕获,当捕捉到上升沿就清零计数器, 当计数器值大于30.当计数器大于30.5us时(16.384KHz的半个周期时间)就认为有故障 ?  
wenyangzeng 回答时间:2018-1-16 20:15:09
如果是定时器输入捕获,有ST官方的例程可参考:
InputCapture.rar (12.78 KB, 下载次数: 6)

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

Inc_brza 回答时间:2018-1-16 21:30:54
wenyangzeng 发表于 2018-1-16 19:33
我还是没弄明白你是要同步定时器还是要对外部脉冲进行计数?

都可以啊,上面不是说了吗
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版