完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
|
|
详细点
|
|
|
|
楼主在问题中的表达我的理解是楼主想对16.384KHz的时钟进行计数,这样可以用GPIO的外部中断,下降沿到来时触发外部中断,计数器加1. |
|
|
|
之前在群里有说过这个问题,提出的解决方案如下: 1、采用输入捕获脉冲数,对一段时间内进行统计,如果数量不够,说明这段时间出现故障 2、采用上升沿计时,下降沿停止统计时间的方式实时监测出故障 |
|
|
|
不用外部中断 就用Tim4 可以做到吗? |
|
|
|
不用外部中断,就用TIM4 可以做到吗?
|
|
|
|
|
|
|
|
|
|
|
|
用Tim4 输入捕获,当捕捉到上升沿就清零计数器, 当计数器值大于30.当计数器大于30.5us时(16.384KHz的半个周期时间)就认为有故障 ? |
|
|
|
如果是定时器输入捕获,有ST官方的例程可参考:
|
|
|
|
|
|
|
|
屠鸡勇士李运好 发表于 2019-5-14 18:23 怎么想的呀,高电平故障不是吗,那就是上升沿开始计数,下降沿复位计数,你可以设置超时中断,只要不超时(16.384Khz的半周期很容易算出来),所以只要超时了不就是有故障了吗,不过频繁中断会对cpu的消耗很大,所以要根据应用场景来看是否需要这么严格,从而设计一个比较宽裕的条件! 最靠谱和比较渐变的方法就是统计脉冲数呀,例如按照你16.384Khz,1s有多少个脉冲数是固定的呀,加入允许点误差,就前后加一点点,如果出现了故障,最后的脉冲数肯定不会是你定义的正常的脉冲数呀. |
|
|
|
testd018 发表于 2019-5-14 18:54 这样做: 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)),会频繁导致看门狗复位。 |
|
|
|
屠鸡勇士李运好 发表于 2019-5-14 19:07 中断太频繁了,对你的系统压力太大~ 你用脉冲数统计法吧,这样得话你只需要格一段时间去轮询脉冲数就行了,记住溢出的时候也要处理一下(复位一下继续统计) |
|
|
|
testd018 发表于 2019-5-14 19:27 1.为什么开启了定时器溢出中断,会导致看门狗频繁复位? 2 .脉冲统计法,没办法及时判断出吧,理论上说只要高电平持续的时间超过31us就认为是故障。 |
|
|
|
屠鸡勇士李运好 发表于 2019-5-14 19:36 1、因为中断太频繁了,导致你没有机会运行主循环的代码就又进中断了,31us的中断太急了 2、按理论说是这样的,这个要根据你需求了 |
|
|
|
外部中断和定时器同时用吧,外部边沿触发外部中断,外部中断所要做的就是上升沿触发中断时启动定时器,和改为下降沿触发外部中断,下降沿触发中断时,清除定时器并改为上升沿触发外部中断。
定时器定时32微秒,如果定时到了,那就是外部故障了, |
|
|
|
学习下 !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2093 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1931 浏览 3 评论
4526 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2076 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2587 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 12:57 , Processed in 1.230127 second(s), Total 77, Slave 70 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号