【附源码】基于stm32的pwm调速自动避障红外遥控小车

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#include "MOTOR.h"
#include "remote.h"
#include "HC-SR04.h"

extern float UltrasonicWave_Measure(void);   
 
 int main(void)
 {		
      float distance;
      u8 key=0;
	  UltrasonicWave_Init(); //超声波测距初始化
      delay_init();	    	         //延时函数初始化	  
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	  uart_init(115200);	 //串口初始化为115200
 	  Remote_Init();
      TIM3_PWM_Init(400,0);	 //不分频。PWM频率=72000000/900=80Khz
      TIM5_PWM_Init(400,0);	 //不分频。PWM频率=72000000/900=80Khz
      while(1)
	  {            
            go_straight(); 
            distance = UltrasonicWave_Measure(); //完成测距
            if(distance < 50)
            {
            	avoid_obstacle();
            }                       
            key=Remote_Scan();
            
            if(key)
            {
                switch(key)
				{			   
				case 194://right
                      turn_right();                             
                      break;	   
				case 34://left
                      turn_left();                             
                      break;		  						  
				case 162://stop
                      stop();                                   
                      break;	
                case 168://back
                      back();
                      break;                                                                                     
				}                                                                 
            }            
      }	 
 }

timer.c

#include "timer.h"
#include "led.h"
#include "usart.h"

   	  
//TIM3 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIO外设
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); 
	   
 
   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOA.7
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM3_CH1\2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //TIM3_CH3\4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
      
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	 
       //初始化TIM3 Channel1 PWM模式   
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1
	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
 
	//初始化TIM3 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
      
      //初始化TIM3 Channel3 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR3上的预装载寄存器
      
      //初始化TIM3 Channel4 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC4
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR4上的预装载寄存器
     
    TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}

void TIM5_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);	//使能定时器5时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
	
 
   //,输出TIM5 CH2的PWM脉冲波形	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM5_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
      
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM5_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
      
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM5_CH3
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
      
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM5_CH4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM5 Channel1 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM5, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM5 OC1
    TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);  //使能TIM5在CCR2上的预装载寄存器
      
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM5, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM5 OC2
	TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);  //使能TIM5在CCR2上的预装载寄存器
      
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC3Init(TIM5, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM5 OC1
    TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable);  //使能TIM5在CCR2上的预装载寄存器
      
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC4Init(TIM5, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM5 OC1
    TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Enable);  //使能TIM5在CCR2上的预装载寄存器
 
	TIM_Cmd(TIM5, ENABLE);  //使能TIM5
	
}

MOTOR.c

#include "MOTOR.h"
#include "delay.h"

#define INq1 PAout(0)// PA0,前右轮,定时器5通道1
#define INq2 PBout(0)// PB0,前右轮,定时器3通道3
#define INq3 PBout(1)// PB1,前左轮,定时器3通道4
#define INq4 PAout(1)// PA1,前左轮,定时器5通道2
#define INh1 PAout(6)// PA6,后右轮,定时器3通道1
#define INh2 PAout(3)// PA3,后右轮,定时器5通道4
#define INh3 PAout(2)// PA2,后左轮,定时器5通道3
#define INh4 PAout(7)// PA7,后左轮,定时器3通道2

void go_straight(void)
{
      delay_ms(10);
      TIM_SetCompare1(TIM3,250);//定时器3,通道1,PA6,右后轮
      //TIM_SetCompare4(TIM5,400);//定时器5,通道4,PA3,右后轮
      TIM_SetCompare2(TIM3,250);//定时器3,通道2,PA7,左后轮
      //TIM_SetCompare3(TIM5,400);//定时器5,通道3,PA2,左后轮
      TIM_SetCompare1(TIM5,250);//定时器5,通道1,PA0,右前轮
      //TIM_SetCompare3(TIM3,400);//定时器3,通道3,PB0,右前轮
      TIM_SetCompare2(TIM5,250);//定时器5,通道2,PA1,左前轮 
      //TIM_SetCompare1(TIM3,400);//定时器3,通道4,PB1,左前轮
      delay_ms(200); 
      
}


void turn_right(void)
{
      delay_ms(10);
      TIM_SetCompare1(TIM3,250);//定时器3,通道1,PA6,右后轮
      //TIM_SetCompare4(TIM5,400);//定时器5,通道4,PA3,右后轮
      TIM_SetCompare2(TIM3,50);//定时器3,通道1,PA7,左后轮
      //TIM_SetCompare3(TIM5,400);//定时器5,通道3,PA2,左后轮
      TIM_SetCompare1(TIM5,250);//定时器5,通道1,PA0,右前轮
      //TIM_SetCompare3(TIM3,400);//定时器3,通道3,PB0,右前轮
      TIM_SetCompare2(TIM5,50);//定时器5,通道2,PA1,左前轮     
      //TIM_SetCompare1(TIM3,400);//定时器3,通道4,PB1,左前轮     
      delay_ms(100);

}

void turn_light_right(void)
{
      delay_ms(10);
      TIM_SetCompare1(TIM3,250);//定时器3,通道1,PA6,右后轮     
      TIM_SetCompare2(TIM3,100);//定时器3,通道1,PA7,左后轮    
      TIM_SetCompare1(TIM5,250);//定时器5,通道1,PA0,右前轮     
      TIM_SetCompare2(TIM5,100);//定时器5,通道2,PA1,左前轮     
      delay_ms(300);         
}

void turn_left(void)
{
      delay_ms(10);
      TIM_SetCompare1(TIM3,50);//定时器3,通道1,PA6,右后轮
      //TIM_SetCompare4(TIM5,400);//定时器5,通道4,PA3,右后轮
      TIM_SetCompare2(TIM3,250);//定时器3,通道1,PA7,左后轮
      //TIM_SetCompare3(TIM5,400);//定时器5,通道3,PA2,左后轮
      TIM_SetCompare1(TIM5,50);//定时器5,通道1,PA0,右前轮
      //TIM_SetCompare3(TIM3,400);//定时器3,通道3,PB0,右前轮
      TIM_SetCompare2(TIM5,250);//定时器5,通道2,PA1,左前轮 
     // TIM_SetCompare1(TIM3,400);//定时器3,通道4,PB1,左前轮 
      delay_ms(100);     
}

void turn_light_left(void)
{
      delay_ms(10);
      TIM_SetCompare1(TIM3,100);//定时器3,通道1,PA6,右后轮     
      TIM_SetCompare2(TIM3,250);//定时器3,通道1,PA7,左后轮    
      TIM_SetCompare1(TIM5,100);//定时器5,通道1,PA0,右前轮     
      TIM_SetCompare2(TIM5,250);//定时器5,通道2,PA1,左前轮     
      delay_ms(300);           
}

void stop(void)
{
       while(1)
       {             
            //delay_ms(10);
            TIM_SetCompare1(TIM3,400);//定时器3,通道1,PA6,右后轮
           //TIM_SetCompare4(TIM5,400);//定时器5,通道4,PA3,右后轮
            TIM_SetCompare2(TIM3,400);//定时器3,通道2,PA7,左后轮
             //TIM_SetCompare3(TIM5,400);//定时器5,通道3,PA2,左后轮
            TIM_SetCompare1(TIM5,400);//定时器5,通道1,PA0,右前轮
            //TIM_SetCompare3(TIM3,400);//定时器3,通道3,PB0,右前轮
            TIM_SetCompare2(TIM5,400);//定时器5,通道2,PA1,左前轮 
            //TIM_SetCompare1(TIM3,400);//定时器3,通道4,PB1,左前轮
            delay_ms(200); 
       }
}

void back(void)
{                 
       //TIM_SetCompare1(TIM3,400);//定时器3,通道1,PA6,右后轮
       TIM_SetCompare4(TIM5,0);//定时器5,通道4,PA3,右后轮
       //TIM_SetCompare2(TIM3,400);//定时器3,通道1,PA7,左后轮
       TIM_SetCompare3(TIM5,0);//定时器5,通道3,PA2,左后轮
       //TIM_SetCompare1(TIM5,400);//定时器5,通道1,PA0,右前轮
       TIM_SetCompare3(TIM3,0);//定时器3,通道3,PB0,右前轮
       //TIM_SetCompare2(TIM5,400);//定时器5,通道2,PA1,左前轮 
       TIM_SetCompare4(TIM3,0);//定时器3,通道4,PB1,左前轮
       delay_ms(200);                     
}

void avoid_obstacle(void)
{
       turn_light_left();
       turn_light_right();
       turn_light_right();
       turn_light_left();
}

HC-SR04.c

#include "HC-SR04.h"
#include "stm32f10x_tim.h"
#include "delay.h"

void UltrasonicWave_Init(void)
{
  	GPIO_InitTypeDef GPIO_InitStructure;    
  	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB时钟
  	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);//开启GPIOB时钟    
 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2时钟    
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;    // 对应trig引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOB,GPIO_Pin_11);    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    // 对应echo引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);    

//定时器初始化,分频系数为71,则频率为1MHZ,每个计数为1us,(频率越高越精确)
//重装载值为65535,溢出时间为1us*65536=    65.536ms=0.065536s
//一个计数周期可以测距 0.065536s * 340m/s / 2 = 11.14112m
  TIM_TimeBaseStructure.TIM_Period = 65535; 
  TIM_TimeBaseStructure.TIM_Prescaler = 71; 
  TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //    
}

void UltrasonicWave_StartMeasure(void)
{
  GPIO_SetBits(GPIOB, GPIO_Pin_11); //拉高PB1电平
  delay_us(20); //持续20us
  GPIO_ResetBits(GPIOB, GPIO_Pin_11); //拉低PB1电平
}


/***** 测距 *****/
float UltrasonicWave_Measure(void) //
{
  while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1);//echo为高电平时,则等待至低电平,才启动超声波
  UltrasonicWave_StartMeasure(); //启动超声波    
  while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == 0);//等待 echo的高电平到来    
  TIM_SetCounter(TIM2,0); //清零计数器
  TIM_Cmd(TIM2, ENABLE); //使能定时器2,开始计数
  while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == 1);//等待 echo的高电平结束
  TIM_Cmd(TIM2, DISABLE);    //失能定时器2,截止计数    
  return (TIM_GetCounter(TIM2))/1000000.0*340/2 *100;    //此处单位转换为cm
}
  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Greif_Hairline

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值