STM32F103学习笔记 (九) 输入捕获实验
2015-01-25 21:24
260 查看
这个实验是用 TIM5 的通道 1( PA0) 来做输入捕获, 捕获 PA0 上高电平的脉宽(用 WK_UP 按键输入高电平),通过串口打印高电平脉宽时间。
初始化里边先设置上升沿为输入捕捉,进入捕捉中断后,记录TIM5_CNT的值,然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM5_CNT 值。这样,前后两次 TIM5_CNT 之差,就是高电平的脉宽,
同时 TIM5 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。
相应的配置步骤为:
(1)开启TIM5时钟和GPIO时钟,设置PA0为下拉输入
(2)初始化
TIM5,设置 TIM5 的 ARR 和 PSC。(3)设置
TIM5 的输入比较参数,开启输入捕获。(4)使能捕获和更新中断(设置
TIM5 的 DIER 寄存器) (5)设置中断分组,编写中断服务函数 。
(6)使能定时器(设置
TIM5 的 CR1 寄存器)
timer.c中:
其中重要的是TIM5 的中断服务函数,TIM5CH1_CAPTURE_STA,是用来记录捕获状态:
设置 TIM5_CH1 捕获上升沿,这在TIM5_Cap_Init 函数执行的时候就设置好了,然后等待上升沿中断到来, 当捕获到上升沿中断,此时如果 TIM5CH1_CAPTURE_STA 的第 6 位为 0, 则表示还没有捕获到新的上升沿, 就先把TIM5CH1_CAPTURE_STA、 TIM5CH1_CAPTURE_VAL 和 TIM5->CNT 等清零,然后再设置TIM5CH1_CAPTURE_STA
的第 6 位为 1, 标记捕获到高电平, 最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出,就在 TIM5CH1_CAPTURE_STA里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置 TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器值到 TIM5CH1_CAPTURE_VAL 里面,最后设置为上升沿捕获,回到初始状态。
main.c:
如果用杜邦线把PB5和PA0连起来,就会看到串口助手里以固定的时间宽度输出。
初始化里边先设置上升沿为输入捕捉,进入捕捉中断后,记录TIM5_CNT的值,然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM5_CNT 值。这样,前后两次 TIM5_CNT 之差,就是高电平的脉宽,
同时 TIM5 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。
相应的配置步骤为:
(1)开启TIM5时钟和GPIO时钟,设置PA0为下拉输入
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能 TIM5 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟
(2)初始化
TIM5,设置 TIM5 的 ARR 和 PSC。(3)设置
TIM5 的输入比较参数,开启输入捕获。(4)使能捕获和更新中断(设置
TIM5 的 DIER 寄存器) (5)设置中断分组,编写中断服务函数 。
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//判断是否为更新中断 if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件 TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位
(6)使能定时器(设置
TIM5 的 CR1 寄存器)
TIM_Cmd(TIM5,ENABLE ); //使能定时器 5
timer.c中:
//定时器 5 通道 1 输入捕获配置 TIM_ICInitTypeDef TIM5_ICInitStructure; 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 时钟 215 //初始化 GPIOA.0 ① GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 设置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.0 GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉 //②初始化 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); //初始化 TIMx //③初始化 TIM5 输入捕获通道 1 TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 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); //初始化 TIM5 输入捕获通道 1 //⑤初始化 NVIC 中断优先级分组 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 TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//④允许更新中断捕获中断 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) { 216 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); //设置为上升沿捕获 }else //还未开始,第一次捕获上升沿 { TIM5CH1_CAPTURE_STA=0; //清空 TIM5CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM5,0); TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //设置为下降沿捕获 } } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 }
其中重要的是TIM5 的中断服务函数,TIM5CH1_CAPTURE_STA,是用来记录捕获状态:
设置 TIM5_CH1 捕获上升沿,这在TIM5_Cap_Init 函数执行的时候就设置好了,然后等待上升沿中断到来, 当捕获到上升沿中断,此时如果 TIM5CH1_CAPTURE_STA 的第 6 位为 0, 则表示还没有捕获到新的上升沿, 就先把TIM5CH1_CAPTURE_STA、 TIM5CH1_CAPTURE_VAL 和 TIM5->CNT 等清零,然后再设置TIM5CH1_CAPTURE_STA
的第 6 位为 1, 标记捕获到高电平, 最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出,就在 TIM5CH1_CAPTURE_STA里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置 TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器值到 TIM5CH1_CAPTURE_VAL 里面,最后设置为上升沿捕获,回到初始状态。
main.c:
<span style="font-size:14px;">extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态 extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值 int main(void) { u32 temp=0; delay_init(); //延时函数初始化 NVIC_Configuration(); //设置 NVIC 中断分组 2 uart_init(9600); //串口初始化波特率为 9600 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; 218 temp*=65536;//溢出时间总和 temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间 printf("HIGH:%d us\r\n",temp); //打印总的高点平时间 TIM5CH1_CAPTURE_STA=0; //开启下一次捕获 } } }</span>
如果用杜邦线把PB5和PA0连起来,就会看到串口助手里以固定的时间宽度输出。
相关文章推荐
- STM32学习笔记之定时器输入捕获实验
- STM32学习笔记之定时器输入捕获实验
- cortex_m3_stm32嵌入式学习笔记(十):输入捕捉实验(定时器的输入捕捉)
- STM32-按键输入实验学习笔记
- 1.28日学习内容——输入捕获实验,超声波测距
- 【ARM学习笔记】实验二:S3C2440A的GPIO输入实验
- cortex_m3_stm32嵌入式学习笔记(二十三):红外遥控实验(输入捕捉+解码)
- STM32学习笔记一一输入捕获
- STM32 通用定时器作为输入捕获 学习笔记
- cortex_m3_stm32嵌入式学习笔记(二):独立按键实验(IO输入)
- STM32学习笔记--按键输入实验
- C++ Primer学习笔记:标准输入/输出
- 交换学习笔记=++=实验二 交换机的通道技术
- 关于SQLServer2005的学习笔记——异常捕获及处理
- [转载]关于SQLServer2005的学习笔记——异常捕获及处理
- OSPF学习笔记3--单区域实验
- WPF and Silverlight 学习笔记(十四):键盘输入、鼠标输入、焦点处理
- 学习笔记 从零开始学单片机(1) 建立实验环境
- OpenCV学习笔记(9)利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面
- 关于SQLServer2005的学习笔记——异常捕获及处理