Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

超声波手势识别(STM32四路超声波获取)

东小东 2019-01-28 01:21:00 阅读数:483 评论数:0 点赞数:0 收藏数:0

   

       超声波手势识别在市场上已经有见实现,但研究其传感器发现并不是市场上随意可见的,如果暂且考虑成本,该如何入门实现简单的手势识别呢。聊天中老师给出一个很好的提议,就是固定四个超声波,分别为上下左右,然后进行程序上的对应编号,用单片机实现四路超声波的距离数据读取,然后程序分析读取的数据进而判断手势。STM32单片机有多个定时器,每个定时器接入一个超声波,分别接入四个,定时器分别开始工作以计数,将得到的距离信息一次性发送四个方向的值到串口,串口连接到PC机,PC机获取到四组值,然后进行分析解释。下面将实现第一步,STM32 实现四路超声波获取。

实现效果:

Python的串口程序上每次从串口获取到上下左右四组值,并输出在控制台,相关的串口实现可以参考:Python的串口通信(pyserial)

 

超声波模块:HC-SR04

单片机:stm32f103c8t6

注意:程序正常工作的前提是必须按复位键

获取值【上,下,左,右】

对应echo的IO【PA0   ,   PA11   ,   PA7   ,   PB6】

对应trig 的IO【PB12   ,   PB13   ,   PB14   ,   PB15】

对应定时器【定时器2通道1,定时器1通道4,定时器3通道2,定时器4通道1】

串口1:A9为TX    A10为RX

超声波使用基本介绍:

(1)采用IO口TRIG触发测距,给至少10us的高电平信号;

(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间/*声速(340M/S)) (未实现)

 

超声波时序:

 

主函数代码:

1 /#include "stm32f10x.h" //STM32头文件 2 /#include "sys.h" 3 /#include "delay.h" 4 /#include "usart.h" 5 /#include "timex.h" 6 /#include "trig.h" 7 8 extern u8 TIM3CH1CAPTURESTA; //输入捕获状态 9 extern u16 TIM3CH1CAPTUREVAL; //输入捕获值 10 extern u8 TIM3CH2CAPTURESTA; //输入捕获状态 11 extern u16 TIM3CH2CAPTUREVAL; //输入捕获值 12 extern u8 TIM2CH1CAPTURESTA; //输入捕获状态 13 extern u16 TIM2CH1CAPTUREVAL; //输入捕获值 14 extern u8 TIM4CH1CAPTURESTA; //输入捕获状态 15 extern u16 TIM4CH1CAPTUREVAL; //输入捕获值 16 extern u8 TIM1CH4CAPTURESTA; //输入捕获状态 17 extern u16 TIM1CH4CAPTUREVAL; //输入捕获值 18 int main (void){//主程序 19 u32 temp1=0;20 //u32 temp2=0; 21 u32 temp3=0;22 u32 temp4=0;23 u32 temp24=0;24 RCCConfiguration(); //时钟设置 25 TRInit(); //输出初始化 26 27 USART1Init(115200);28 29 TIM3CapInit(0XFFFF,72-1); //以1Mhz的频率计数//打印总的高点平时间 30 TIM2CapInit(0XFFFF,72-1); //以1Mhz的频率计数//打印总的高点平时间 31 TIM4CapInit(0XFFFF,72-1); //以1Mhz的频率计数//打印总的高点平时间 32 TIM1CapInit(0XFFFF,72-1); //以1Mhz的频率计数//打印总的高点平时间 33 delays(1);34 printf("////////// INIT ALL 11/////////rn");35 PBout(12)=1;36 delayus(13);37 PBout(12)=0;38 39 PBout(14)=1;40 delayus(13);41 PBout(14)=0;42 43 PBout(15)=1;44 delayus(13);45 PBout(15)=0;46 47 PBout(13)=1;48 delayus(13);49 PBout(13)=0;50 51 while(1){52 //定时器2通道1 53 if(TIM2CH1CAPTURESTA&0X80)//成功捕获到了一次上升沿 54 {55 temp1=TIM2CH1CAPTURESTA&0X3F;56 temp1/=65536;//溢出时间总和 57 temp1+=TIM2CH1CAPTUREVAL;//得到总的高电平时间 58 printf("time2-----:%d rn",temp1);//打印总的高点平时间 59 TIM2CH1CAPTURESTA=0;//开启下一次捕获 60 PBout(12)=1;61 delayus(13);62 PBout(12)=0;63 }64 65 //定时器1通道4 66 if(TIM1CH4CAPTURESTA&0X80)//成功捕获到了一次上升沿 67 {68 temp24=TIM1CH4CAPTURESTA&0X3F;69 temp24/*=65536;//溢出时间总和 70 temp24+=TIM1CH4CAPTUREVAL;//得到总的高电平时间 71 printf("time14-----:%d rn",temp24);//打印总的高点平时间 72 TIM1CH4CAPTURESTA=0;//开启下一次捕获 73 PBout(13)=1;74 delayus(13);75 PBout(13)=0;76 }77 //定时器3通道2 78 if(TIM3CH2CAPTURESTA&0X80)//成功捕获到了一次上升沿 79 {80 temp3=TIM3CH2CAPTURESTA&0X3F;81 temp3/=65536;//溢出时间总和 82 temp3+=TIM3CH2CAPTUREVAL;//得到总的高电平时间 83 printf("time32----:%d rn",temp3);//打印总的高点平时间 84 TIM3CH2CAPTURESTA=0;//开启下一次捕获 85 PBout(14)=1;86 delayus(13);87 PBout(14)=0;88 }89 //定时器4通道1 90 if(TIM4CH1CAPTURESTA&0X80)//成功捕获到了一次上升沿 91 {92 temp4=TIM4CH1CAPTURE_STA&0X3F;93 temp4/=65536;//溢出时间总和 94 temp4+=TIM4CH1CAPTUREVAL;//得到总的高电平时间 95 printf("time4-----:%d rn",temp4);//打印总的高点平时间 96 TIM4CH1CAPTURESTA=0;//开启下一次捕获 97 PBout(15)=1;98 delay_us(13);99 PBout(15)=0;100 }101 102 //发送最终结果------------------------------------ 103 if((temp1 >0)&&(temp24 >0)&&(temp3 >0)&&(temp4 >0)){104 105 printf("[%d,%d,%d,%d]",temp1,temp24,temp3,temp4);106 temp1=temp24=temp3=temp4=0;107 PBout(0)=1;108 }109 110 }111 }

定时器2通道1代码实现:

1 /#include"timex.h" 2 /#include "usart.h" 3 4 //定时器3通道1输入捕获配置 5 6 TIMICInitTypeDef TIM2ICInitStructure;7 8 voidTIM2CapInit(u16 arr,u16 psc)9 {10 11 12 GPIOInitTypeDef GPIOInitStructure;13 TIMTimeBaseInitTypeDef TIMTimeBaseStructure;14 NVICInitTypeDef NVICInitStructure;15 printf("---time 22222 1111 ---rn");16 RCCAPB1PeriphClockCmd(RCCAPB1PeriphTIM2, ENABLE); //使能TIM2时钟 17 RCCAPB2PeriphClockCmd(RCCAPB2PeriphGPIOA, ENABLE); //使能GPIOA时钟 18 19 GPIOInitStructure.GPIOPin = GPIOPin0; //PA0清除之前设置 20 GPIOInitStructure.GPIOMode = GPIOModeIPD; //PA0 输入 21 GPIOInit(GPIOA, &GPIOInitStructure);22 GPIOResetBits(GPIOA,GPIOPin0); //PA0下拉23 24 //初始化定时器5 TIM5 25 TIMTimeBaseStructure.TIMPeriod = arr; //设定计数器自动重装值 26 TIMTimeBaseStructure.TIMPrescaler =psc; //预分频器 27 TIMTimeBaseStructure.TIMClockDivision = TIMCKDDIV1; //设置时钟分割:TDTS = Tcktim 28 TIMTimeBaseStructure.TIMCounterMode = TIMCounterModeUp; //TIM向上计数模式 29 TIMTimeBaseInit(TIM2, &TIMTimeBaseStructure); //根据TIMTimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位30 31 //初始化TIM5输入捕获参数 32 TIM2ICInitStructure.TIMChannel = TIMChannel1; //CC1S=01 选择输入端 IC1映射到TI1上 33 TIM2ICInitStructure.TIMICPolarity = TIMICPolarityRising; //上升沿捕获 34 TIM2ICInitStructure.TIMICSelection = TIMICSelectionDirectTI; //映射到TI1上 35 TIM2ICInitStructure.TIMICPrescaler = TIMICPSCDIV1; //配置输入分频,不分频 36 TIM2ICInitStructure.TIMICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 37 TIMICInit(TIM2, &TIM2ICInitStructure);38 39 //中断分组初始化 40 NVICInitStructure.NVICIRQChannel = TIM2IRQn; //TIM3中断 41 NVICInitStructure.NVICIRQChannelPreemptionPriority = 2; //先占优先级2级 42 NVICInitStructure.NVICIRQChannelSubPriority = 0; //从优先级0级 43 NVICInitStructure.NVICIRQChannelCmd = ENABLE; //IRQ通道被使能 44 NVICInit(&NVICInitStructure); //根据NVICInitStruct中指定的参数初始化外设NVIC寄存器45 //printf("///////////////////////////////////*rn"); 46 TIMITConfig(TIM2,TIMITUpdate|TIMITCC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 47 48 TIMCmd(TIM2,ENABLE ); //使能定时器5 49 50 51 52 }53 54 u8 TIM2CH1CAPTURESTA=0; //输入捕获状态 55 u16 TIM2CH1CAPTUREVAL; //输入捕获值56 57 //定时器5中断服务程序 58 void TIM2IRQHandler(void)59 {60 //printf("////////////////////222222///////////////*rn"); 61 if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 62 {63 if (TIM_GetITStatus(TIM2, TIM_IT_Update) !=RESET)64 65 {66 if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 67 {68 if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 69 {70 TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 71 TIM2CH1_CAPTURE_VAL=0XFFFF;72 }else TIM2CH1_CAPTURE_STA++;73 }74 }75 if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 76 {77 if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 78 {79 TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 80 TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);81 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获 82 }else //还未开始,第一次捕获上升沿 83 {84 TIM2CH1_CAPTURE_STA=0; //清空 85 TIM2CH1_CAPTURE_VAL=0;86 TIM_SetCounter(TIM2,0);87 TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 88 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获 89 }90 }91 }92 93 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 94 95 }

 定时器1通道4实现:

1 /#include"timex.h" 2 /#include "usart.h" 3 4 5 6 TIMICInitTypeDef TIM1ICInitStructure;7 8 voidTIM1CapInit(u16 arr,u16 psc)9 {10 11 GPIOInitTypeDef GPIOInitStructure;12 TIMTimeBaseInitTypeDef TIMTimeBaseStructure;13 NVICInitTypeDef NVICInitStructure;14 printf("---time 11111 4444 ---rn");15 RCCAPB2PeriphClockCmd(RCCAPB2PeriphTIM1, ENABLE); //使能时钟 16 RCCAPB2PeriphClockCmd(RCCAPB2PeriphGPIOA, ENABLE); 17 18 GPIOInitStructure.GPIOPin = GPIOPin8|GPIOPin11; //清除之前设置 19 GPIOInitStructure.GPIOMode = GPIOModeIPD; //输入 20 GPIOInit(GPIOA, &GPIOInitStructure);21 GPIOResetBits(GPIOA,GPIOPin8|GPIOPin11); //下拉22 23 //初始化定时器1 24 TIMTimeBaseStructure.TIMPeriod = arr; //设定计数器自动重装值 25 TIMTimeBaseStructure.TIMPrescaler =psc; //预分频器 26 TIMTimeBaseStructure.TIMClockDivision = TIMCKDDIV1; //设置时钟分割:TDTS = Tcktim 27 TIMTimeBaseStructure.TIMCounterMode = TIMCounterModeUp; //TIM向上计数模式 28 TIMTimeBaseInit(TIM1, &TIMTimeBaseStructure); //根据TIMTimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位29 30 //初始化TIM1 31 TIM1ICInitStructure.TIMChannel = TIMChannel4; //CC1S=01 选择输入端 IC1映射到TI1上 32 TIM1ICInitStructure.TIMICPolarity = TIMICPolarityRising; //上升沿捕获 33 TIM1ICInitStructure.TIMICSelection = TIMICSelectionDirectTI; //映射到TI1上 34 TIM1ICInitStructure.TIMICPrescaler = TIMICPSCDIV1; //配置输入分频,不分频 35 TIM1ICInitStructure.TIMICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 36 TIMICInit(TIM1, &TIM1ICInitStructure);37 38 //中断分组初始化39 //Device header 40 NVICInitStructure.NVICIRQChannel = TIM1CCIRQn; //中断 41 NVICInitStructure.NVICIRQChannelPreemptionPriority = 2; //先占优先级2级 42 NVICInitStructure.NVICIRQChannelSubPriority = 0; //从优先级0级 43 NVICInitStructure.NVICIRQChannelCmd = ENABLE; //IRQ通道被使能 44 NVICInit(&NVICInitStructure); //根据NVICInitStruct中指定的参数初始化外设NVIC寄存器 45 46 TIMITConfig(TIM1,TIMITCC4|TIMITUpdate,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 47 48 TIMCmd(TIM1,ENABLE ); //使能定时器1 49 50 }51 52 53 u8 TIM1CH4CAPTURESTA=0; //输入捕获状态 54 int TIM1CH4CAPTUREVAL0,TIM1CH4CAPTUREVAL; //输入捕获值55 //定时器5中断服务程序 56 void TIM1UPIRQHandler(void)57 {58 59 if((TIM1CH4CAPTURESTA&0X80)==0)//还未成功捕获 60 {61 if (TIMGetITStatus(TIM1, TIMITUpdate) !=RESET)62 63 {64 if(TIM1CH4CAPTURESTA&0X40)//已经捕获到高电平了 65 {66 if((TIM1CH4CAPTURESTA&0X3F)==0X3F)//高电平太长了 67 {68 TIM1CH4CAPTURESTA|=0X80;//标记成功捕获了一次 69 TIM1CH4CAPTUREVAL=0XFFFF;70 }else TIM1CH4CAPTURESTA++;71 }72 }73 }74 75 TIMClearITPendingBit(TIM1, TIMITUpdate); //清除中断标志位 76 77 78 79 }80 void TIM1CCIRQHandler(void)81 {82 if((TIM1CH4CAPTURESTA&0X80)==0)//还未成功捕获 83 {84 if (TIMGetITStatus(TIM1, TIMITCC4) != RESET)//捕获1发生捕获事件 85 {86 if(TIM1CH4CAPTURESTA&0X40) //捕获到一个下降沿 87 {88 TIM1CH4CAPTURESTA|=0X80; //标记成功捕获到一次上升沿 89 TIM1CH4CAPTUREVAL=TIMGetCapture4(TIM1)-TIM1CH4CAPTUREVAL0;90 TIMOC4PolarityConfig(TIM1,TIMICPolarityRising); //CC1P=0 设置为上升沿捕获 91 }else //还未开始,第一次捕获上升沿 92 {93 TIM1CH4CAPTURESTA=0; //清空 94 TIM1CH4CAPTUREVAL0=TIMGetCapture4(TIM1);//!!!!!!!!!!!!!!!!!!!!!!!95 //TIMSetCounter(TIM1,0); 96 TIM1CH4CAPTURESTA|=0X40; //标记捕获到了上升沿 97 TIMOC4PolarityConfig(TIM1,TIMICPolarityFalling); //CC1P=1 设置为下降沿捕获 98 }99 }100 }101 102 TIMClearITPendingBit(TIM1, TIMITCC1); //清除中断标志位 103 104 }

定时器3通道2代码实现:

1 /#include"timex.h" 2 /#include "usart.h" 3 4 //定时器3通道1输入捕获配置 5 6 TIMICInitTypeDef TIM3ICInitStructure;7 TIMICInitTypeDef TIM3ICInitStructure1;8 voidTIM3CapInit(u16 arr,u16 psc)9 {10 11 GPIOInitTypeDef GPIOInitStructure;12 TIMTimeBaseInitTypeDef TIMTimeBaseStructure;13 NVICInitTypeDef NVICInitStructure;14 15 printf("---time 33333 2222 ---rn");16 RCCAPB1PeriphClockCmd(RCCAPB1PeriphTIM3, ENABLE); //使能时钟 17 RCCAPB2PeriphClockCmd(RCCAPB2PeriphGPIOA, ENABLE); 18 19 GPIOInitStructure.GPIOPin = GPIOPin6|GPIOPin7; //清除之前设置 20 GPIOInitStructure.GPIOMode = GPIOModeIPD; //输入 21 GPIOInit(GPIOA, &GPIOInitStructure);22 GPIOResetBits(GPIOA,GPIOPin6 | GPIOPin7); //下拉23 24 //初始化定时器5 TIM5 25 TIMTimeBaseStructure.TIMPeriod = arr; //设定计数器自动重装值 26 TIMTimeBaseStructure.TIMPrescaler =psc; //预分频器 27 TIMTimeBaseStructure.TIMClockDivision = TIMCKDDIV1; //设置时钟分割:TDTS = Tcktim 28 TIMTimeBaseStructure.TIMCounterMode = TIMCounterModeUp; //TIM向上计数模式 29 TIMTimeBaseInit(TIM3, &TIMTimeBaseStructure); //根据TIMTimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位30 31 //初始化TIM5输入捕获参数 32 TIM3ICInitStructure.TIMChannel = TIMChannel1; //CC1S=01 选择输入端 IC1映射到TI1上 33 TIM3ICInitStructure.TIMICPolarity = TIMICPolarityRising; //上升沿捕获 34 TIM3ICInitStructure.TIMICSelection = TIMICSelectionDirectTI; //映射到TI1上 35 TIM3ICInitStructure.TIMICPrescaler = TIMICPSCDIV1; //配置输入分频,不分频 36 TIM3ICInitStructure.TIMICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 37 TIMICInit(TIM3, &TIM3ICInitStructure);38 39 //初始化TIM5输入捕获参数 40 TIM3ICInitStructure1.TIMChannel = TIMChannel2; //CC1S=01 选择输入端 IC1映射到TI1上 41 TIM3ICInitStructure1.TIMICPolarity = TIMICPolarityRising; //上升沿捕获 42 TIM3ICInitStructure1.TIMICSelection = TIMICSelectionDirectTI; //映射到TI2上!!!!!!!!!!!!!! !!!!! 43 TIM3ICInitStructure1.TIMICPrescaler = TIMICPSCDIV1; //配置输入分频,不分频 44 TIM3ICInitStructure1.TIMICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 45 TIMICInit(TIM3, &TIM3ICInitStructure1);46 47 48 49 50 //中断分组初始化 51 NVICInitStructure.NVICIRQChannel = TIM3IRQn; //TIM3中断 52 NVICInitStructure.NVICIRQChannelPreemptionPriority = 1; //先占优先级2级 53 NVICInitStructure.NVICIRQChannelSubPriority = 0; //从优先级0级 54 NVICInitStructure.NVICIRQChannelCmd = ENABLE; //IRQ通道被使能 55 NVICInit(&NVICInitStructure); //根据NVICInitStruct中指定的参数初始化外设NVIC寄存器56 //printf("///////////////////////////////////*rn"); 57 TIMITConfig(TIM3,TIMITUpdate|TIMITCC1|TIMITCC2,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 58 59 TIMCmd(TIM3,ENABLE ); //使能定时器5 60 61 62 63 }64 65 u8 TIM3CH1CAPTURESTA=0; //输入捕获状态 66 u16 TIM3CH1CAPTUREVAL; //输入捕获值 67 68 u8 TIM3CH2CAPTURESTA=0; //输入捕获状态 69 u16 TIM3CH2CAPTUREVAL; //输入捕获值 70 71 void TIM3IRQHandler(void)72 {73 //printf("////////////////////222222///////////////*rn"); 74 75 if (TIM_GetITStatus(TIM3, TIM_IT_Update) !=RESET)76 77 {78 if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 79 {80 if(TIM3CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 81 {82 if((TIM3CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 83 {84 85 TIM3CH1_CAPTURE_VAL=0XFFFF;86 TIM3CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 87 }else TIM3CH1_CAPTURE_STA++;88 }89 }90 91 92 if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获 93 {94 if(TIM3CH2_CAPTURE_STA&0X40)//已经捕获到高电平了 95 {96 if((TIM3CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 97 {98 99 TIM3CH2_CAPTURE_VAL=0XFFFF;100 TIM3CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次 101 }else TIM3CH2_CAPTURE_STA++;102 }103 104 }105 }else{106 107 108 109 110 if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 111 {112 if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 113 {114 115 if(TIM3CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 116 {117 TIM3CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 118 TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);119 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获 120 }else //还未开始,第一次捕获上升沿 121 {122 TIM3CH1_CAPTURE_STA=0; //清空 123 TIM3CH1_CAPTURE_VAL=0;124 TIM_SetCounter(TIM3,0);125 126 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获 127 TIM3CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 128 }129 }130 }131 132 133 134 135 if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获 136 {137 if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕获1发生捕获事件 138 {139 if(TIM3CH2_CAPTURE_STA&0X40) //捕获到一个下降沿 140 {141 TIM3CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 142 TIM3CH2_CAPTURE_VAL=TIM_GetCapture2(TIM3);143 TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获 144 }else //还未开始,第一次捕获上升沿 145 {146 TIM3CH2_CAPTURE_STA=0; //清空 147 TIM3CH2_CAPTURE_VAL=0;148 TIM_SetCounter(TIM3,0);149 150 TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获 151 TIM3CH2_CAPTURE_STA|=0X40; //标记捕获到了上升沿 152 }153 }154 155 }}156 //TIM_SetCounter(TIM3,0); 157 TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update|TIM_IT_CC2); //清除中断标志位 158 159 }

定时器4通道1代码实现:

1 /#include"timex.h" 2 /#include "usart.h" 3 4 //定时器4通道1输入捕获配置 5 6 TIMICInitTypeDef TIM4ICInitStructure;7 8 voidTIM4CapInit(u16 arr,u16 psc)9 {10 11 12 GPIOInitTypeDef GPIOInitStructure;13 TIMTimeBaseInitTypeDef TIMTimeBaseStructure;14 NVICInitTypeDef NVICInitStructure;15 printf("---time 44444 1111 ---rn");16 RCCAPB1PeriphClockCmd(RCCAPB1PeriphTIM4, ENABLE); //使能TIM4时钟 17 RCCAPB2PeriphClockCmd(RCCAPB2PeriphGPIOB, ENABLE); //使能GPIOB时钟 18 19 GPIOInitStructure.GPIOPin = GPIOPin6; //清除之前设置 20 GPIOInitStructure.GPIOMode = GPIOModeIPD; //输入 21 GPIOInit(GPIOB, &GPIOInitStructure);22 GPIOResetBits(GPIOB,GPIOPin6); //下拉23 24 //初始化定时器5 TIM5 25 TIMTimeBaseStructure.TIMPeriod = arr; //设定计数器自动重装值 26 TIMTimeBaseStructure.TIMPrescaler =psc; //预分频器 27 TIMTimeBaseStructure.TIMClockDivision = TIMCKDDIV1; //设置时钟分割:TDTS = Tcktim 28 TIMTimeBaseStructure.TIMCounterMode = TIMCounterModeUp; //TIM向上计数模式 29 TIMTimeBaseInit(TIM4, &TIMTimeBaseStructure); //根据TIMTimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位30 31 //初始化TIM5输入捕获参数 32 TIM4ICInitStructure.TIMChannel = TIMChannel1; //CC1S=01 选择输入端 IC1映射到TI1上 33 TIM4ICInitStructure.TIMICPolarity = TIMICPolarityRising; //上升沿捕获 34 TIM4ICInitStructure.TIMICSelection = TIMICSelectionDirectTI; //映射到TI1上 35 TIM4ICInitStructure.TIMICPrescaler = TIMICPSCDIV1; //配置输入分频,不分频 36 TIM4ICInitStructure.TIMICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 37 TIMICInit(TIM4, &TIM4ICInitStructure);38 39 //中断分组初始化 40 NVICInitStructure.NVICIRQChannel = TIM4IRQn; //TIM3中断 41 NVICInitStructure.NVICIRQChannelPreemptionPriority = 2; //先占优先级2级 42 NVICInitStructure.NVICIRQChannelSubPriority = 0; //从优先级0级 43 NVICInitStructure.NVICIRQChannelCmd = ENABLE; //IRQ通道被使能 44 NVICInit(&NVICInitStructure); //根据NVICInitStruct中指定的参数初始化外设NVIC寄存器45 //printf("///////////////////////////////////*rn"); 46 TIMITConfig(TIM4,TIMITUpdate|TIMITCC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 47 48 TIMCmd(TIM4,ENABLE ); //使能定时器5 49 50 51 52 }53 54 u8 TIM4CH1CAPTURESTA=0; //输入捕获状态 55 u16 TIM4CH1CAPTUREVAL; //输入捕获值56 57 //定时器5中断服务程序 58 void TIM4IRQHandler(void)59 {60 //printf("////////////////////222222///////////////*rn"); 61 if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 62 {63 if (TIM_GetITStatus(TIM4, TIM_IT_Update) !=RESET)64 65 {66 if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 67 {68 if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 69 {70 TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 71 TIM4CH1_CAPTURE_VAL=0XFFFF;72 }else TIM4CH1_CAPTURE_STA++;73 }74 }75 if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 76 {77 if(TIM4CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 78 {79 TIM4CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 80 TIM4CH1_CAPTURE_VAL=TIM_GetCapture1(TIM4);81 TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获 82 }else //还未开始,第一次捕获上升沿 83 {84 TIM4CH1_CAPTURE_STA=0; //清空 85 TIM4CH1_CAPTURE_VAL=0;86 TIM_SetCounter(TIM4,0);87 TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 88 TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获 89 }90 }91 }92 93 TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 94 95 }

 

 

版权声明
本文为[东小东]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/dongxiaodong/p/10134873.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领