采用三个电感循迹和超声波避障
制作出来的实物图如下:
单片机源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "sys.h"
- #include "usart.h"
- #include "timer.h"
- #include "moto.h"
- #include "pwm.h"
- #include "lcd.h"
- #define Trig PGout(1) //PC1 TRIG
- //函数声明
- void UltrasonicWave_Configuration(void);
- void UltrasonicWave_StartMeasure(void);
- void TIM5_Int_Init(u16 arr,u16 psc);
- extern int Sensor_Left,Sensor_Middle,Sensor_Right;//电磁巡线相关
- extern float Velocity_KP,Velocity_KI,Sensor,sum; //速度控制PID参数
- extern float Velocity,Velocity_Set,Turn,Angle_Set;
- extern int Motor_A,Motor_B,Servo,Target_A,Target_B; //电机控制相关
- extern int Encoder_Left,Encoder_Right; //左右编码器的脉冲计数
- extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态
- extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值
- //void TIM3_Int_Init(u16 arr,u16 psc);
- void UltrasonicWave_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOG, &GPIO_InitStructure);
- }
- void UltrasonicWave_StartMeasure(void)
- {
- Trig = 1;
- delay_us(20); //??20US
- Trig = 0;
-
- }
- int main(void)
- {
- u32 temp=0;
- float UltrasonicWave_Distance=0; //计算出的距离
- delay_init(); //延时函数初始化
- Encoder_Init_TIM2(); //=====编码器接口
- delay_ms(100);
- Encoder_Init_TIM3(); //=====初始化编码器
- delay_ms(100);
- Motor_PWM_Init(7199,0); //=====初始化PWM 10KHZ,用于驱动电机
- delay_ms(100);
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
- UltrasonicWave_Configuration();
- TIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数
- ele_Init(); //=====电磁传感器初始化
- delay_ms(100);
-
- LED_Init(); //LED端口初始化
- LCD_Init();
-
- POINT_COLOR=RED;
- delay_ms(100);
- //TIM5_Int_Init(5000,71);//10Khz的计数频率,计数到5000为500ms
- delay_ms(100);
- while(1)
- {
- UltrasonicWave_StartMeasure();//开始测距
- if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
- {
- temp=TIM5CH1_CAPTURE_STA&0X3F;
- temp*=65536;//溢出时间总和
- temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间
-
- UltrasonicWave_Distance=(float)temp*170/10000;//距离计算公式:距离=高电平持续时间*声速/2
- //即 距离= 高电平持续时间*340*100/(2*1000 000) = 高电平持续时间*170/10000
- //printf("Distance:%f cm\r\n",UltrasonicWave_Distance);//打印总的高点平时间
- TIM5CH1_CAPTURE_STA=0;//开启下一次捕获
- }
- LCD_ShowString(10,40,200,16,16,"TFTLCD TEST");
- LCD_ShowxNum(10,60,Sensor_Left,4,16,0);
- LCD_ShowxNum(10,80,Sensor_Middle,4,16,0);
- LCD_ShowxNum(10,100,Sensor_Right,4,16,0);
- LCD_ShowxNum(10,120,Turn,4,16,0);
- LCD_ShowxNum(10,140,Sensor,4,16,0);
- LCD_ShowxNum(10,160,UltrasonicWave_Distance,4,16,0);
- Sensor_Left=Get_Adc(11); //采集左边电感的数据
- Sensor_Right=Get_Adc(13); //采集右边电感的数据
- Sensor_Middle=Get_Adc(12); //采集中间电感的数据
- sum=Sensor_Left-Sensor_Right; //归一化处理
- Sensor=150*sum/(Sensor_Left+Sensor_Middle+Sensor_Right+1); //求偏差
- Sensor=Sensor>120?120:Sensor;
- Sensor=Sensor<-120?-120:Sensor;
- Get_RC();//pid计算输出
- if(UltrasonicWave_Distance>15)
- {
- PWMA1=4000+Turn,PWMA2=0;
- PWMB1=0,PWMB2=3200+Turn;
- }
- else
- {
- PWMA1=7200+Turn,PWMA2=0;
- PWMB1=0,PWMB2=0+Turn;
- }
- //LED0=!LED0;
- //delay_ms(200);//测试主程序是否卡死
-
- }
- }
- 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)//检查TIM5更新中断发生与否
-
- {
- 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 设置为下降沿捕获
- }
- }
- }
-
- TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
-
- }
- //定时器3中断服务程序
- //void TIM5_IRQHandler(void) //TIM3中断
- //{
- // if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
- // {
- //
- // TIM_ClearITPendingBit(TIM5, TIM_IT_Update ); //清除TIMx更新中断标志
- //// if(Flag_Target==1) '
- //
- //
- // //LED1=!LED1;//测试中断
- // // if(Flag_Target==0)
- //// {
- // // Encoder_Left=Read_Encoder(2); //===读取编码器的值 //为了保证M法测速的时间基准,首先读取编码器数据
- // // Encoder_Right=-Read_Encoder(3); //===读取编码器的值
- // Get_RC();
- // //Kinematic_Analysis(Velocity,Turn); //小车运动学分析
- ////Motor_A=Incremental_PI_A(Encoder_Left,Target_A); //===速度闭环控制计算电机A最终PWM
- // // Motor_B=Incremental_PI_B(Encoder_Right,Target_B); //===速度闭环控制计算电机B最终PWM
- // // Xianfu_Pwm(); //===PWM限幅
- // //Set_Pwm(Motor_A,Motor_B,Servo); //===赋值给PWM寄存器
- //// }
- // }
- //}
复制代码
所有资料51hei提供下载:
xunji5.16.7z
(234.08 KB, 下载次数: 37)
|