我的项目1
1.利用定时器判断正方转,完成;(定时器捕获输入)
代码1:main.c
1 #include "led.h" 2 #include "delay.h" 3 #include "sys.h" 4 #include "usart.h" 5 #include "timer.h" 6 7 extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态 8 extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值 9 extern u8 TIM4CH1_CAPTURE_STA; //输入捕获状态 10 extern u16 TIM4CH1_CAPTURE_VAL; //输入捕获值 11 extern u8 TIM2CH1_CAPTURE_STA; //输入捕获状态 12 extern u16 TIM2CH1_CAPTURE_VAL; //输入捕获值 13 14 #define OVER_TIME 30000 //100us中断一次,3秒为不转 15 #define OVER_COUNT 42000000 16 extern u32 LOW_COUNT,HIGHT_COUNT; 17 extern u32 LOW_COUNT2,HIGHT_COUNT2; 18 int main(void) 19 { 20 u32 temp_time=0; 21 u32 temp_time2=0; 22 u32 low_time=0; 23 u32 low_time2=0; 24 int cycle_i=0,ret=0; 25 int cycle_y=0,ret2=0; 26 delay_init(); //延时函数初始化 27 NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 28 LED_Init(); //初始化gpio 29 uart_init(115200); //串口初始化为115200 30 TIM2_CH1_Cap_Init(0XFFFF,72-1); //PA0 31 TIM3_Int_Init(7200-1,0); //100us 10khz 用作两路不转的判断 32 TIM4_Cap_Init(0XFFFF,72-1); //PB6 以1Mhz的频率计数 ,65.536ms,65536us*0x3f=4095ms 33 34 while(1) 35 { 36 if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿 37 { 38 temp_time=TIM4CH1_CAPTURE_STA&0X3F; 39 temp_time*=65536;//溢出时间总和 40 temp_time+=TIM4CH1_CAPTURE_VAL;//得到总的高电平时间,以1Mhz的频率计数 41 printf("LOW:%d us\r\n",temp_time);//打印总的低电平时间 42 //低电平超时 43 if(temp_time>3000000) 44 { 45 GPIO_ResetBits(GPIOA,GPIO_Pin_5); //PA5 LOW 46 GPIO_ResetBits(GPIOA,GPIO_Pin_6); //PA6 LOW 47 printf("LOW TOO LONG\r\n"); 48 } 49 else 50 { 51 if(temp_time>=100)//需要做一定的滤波; 52 { 53 cycle_i++; 54 if(low_time > 0 )//判断 55 { 56 if(low_time > temp_time) 57 { 58 ret++; 59 } 60 } 61 low_time=temp_time;//赋值保存 62 if(cycle_i%9==0) 63 { 64 if(ret >= 6)//ret=6 65 { 66 //正传 67 GPIO_SetBits(GPIOA,GPIO_Pin_5); //PA5 HIGHT 68 GPIO_ResetBits(GPIOA,GPIO_Pin_6); //PA6 LOW 69 printf("RET:%d \r\n",ret); 70 } 71 else if(ret <= 3 )//ret=3 72 { 73 //反转 74 GPIO_SetBits(GPIOA,GPIO_Pin_6); //PA6 HIGHT 75 GPIO_ResetBits(GPIOA,GPIO_Pin_5); //PA5 LOW 76 printf("RET:%d \r\n",ret); 77 } 78 else 79 { 80 printf("error1 \r\n"); 81 } 82 83 cycle_i=0; 84 ret=0; 85 } 86 } 87 } 88 TIM4CH1_CAPTURE_STA=0;//开启下一次捕获 89 90 } 91 if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿 92 { 93 temp_time2=TIM2CH1_CAPTURE_STA&0X3F; 94 temp_time2*=65536;//溢出时间总和 95 temp_time2+=TIM2CH1_CAPTURE_VAL;//得到总的高电平时间,以1Mhz的频率计数 96 printf("LOW2:%d us\r\n",temp_time2);//打印总的低电平时间 97 //低电平超时 98 if(temp_time2>3000000)//4194303,超时时间 99 { 100 GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 LOW 101 GPIO_ResetBits(GPIOA,GPIO_Pin_8); //PA8 LOW 102 printf("LOW2 TOO LONG\r\n"); 103 } 104 else 105 { 106 if(temp_time2>=100)//需要做一定的滤波; 107 { 108 cycle_y++; 109 if(low_time2 > 0)//判断 110 { 111 if(low_time2 > temp_time2) 112 { 113 ret2++; 114 } 115 } 116 low_time2=temp_time2;//赋值保存 117 118 if(cycle_y%9==0) 119 { 120 if(ret2 >= 5)//ret2=6 121 { 122 //正传 123 GPIO_SetBits(GPIOA,GPIO_Pin_7); //PA7 HIGHT 124 GPIO_ResetBits(GPIOA,GPIO_Pin_8); //PA8 LOW 125 printf("RET2:%d \r\n",ret2); 126 } 127 else if(ret2 < 5)//ret2=3 128 { 129 //反转 130 GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA8 HIGHT 131 GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 LOW 132 printf("RET2:%d \r\n",ret2); 133 } 134 else 135 { 136 printf("error2 \r\n"); 137 } 138 cycle_y=0; 139 ret2=0; 140 } 141 } 142 143 } 144 TIM2CH1_CAPTURE_STA=0;//开启下一次捕获 145 } 146 147 //第1路 148 if(LOW_COUNT > OVER_COUNT)//防数据溢出 149 { 150 LOW_COUNT=0; 151 } 152 if(HIGHT_COUNT > OVER_COUNT) 153 { 154 HIGHT_COUNT=0; 155 } 156 if(LOW_COUNT > OVER_TIME )//超过3秒钟,io口状态没有变化,判断为不转 157 { 158 159 GPIO_SetBits(GPIOC,GPIO_Pin_13); //LED2灭 160 GPIO_SetBits(GPIOB,GPIO_Pin_0); //LED3灭 161 GPIO_ResetBits(GPIOA,GPIO_Pin_5); //PA5 LOW 162 GPIO_ResetBits(GPIOA,GPIO_Pin_6); //PA6 LOW 163 LOW_COUNT=0; 164 printf("no turn1_L \r\n"); 165 } 166 if(HIGHT_COUNT > OVER_TIME )//超过3秒钟,io口状态没有变化,判断为不转 167 { 168 GPIO_SetBits(GPIOC,GPIO_Pin_13); //LED2灭 169 GPIO_SetBits(GPIOB,GPIO_Pin_0); //LED3灭 170 GPIO_ResetBits(GPIOA,GPIO_Pin_5); //PA5 LOW 171 GPIO_ResetBits(GPIOA,GPIO_Pin_6); //PA6 LOW 172 HIGHT_COUNT=0; 173 printf("no turn1_H \r\n"); 174 } 175 176 //第二路 177 if(LOW_COUNT2 > OVER_COUNT)//防数据溢出 178 { 179 LOW_COUNT2=0; 180 181 } 182 if(HIGHT_COUNT2 > OVER_COUNT) 183 { 184 HIGHT_COUNT2=0; 185 } 186 if(LOW_COUNT2 > OVER_TIME )//超过5秒钟,io口状态没有变化,判断为不转 187 { 188 GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 LOW 189 GPIO_ResetBits(GPIOA,GPIO_Pin_8); //PA8 LOW 190 LOW_COUNT2=0; 191 printf("no turn2_L \r\n"); 192 193 } 194 if(HIGHT_COUNT2 > OVER_TIME )//超过5秒钟,io口状态没有变化,判断为不转 195 { 196 197 GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 LOW 198 GPIO_ResetBits(GPIOA,GPIO_Pin_8); //PA8 LOW 199 HIGHT_COUNT2=0; 200 printf("no turn2_H \r\n"); 201 } 202 } 203 204 }
代码2:timer.c
#include "timer.h" #include "led.h" #include "usart.h" void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( //使能或者失能指定的TIM中断 TIM3, //TIM2 TIM_IT_Update | //TIM 中断源 TIM_IT_Trigger, //TIM 触发中断源 ENABLE //使能 ); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设 } int flag_on=0,flag_off=0; int flag_on2=0,flag_off2=0; u32 LOW_COUNT=0,HIGHT_COUNT=0; u32 LOW_COUNT2=0,HIGHT_COUNT2=0; #define PB6 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) //第一路PB6 #define PA0 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //第二路PA0 void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 // LED1=!LED1; if(PB6==0)//读取io口状态 { LOW_COUNT++;//低电平时间计数 flag_on=1; //替高电平设置标志位;保证程序复位后,首先为低电平计数 if(flag_off == 1)//高电平计数后,低电平计数跟高电平计数比较,低电平计数不能大于高电平计数,不符合正反转的规律 { HIGHT_COUNT = 0;//为高电平计数复位 flag_off=0;//标志清零 } } else if(PB6==1) { HIGHT_COUNT++;//高电平时间计数 flag_off=1; //替低电平设置标准位 if(flag_on==1)//dot need to run ever times,选择合适的地方 { flag_on=0; LOW_COUNT = 0; } } if(PA0==0)//读取io口状态 { LOW_COUNT2++;//低电平时间计数 flag_on2=1; //替高电平设置标志位;保证程序复位后,首先为低电平计数 if(flag_off2 == 1)//高电平计数后,低电平计数跟高电平计数比较,低电平计数不能大于高电平计数,不符合正反转的规律 { HIGHT_COUNT2 = 0;//为高电平计数复位 flag_off2=0;//标志清零 } } else if(PA0==1) { HIGHT_COUNT2++;//高电平时间计数 flag_off2=1; //替低电平设置标准位 if(flag_on2==1)//dot need to run ever times,选择合适的地方 { flag_on2=0; LOW_COUNT2 = 0; } } } } TIM_ICInitTypeDef TIM2_ICInitStructure; void TIM2_CH1_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_0); //初始化定时器4 TIM2 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(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM5输入捕获参数 TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上 TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获;zyq TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上 TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 TIM_ICInit(TIM2, &TIM2_ICInitStructure); //中断分组初始化 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 TIM_Cmd(TIM2,ENABLE ); //使能定时器4 } u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态 u16 TIM2CH1_CAPTURE_VAL; //输入捕获值 //定时器2中断服务程序 void TIM2_IRQHandler(void) { if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到低电平了 { if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//低电平太长了 { TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 TIM2CH1_CAPTURE_VAL=0XFFFF; }else TIM2CH1_CAPTURE_STA++; } } if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 { if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个上升沿 { TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次下降沿 TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2); TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=0 设置为下降沿捕获 }else //还未开始,第一次捕获下降沿 { TIM2CH1_CAPTURE_STA=0; //清空 TIM2CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM2,0); TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了下降沿 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=1 设置为上升沿捕获 } } } TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 } // TIM1_CH4_Cap_Init(0XFFFF,72-1); //定时器4通道1输入捕获配置 TIM_ICInitTypeDef TIM4_ICInitStructure; void TIM4_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PA11 清除之前设置 // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA11 输入 // GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO_SetBits(GPIOA,GPIO_Pin_11); //PA11 上拉 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_6); //初始化定时器4 TIM4 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(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM5输入捕获参数 TIM4_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上 // TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获;zyq TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上 TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM4_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波 TIM_ICInit(TIM4, &TIM4_ICInitStructure); //中断分组初始化 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 TIM_Cmd(TIM4,ENABLE ); //使能定时器4 } u8 TIM4CH1_CAPTURE_STA=0; //输入捕获状态 u16 TIM4CH1_CAPTURE_VAL; //输入捕获值 u8 TIM4CH2_CAPTURE_STA=0; //输入捕获状态 u16 TIM4CH2_CAPTURE_VAL; //输入捕获值 //定时器4中断服务程序 void TIM4_IRQHandler(void) { if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) { if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到低电平了 { if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//低电平太长了 { TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 TIM4CH1_CAPTURE_VAL=0XFFFF; }else TIM4CH1_CAPTURE_STA++; } } if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 { if(TIM4CH1_CAPTURE_STA&0X40) //捕获到一个上升沿 { TIM4CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次下降沿 TIM4CH1_CAPTURE_VAL=TIM_GetCapture1(TIM4); TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Falling); //CC1P=0 设置为下降沿捕获 }else //还未开始,第一次捕获下降沿 { TIM4CH1_CAPTURE_STA=0; //清空 TIM4CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM4,0); TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了下降沿 TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Rising); //CC1P=1 设置为上升沿捕获 } } } TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 }
代码3:timer.h
#ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM2_CH1_Cap_Init(u16 arr,u16 psc); void TIM3_Int_Init(u16 arr,u16 psc); void TIM4_Cap_Init(u16 arr,u16 psc); #endif
模块:输入高低电平;不需要驱动;
产品名称:测速传感器模块
版本:槽宽 10mm
物料编码:010903
联系人:张先生
电话:18666850635
QQ:835653538
淘宝店铺:http://fcswitch.taobao.com/
                    
                
                
            
        
浙公网安备 33010602011771号