stm32 电磁巡线小车

一 可实现功能

  1. 使用陀螺仪,根据俯仰角变化在下坡后停车 。
  2. 通过三路电感,实现小车巡线,可循 s弯 ,d形弯,8字弯,环岛。
  3. 可在不同的地方巡线,有学习能力。
  4. 红外光电开关判断,实现小车的启停,启动舵机。

二 实物图


三 所需材料

  • 此账单与可遥控机械臂小车账单合并

四 程序

// mian.c#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "mpu6050.h"
#include "usmart.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "stm32f10x.h"
#include "oscilloscope.h"
#include "adc.h"
#include  "motor.h"
#include  "xhg.h"
#include "slope.h"
#include "duoji.h"float pitch,roll,yaw;       //欧拉角int sign1 = 1, sign2 = 1;
int sign3 = 1;int error=0,error2=0,error3=0;
int flag6=0;
int main(void)
{ extern unsigned char time;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先TIM3_PWM_Init();  TIM2_PWM_Init();TIM4_PWM_Init();ADC_init();     //  adc 采集delay_init();TIM4_duoji();key_y();sensor_init();    // 小黄管GPIO_SetBits(GPIOC,GPIO_Pin_0 |  GPIO_Pin_1|  GPIO_Pin_2 |  GPIO_Pin_6|  GPIO_Pin_7|GPIO_Pin_3);   //触发信号/*************上下桥模块*************/while( 1 ){ if(GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_8) == 0&&flag6==0){MPU_Init();     //初始化MPU6050 while( mpu_dmp_init() );flag6=1;}if(GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_9) == 0&&flag6==0){flag6=2;}if(flag6==1){if( mpu_dmp_get_data(&pitch,&roll,&yaw) == 0 ){ if( pitch < 10 ){forward(80,80);}else if(pitch>15&&pitch<25){forward(60,60);}else if(pitch>25)           //          俯仰角  {forward(20,20);delay_ms(3000);stop();while(GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_1) == 1) ;    // 第一节车厢                sign3 = 0;flag6=2;break;}else{forward(20,20);}}}if(flag6==2){break;}}while(1)
{       //小黄管检测 有严格的顺序, 在蓝方 先右后左   //  pc1 第一节//  pc0 第二节//  pc2 第三节int i;float left_speed=85;float right_speed=85;pid_cul(left_speed,right_speed);   if( (GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_7) == 0) && ( sign1 == 1) ) //右侧小黄管检测到挡板{   sign1 = 0;stop();for( i = 0; i<250; i++){stop();delay_ms(100);if( GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_0) == 0 )//     小车后间   第二小黄管检测到物料放入  { break;//跳出延时等待,继续循迹}}                    }else if( (GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_6) == 0) && ( sign2 == 1 )&&(sign1==0) ) //左侧小黄管检测到挡板{  delay_ms(30);sign2=0;for( i = 0; i<250; i++){stop();delay_ms( 100 );if( GPIO_ReadInputDataBit(GPIOC , GPIO_Pin_2) == 0)       //  小车中黄管     检测到物料放入{break;//跳出延时等待,继续循迹}}}else if( !(GPIO_ReadInputDataBit( GPIOC , GPIO_Pin_3 )) &&sign1==0&&sign2==0){stop();duoji_juqi();while(1);}}}
void key_y()
{GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC , ENABLE );  //串口时钟使能GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式GPIO_InitStruct.GPIO_Pin =   GPIO_Pin_8 |  GPIO_Pin_9 ;           //后两个依次为左右检测挡板小黄管.  //前三个为检测物料小黄管.依次检测第一块物料,第二块物料,第三块物料GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init( GPIOC , &GPIO_InitStruct );
}
// motor.c
// pid #include "stm32f10x.h"
#include  "motor.h"
#include "delay.h"
#include "adc.h"
#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "duoji.h"unsigned char time = 0;void TIM4_PWM_Init()
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能TIM_TimeBaseStructure.TIM_Period = 9999; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值  TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器}
//定时器3中断服务程序
void TIM4_IRQHandler(void)   //TIM4中断
{time++;//1秒中断一次TIM_ClearITPendingBit(TIM4,TIM_IT_Update);    }void  TIM3_PWM_Init( )
{
//TIM3 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器4时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO //初始化TIM3TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM3 C![在这里插入图片描述](https://img-blog.csdnimg.cn/0c153beed1814e3da3ed30ce3058eb89.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YyX5Lqs5LiN5Lya6YGH5Yiw6KW_6ZuF5Zu-,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
hannel/2/3/4 PWM模式  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC4 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR3上的预装载寄存器TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR4上的预装载寄存器 TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}void TIM2_PWM_Init( void )
{  GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器4时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //右前7通道2,左前8通道3,右后6通道1,左后9通道4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO //初始化TIM4TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM2 Channel/2/3/4 PWM模式  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC1TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC2TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC4Init(TIM2, &TIM_OCInitStructure);  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM4在CCR1上的预装载寄存器TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_Cmd(TIM2, ENABLE); }//TIM1中的PB6 PB7  代表左前轮, PB0 PB1  代表左后轮; TIM4中的PB6 B7代表右后轮,B8 B9代表右前轮
void forward(float speed_left ,float speed_right )
{TIM_SetCompare1(TIM3,speed_right);    //        PA6  PA7  右前TIM_SetCompare2(TIM3,0);   TIM_SetCompare3(TIM3,speed_right);    //      PB0  PB1     右后TIM_SetCompare4(TIM3,0);          TIM_SetCompare1(TIM2,speed_left);     //    PA0   PA1  左前TIM_SetCompare2(TIM2,0);       TIM_SetCompare3(TIM2,speed_left);     TIM_SetCompare4(TIM2,0);             //           PA2   PA3    左后
}void turnright(float  speed_left, float  speed_right)
{ //  右轮反转, 左轮正转 加速  TIM_SetCompare1(TIM3,0);              //      PA6  PA7  右前TIM_SetCompare2(TIM3,speed_right);   TIM_SetCompare3(TIM3,0);              //      PB0  PB1     右后TIM_SetCompare4(TIM3,speed_right);          TIM_SetCompare1(TIM2,speed_left);     //      PA0   PA1  左前TIM_SetCompare2(TIM2,0);       TIM_SetCompare3(TIM2,speed_left);     TIM_SetCompare4(TIM2,0);             //        PA2   PA3    左后}void turnleft(float  speed_left, float  speed_right)
{ // 左轮反转, 右轮正转 加速 TIM_SetCompare1(TIM3,speed_right);              //      PA6  PA7  右前TIM_SetCompare2(TIM3,0);   TIM_SetCompare3(TIM3,speed_right);              //      PB0  PB1     右后TIM_SetCompare4(TIM3,0);          TIM_SetCompare1(TIM2,0);     //      PA0   PA1  左前TIM_SetCompare2(TIM2,speed_left);       TIM_SetCompare3(TIM2,0);     TIM_SetCompare4(TIM2,speed_left);             //        PA2   PA3    左后}void stop(void)
{TIM_SetCompare1(TIM3,0);              //      PA6  PA7  右前TIM_SetCompare2(TIM3,0);   TIM_SetCompare3(TIM3,0);              //      PB0  PB1     右后TIM_SetCompare4(TIM3,0);          TIM_SetCompare1(TIM2,0);     //      PA0   PA1  左前TIM_SetCompare2(TIM2,0);       TIM_SetCompare3(TIM2,0);     TIM_SetCompare4(TIM2,0);             //        PA2   PA3    左后; }void  pid_cul(float left_speed, float right_speed)
{int max = 2000;int symbol;int change_speed;float left,middle,right;float kp = 0.078,Kp;   //0.0878,     0.178     0.0378      0.0578    0.0478float ki = 0.00031,Ki;float kd = 0.00853,Kd;float error;static float last_1_error = 0;static float last_2_error = 0;left = Get_ADC_Average(ADC_Channel_5); //通道一 PA1middle = Get_ADC_Average(ADC_Channel_14);    //通道四 PA4right = Get_ADC_Average(ADC_Channel_15); //通道三 PA3symbol = left - right;if( symbol < 0 ){error = -symbol;}else{error = symbol;}if(middle<750&&left<750)   //  直右转 {turnright(70,80);delay_ms(250);}else if(middle<750&&right<750)   //  直左转 {turnleft(80,70);delay_ms(250);} if(middle>3000&&right>2200&&time<5)    // right left  值不定  { forward(80,80);delay_ms(510);turnleft(80,80);delay_ms(200);forward(70,80);delay_ms(400);TIM_Cmd(TIM4, ENABLE);  //使能TIM4}else    if(middle>3000&&right>2000&&time>12){forward(80,80);delay_ms(150);turnleft(70,80);delay_ms(200);forward(70,80);delay_ms(800);}else  if(  left-right < -300 )      // 小车已往左偏   往右转{Kp = kp * ( error - last_1_error );Ki += ki * error;Kd = kd * ( error - ( 2 * last_1_error ) +  last_2_error );if( error > max )//限幅{error = last_1_error;}change_speed = (int)( Kp + Ki + Kd );forward((left_speed + change_speed) , (right_speed - change_speed) );} else if(left-right > 300  )     //正值向右偏,小车向左转;{error = symbol;Kp = kp * ( error - last_1_error );Ki += ki * error;Kd = kd * ( error - ( 2 * last_1_error ) +  last_2_error );if( error > max )//限幅{error = last_1_error;}change_speed = (int)( Kp + Ki + Kd );forward((left_speed -change_speed) , (right_speed + change_speed));}else   {forward( left_speed ,right_speed );//以初始速度直行} last_1_error = error;last_2_error = last_1_error;
}
// adc.c
// 电感采集 滤波算法 #include "adc.h"
#include "math.h"
#include "delay.h"
#include "stm32f10x.h"void ADC_init()
{ADC_InitTypeDef ADC_InitStruct;                                                                                                                            //定义adc结构体GPIO_InitTypeDef GPIO_InitStruct;                                                                                                                     //定义gpio结构体RCC_ADCCLKConfig(RCC_PCLK2_Div6);                                                                                                                        //选择时钟2分频                             RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);                                        //使能gpio和adcGPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;                                                                                                       //gpio口初始化GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;       //添加口   需要修改的地方GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;                                                                                                       //gpio口初始化GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;       //添加口   需要修改的地方GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStruct); ADC_DeInit(ADC1);                                                                                                                                                       //adc初始化ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;     //独立模式ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;      //不开启扫描ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;   //数据右对齐ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;  //触发软件ADC_InitStruct.ADC_NbrOfChannel=3;                  //ADC的通道数目   着重注意一下需要修改ADC_InitStruct.ADC_ScanConvMode=DISABLE;ADC_Init(ADC1,&ADC_InitStruct);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);  //重置指定的ADC的校准寄存器while(ADC_GetResetCalibrationStatus(ADC1));//等待上一步操作完成ADC_StartCalibration(ADC1);     //开始制定ADC的校准状态while(ADC_GetCalibrationStatus(ADC1));  //等待上一步操作完成ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5 );ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 2, ADC_SampleTime_239Cycles5 );ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 3, ADC_SampleTime_239Cycles5 );}//获取ADC通道的数据u16 Get_ADC(u8 ch)
{ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);  //开始采集 采集哪个口ADC_SoftwareStartConvCmd(ADC1,ENABLE);while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));return ADC_GetConversionValue(ADC1);
}//软件滤波
#define N 12
u16 Get_ADC_Average(u8 ch)
{u32 temp_value=0;u8 t;for(t=0;t<10;t++){temp_value+=Get_ADC(ch);}return temp_value/N;
}
// 舵机
#include "duoji.h"
#include "stm32f10x.h"
#include "delay.h"void TIM4_duoji()
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  //使能TIM8的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIO 的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//配置GPIO//设置该引脚为复用输出功能,输出 TIM8 CH1 的 PWM 脉冲波形GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化TIM8TIM_TimeBaseStructure.TIM_Period = 1999;                     //设置自动重装载的值TIM_TimeBaseStructure.TIM_Prescaler = 719;                  //设置预分频系数TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置向上计数(累加)计数模式//至此,定时器就能正常工作了,此时的溢出时间也就是周期为:Tout= ((arr+1)*(psc+1))/Tclk 这里的Tclk为72MHzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟的分频因子,仅对电路的稳定性有影响TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);            //初始化TIM8//初始化 TIM8 Channel2 PWM 模式TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择PWM模式2,/*在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。*/TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //设置极性,输出有效电平为:高电平TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OC4Init(TIM1, &TIM_OCInitStructure);                   //初始化外设 TIM8 OC1TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能预装载寄存器GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1,ENABLE);TIM_Cmd(TIM1, ENABLE); //使能 TIM8TIM_CtrlPWMOutputs(TIM1, ENABLE); //主输出使能,当使用的是通用定时器时,这句不需要
}//
void duoji_juqi()
{int i;int j;for(j=0;j<10;j++){ for(i = 1500 ; i >0; i--)// 865 900{ TIM_SetCompare4( TIM1 , i );delay_us( 500 );}for(i = 0 ; i <1500; i++)// 865 900{  TIM_SetCompare4( TIM1 , i );delay_us( 500 );}}}// 萌新驾到
// 此为不完全程序,如需完整程序请私聊,免费

五 总结

 1.在购买材料时,尽量买材质好一点的,杜邦线的选择很重要,材质差的杜邦线,会影响很多地方,而这些地方,会很麻烦。另外也多买几份,当作备用件,这对项目的进程有很大的帮助。2.在书写程序时,要多独立思考,编译器有很多不懂的bug时,用百度查,可以在后台开一个网易有道词典,可以翻译出现bug原因,通常是程序书写不规范导致。3.多采集数据,电磁赛道与很多其他的赛道不同,不同赛道,不同楼层的电感值可能会不同,注意采集,直线,直角,d形弯,环岛,s弯 电磁值的变化,总结规律。4.注意保护电感,小车在赛道巡线时,可能会与赛道或其他小车产生碰撞,电感位置的变化也会对小车巡线产生影响。5.小车在前期接线,插线时,要注意避免线太乱,否则到项目后期,在小车出现硬件上的问题时,会因为线太乱,影响项目进程。

stm32 电磁巡线小车相关推荐

  1. 基于STC89C52RC模块的巡线小车

    基于STC89C52RC模块的巡线小车 在STC89C52RC的基础上使用电机驱动使小车完成巡线,停站,避障,掉头等多功能智能小车 所需头文件: #include <reg52.h> #i ...

  2. Arduino案例实操 -- 智能巡防小车(三)图形化巡线小车编程

    巡防小车的巡线功能同时可以用图形化编程软件来实现.博主这里用的图形化编程软件是KRobot. 三.图形化巡线小车编程 3.1 编程环境配置 3.1.1 下载编程软件 3.1.2 安装编程软件 3.2 ...

  3. Arduino案例实操 -- 智能巡防小车(三)Arduino IDE巡线小车编程

    三.Arduino IDE巡线小车编程 3.1 Arduino开发环境 下载免安装ZIP包 下载IDE安装包 3.2 Arduino IDE 3.3 Blink项目实例 打开内置案例 进行程序上传 3 ...

  4. OpenMV:14巡线小车

    文章目录 追小球的小车 巡线小车 这个例子展示了在OpenMV Cam上使用get_regression()方法获得ROI的线性回归.使用这种方法,可以轻松让机器人跟踪所有指向相同大致方向的线. 本例 ...

  5. 基于STM32F103智能巡线小车

    ​ 项目描述: 巡线小车是我作为新手入手的第一个项目,基本巡线功能是使用红外传感器循迹模块判断黑线的路径来确定转向方向,同时控制单片机配置PWM占空比波控制小车前进的L298N电机模块,实现前后退,左 ...

  6. 巡线小车学习笔记(arduino 四路循迹)

    巡线小车代码学习笔记 红外布局原理 中间两路巡线一直在黑线上,小车会直行,当任意一个出来,小车会自动纠正.如果最外面的检测到黑线.则小车以更大速度纠正到黑线上去.在算法上,优先处理锐角,直角等外围传感 ...

  7. 从零开始制作OV7670摄像头巡线小车

    大家想不想自己动手制作如下一款摄像头巡线小车呢? 摄像头寻迹小车,你们想要不? 这款硬件原理图如下所示: 需要的主要材料清单有: 1.STM32F411核心板 2.OV7670摄像头 3.A4988步 ...

  8. 基于arduino下的巡线小车

    先发代码再进行解释吧 #include <Wire.h> // Include the I2C library (required) #include "QGPMaker_IIC ...

  9. 根据星瞳科技openmv巡线小车所改进的巡线方案

    首先看一下星瞳科技的巡线方案(附上其开源源码): THRESHOLD = (5, 70, -23, 15, -57, 0) # Grayscale threshold for dark things. ...

最新文章

  1. zend framework php编码规范,Zend Framework常用校验器详解
  2. springMVC参数传递(三)
  3. STC89C52单片机 独立键盘
  4. jQuery表单校验jquery.validate.js的使用
  5. Pandas数据排序,人人都能学会的几种方法
  6. android滚动条布局横向,Android自定义ViewGroup实现可滚动的横向布局(2)
  7. hive的row_number()、rank()和dense_rank()的区别以及具体使用
  8. 帮你少写一大半参数校验代码的小技巧
  9. 服务器提交协议冲突 Section=ResponseStatusLine 的解决办法
  10. VB讲课笔记14:二级VB知识点总结
  11. 端到端测试哪家强?不容错过的Cypress
  12. 解决Ubuntu16.04中文乱码问题
  13. linux下两个线程交替打印,两个线程交替打印AB
  14. python机器学习-乳腺癌细胞挖掘(基于真实美国临床数据)
  15. Mybatis自动去重
  16. PSNR峰值信噪比(python代码实现+SSIM+MSIM)
  17. 团队作业8----第二次项目冲刺(Beta阶段) 第四天
  18. android 设置来电铃声
  19. 学习python第八节课:可变与不可变对象
  20. global 与 $GLOBALS用法

热门文章

  1. IT从业人员必须要知道的英语词汇
  2. Windows 7中使用建设银行网银
  3. y神动态规划第二课、第三课代码
  4. font-weight(字体粗细)属性
  5. 基于Andriod的温湿度检测超声波测量
  6. php蚂蚁森林的效果,iOS仿支付宝蚂蚁森林动画效果
  7. 四川师大计算机学院老师举报校长的贴子,学生毕业8年举报遭老师辱骂 已升副校长老师被撤职...
  8. 基于状态机的简单控制
  9. ed2k解析源码php,PHP源码调试分析
  10. Java之~hutool批量压缩多个图片文件上传到云服务(InputStream )