寒假学习之stm32(9)----PWM进行输入捕获
来源:互联网 发布:魔法盾软件 编辑:程序博客网 时间:2024/05/17 06:42
应用
呃,说到应用,目前能想到的最主要的应用就是检测输入波的频率,其他的暂时没想,日后再更新吧~
工作过程
通过检测TIMx_CHx(某一个定时器的某一个通道)的边沿信号,在边沿信号发生跳定(上升或者下降)定时,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。
详细的工作过程:1. 设置输入捕获滤波器(去抖动,滤噪音,可以设定N个周期检测一次高电平)2. 设定输入捕获极性(上升沿捕获 or 下降沿捕获)3. 设置输入捕获映射通道(输入 or 输出)4. 设置输入捕获分频器(每n个事件捕获一次)5. 捕获到有效信号开启中断
配置过程:
1. 初始化时钟2. 初始化IO,注意,此时GPIO_Mode_IPD 或者 GPIO_Mode_IPU3. 初始化定时器, ARR,PSC。。 TIM_TimeBaseInit()4. 初始化输入捕获通道 TIM_ICInit()5. 开启捕获中断 TIM_ITConfig() NVIC_Init()6. 使能定时器 TIM_Cmd()7. 编写中断服务函数 TIMx_IRQHandler()
配置的过程和上一讲极其类似,代码就贴出来吧:
#include"stm32f10x.h"void TIM5_Cap_Init(u16 arr,u16 psc){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能TIM5时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前设置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉 //初始化定时器5 TIM5 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM5输入捕获参数 TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上 TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上 TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 TIM_ICInit(TIM5, &TIM5_ICInitStructure); //中断分组初始化 NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 TIM_Cmd(TIM5,ENABLE ); //使能定时器5}u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态 u16 TIM5CH1_CAPTURE_VAL; //输入捕获值//定时器5中断服务程序 void TIM5_IRQHandler(void){ if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) { if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 { if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 { TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 TIM5CH1_CAPTURE_VAL=0XFFFF; }else TIM5CH1_CAPTURE_STA++; } } if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 { if(TIM5CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 { TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获 }else //还未开始,第一次捕获上升沿 { TIM5CH1_CAPTURE_STA=0; //清空 TIM5CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM5,0); TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); /*CC1P=1 设置为下降沿捕获库函数只提供给了下面的函数输出比较极性函数:void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); 根据有效性判断这个函数的入口参数为:#define TIM_OCPolarity_High ((uint16_t)0x0000)#define TIM_OCPolarity_Low ((uint16_t)0x0002)第二个参数取值判断:#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ ((POLARITY) == TIM_OCPolarity_Low))查看了固件库V1.5版本,并没有输入捕获极性判断的函数,但是因为在两种模式下,都是配置同一个位,而且,#define TIM_ICPolarity_Rising ((uint16_t)0x0000)#define TIM_ICPolarity_Falling ((uint16_t)0x0002)也就是说: TIM_OCPolarity_High = TIM_ICPolarity_Rising TIM_OCPolarity_Low = TIM_ICPolarity_Falling 所以:TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); 和 TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_Low);都是对寄存器CCER配置: TIM5->CCER|=1<<1; */ } } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位}extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态 extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值 int main(void) { u32 temp=0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 TIM3_PWM_Init(899,0); //不分频。PWM频率=72000/(899+1)=80Khz TIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 while(1) { delay_ms(10); TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)+1); if(TIM_GetCapture2(TIM3)==300)TIM_SetCompare2(TIM3,0); if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿 { temp=TIM5CH1_CAPTURE_STA&0X3F; temp*=65536;//溢出时间总和 temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间 printf("HIGH:%d us\r\n",temp);//打印总的高点平时间 TIM5CH1_CAPTURE_STA=0;//开启下一次捕获 } } }
1 0
- 寒假学习之stm32(9)----PWM进行输入捕获
- 寒假学习之stm32(8)-----定时器输出PWM
- stm32 定时器pwm输入捕获
- stm32定时器输入捕获pwm
- stm32 PWM input捕获输入模式
- stm32的PWM输入捕获模式
- stm32定时器pwm模式输入捕获
- stm32 输入捕获学习(一)
- stm32 输入捕获学习(二)
- 寒假学习之STM32(1)----GPIO
- STM32 PWM捕获
- STM32 PWM捕获
- STM32 PWM 捕获4
- STM32学习笔记之定时器输入捕获实验
- STM32学习笔记之定时器输入捕获实验
- pwm输入捕获
- PWM输入捕获模式
- stm32库函数学习篇---通用定时器(输入捕获功能)
- 【ADB命令第三篇】手机密码(访问权限密码或者锁屏密码等)忘记怎么办?
- String,StringBuffer,StringBuilder
- UVa220 算法竞赛入门经典(第2版)习题4-3 黑白棋 Othello
- MySql优化
- 51 NOD 1094 和为k的连续区间(前缀和)
- 寒假学习之stm32(9)----PWM进行输入捕获
- Java SE 基础:泛型
- 分析服务器非法登陆日志之Linux下查询IP归属地
- C++指针——(3)指针与函数
- 51 NOD 1095 Anigram单词
- 蓝桥杯 圆的面积并控制输出格式
- UVa11636 Hello World!
- 第17章 控件模版(1)——模版的创建与使用
- I/O 多路复用之select、poll、epoll实现原理及对比总结