【考核评估】stm32蓝牙智能小车可调节速度,ADC控制LED灯亮度

在stm32f407的学习过程中,自己动手做一个智能小车,同时也是为了实验室考核的需要。同时用电位器
利用ADC控制LED灯亮度。有问题或者要代码可以问我直接在下方评论或者给我发邮件(我的邮箱[email protected]
注意:如果要控制速度ENA,ENB必须与PWM相连。
会串口通信就可以使用蓝牙,一般从淘宝上买的蓝牙默认为从机,直接用杜邦线将蓝牙与单片机连接起来就行。也可通过AT指令调节,这里不做说明,网上很多。PWM调速的原理读者很容易就可以在网上找到,这里也不做说明。
蓝牙连接方式:VCC------+5v
GND-------GND
TXD-------Ux_RX
RXD-------Ux_TX
那两个IO口可以不用连接。 stm32与L298N连接方式(这是我自己的你们可以根据自己的情况修改): IN1----PB6 IN2----PB7 IN3----PB8 IN4----PB9 ENA----PF6 ENB-----PD13
在写代码的时候可以一部分写完再写另一部分,这样出现了错误就能及时修改。在检测PWM的时候可以先用杜邦线将选择的PWM管脚口与LED管脚口连接,通过观察灯的亮度来检测PWM是否正常。
材料清单:小车,蓝牙模块HC05,L298N(具体数量根据电机数决定 ),18650锂电池(4节1.5v的带不动电机),杜邦线,线仔线。
![在这里插入图片描述](ht

tps://img-blog.csdnimg.cn/20200309213535980.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xMWV9BXw==,size_16,color_FFFFFF,t_70)

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
上代码:

在这里插入图片描述

主函数 main.h

#include "system.h"
#include "motor.h"
#include "pwm.h"
#include "motor.h"
#include "usart3.h"
#include "led.h"
#include "SysTick.h"
#include "adc.h"
#include "time.h"
#include "beep.h"

int main()
{ 
 
 u16 value;
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
 SysTick_Init(168);
 LED_Init();
 BEEP_Init();
 TIM10_CH1_CH3_PWM_Init(500-1,84-1); //PWM调速
 TIM4_CH1_CH3_PWM_Init(500-1,84-1); //PWM调速
 MotorInit();//动力系统
 USART3_Init(9600);//蓝牙串口连接手机
 ADCx_Init();
 TIM14_CH1_PWM_Init(5000-1,84-1); //频率是2Kh
 TIM3_Init(5000-1,84-1); //500ms

while(1)
 { 
  value=Get_ADC_Value(ADC_Channel_5);
  TIM_SetCompare1(TIM14,value);  
  if(value>4000)
  {
   TIM_SetCompare1(TIM14,0);  //adc调节LED灯亮度
   TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
  }
 }
}

motor.h

#ifndef _motor_H
#define _motor_H
#include "system.h"
void MotorInit(void);
void Stop(void);
void Turnleft(void);
void Turnright(void);
void Turnback(void);
void Turnfront(void);
#endif

motor.c

#include "motor.h"
void MotorInit(void)
{
//初始化和使能单片机上的GPIO端口,保证可以正常给端口高低电平
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 GPIO_ResetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
}

//停止模式
void Stop(void)
{
 GPIO_ResetBits(GPIOB,GPIO_Pin_6);
 GPIO_ResetBits(GPIOB,GPIO_Pin_7);
 GPIO_ResetBits(GPIOB,GPIO_Pin_8);
 GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}

//左转模式 -> 左电机反转,右电机正转
void Turnleft(void)
{
 GPIO_SetBits(GPIOB,GPIO_Pin_6);
 GPIO_ResetBits(GPIOB,GPIO_Pin_7);
 GPIO_ResetBits(GPIOB,GPIO_Pin_8);
 GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
//右转模式 -> 左电机正转,右电机反转
void Turnright(void)
{
 GPIO_ResetBits(GPIOB,GPIO_Pin_6);
 GPIO_SetBits(GPIOB,GPIO_Pin_7);
 GPIO_SetBits(GPIOB,GPIO_Pin_8);
 GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}
//后退模式 -> 左电机反转,右电机反转
void Turnback(void)
{
 GPIO_ResetBits(GPIOB,GPIO_Pin_6);
 GPIO_SetBits(GPIOB,GPIO_Pin_7);
 GPIO_ResetBits(GPIOB,GPIO_Pin_8);
 GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
//前进模式 -> 左电机正转,右电机正转
void Turnfront(void)
{
 GPIO_SetBits(GPIOB,GPIO_Pin_6);
 GPIO_ResetBits(GPIOB,GPIO_Pin_7);
 GPIO_SetBits(GPIOB,GPIO_Pin_8);
 GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}

pwm.h

#ifndef _pwm_H
#define _pwm_H
#include "system.h"
void TIM10_CH1_CH3_PWM_Init(u16 per,u16 psc);
void TIM4_CH1_CH3_PWM_Init(u16 per,u16 psc);
void TIM14_CH1_PWM_Init(u16 per,u16 psc);
void Speed_1_Control(void);
void Speed_2_Control(void);
void Speed_3_Control(void);
void Speed_0_Control(void);
#endif

pwm.c

#include "pwm.h"
#include "SysTick.h"
#include "motor.h"

void TIM10_CH1_CH3_PWM_Init(u16 per,u16 psc)
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE);//使能TIM4时钟
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);

 GPIO_PinAFConfig(GPIOF,GPIO_PinSource6,GPIO_AF_TIM10);//管脚复用
 
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //复用输出模式
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//管脚设置
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度为100M
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体

 TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
 TIM_TimeBaseInit(TIM10,&TIM_TimeBaseInitStructure); 

 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
 TIM_OC1Init(TIM10,&TIM_OCInitStructure); //输出比较通道1初始化
 TIM_OC1PreloadConfig(TIM10,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器

 TIM_ARRPreloadConfig(TIM10,ENABLE);//使能预装载寄存器
 TIM_Cmd(TIM10,ENABLE); //使能定时器
 }

 void TIM4_CH1_CH3_PWM_Init(u16 per,u16 psc)
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
 GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);//管脚复用
 
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //复用输出模式
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;//管脚设置
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度为100M
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
 GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化结构体
 
 TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure); 

 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
 TIM_OC2Init(TIM4,&TIM_OCInitStructure); //输出比较通道1初始化
 TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器

 TIM_ARRPreloadConfig(TIM4,ENABLE);//使能预装载寄存器
 TIM_Cmd(TIM4,ENABLE); //使能定时器
}

void TIM14_CH1_PWM_Init(u16 per,u16 psc)
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//使能TIM14时钟
 
 GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//管脚复用
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //复用输出模式
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//管脚设置
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度为100M
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体
 
 
 TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
 TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure); 
 
 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
 TIM_OC1Init(TIM14,&TIM_OCInitStructure); //输出比较通道1初始化
 
 TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
 TIM_ARRPreloadConfig(TIM14,ENABLE);//使能预装载寄存器
 
 TIM_Cmd(TIM14,ENABLE); //使能定时器
}

void Speed_1_Control(void) //高速
{
 Turnfront();
 TIM_SetCompare1(TIM10,1);
 TIM_SetCompare2(TIM4,1);
}

 void Speed_2_Control(void) //中速
{
 Turnfront();
 TIM_SetCompare1(TIM10,150);
 TIM_SetCompare2(TIM4,150); 
}

void Speed_3_Control(void) //低速
{
 Turnfront();
 TIM_SetCompare1(TIM10,300);
 TIM_SetCompare2(TIM4,300);
}

void Speed_0_Control(void)  //一键加速
{
 u16 a=350;
 for(a=350;a>0;a--)
 {
  Turnfront();
  TIM_SetCompare1(TIM10,a);
  TIM_SetCompare2(TIM4,a);
  delay_ms(5);
 }
}

usart3.h

#ifndef _usart3_H
#define _usart3_H

#include "system.h"
void USART3_Init(u32 bound);

#endif

usart3.c

#include "usart3.h"
#include "led.h"
#include "beep.h"
#include "motor.h"
#include "SysTick.h"
#include "pwm.h"


void USART3_Init(u32 bound)
{
  GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟 
  
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3);
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_10;//管脚设置F9
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度为100M
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化结构体

  USART_InitStructure.USART_BaudRate=bound;
  USART_InitStructure.USART_WordLength=USART_WordLength_8b;
  USART_InitStructure.USART_StopBits=USART_StopBits_1;
  USART_InitStructure.USART_Parity=USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
  USART_Init(USART3,&USART_InitStructure);

  USART_Cmd(USART3,ENABLE);
  USART_ClearFlag(USART3,USART_FLAG_TC);
  USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void USART3_IRQHandler (void)
{
  u8 r;//r为手机串口APP发送给蓝牙模块的信息
  if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
  {
   USART_ClearITPendingBit(USART3, USART_IT_RXNE);   //清除 USART1 的中断待处理位
   r=USART_ReceiveData(USART3);
     if(r=='1')
      {
       Speed_0_Control();
       led2=0;
      }
     
     if(r=='2')
     {
      Turnfront();
      TIM_SetCompare1(TIM10,1);
      TIM_SetCompare2(TIM4,1);
      led2=1;
     }
     
     if(r=='3')
      {
       Speed_1_Control();
       
      }
     
     if(r=='4')
     {
      Turnleft();
      TIM_SetCompare1(TIM10,1);
      TIM_SetCompare2(TIM4,1);
      led2=1;
     }
     
     if(r=='5')
      {
       beep=0;
      }
     
     if(r=='6')
     {
      Turnright();
      TIM_SetCompare1(TIM10,1);
      TIM_SetCompare2(TIM4,1);
      led2=1;
     }
     
     if(r=='7')
      {
       Speed_2_Control();
      }
     
     if(r=='8')
     {
      Turnback();
      TIM_SetCompare1(TIM10,1);
      TIM_SetCompare2(TIM4,1);
      led2=1;
     }
     
     if(r=='9')
      {
       Speed_3_Control();
      }
      
     if(r=='0')
     {
      beep=1;
     }
     
     if(r=='a')
      {
       Stop();
       beep=0;
       delay_ms(100);
       beep=1;
      }  
  }
  
  USART_ClearFlag(USART3,USART_FLAG_TC);
}

time.h

#ifndef _time_H
#define _time_H
#include "system.h"
void TIM3_Init(u32 per,u16 psc);

#endif

time.c

#include "time.h"
#include "led.h"
#include "SysTick.h"

void TIM3_Init(u32 per,u16 psc)
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM4时钟
 
 TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
 
 TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE); //开启定时器中断
 TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
 
 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//定时器中断通道
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;  //子优先级
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
 NVIC_Init(&NVIC_InitStructure); 
 
 TIM_Cmd(TIM3,ENABLE); //使能定时器 
}

/*******************************************************************************
* 函 数 名         : TIM4_IRQHandler
* 函数功能     : TIM4中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void TIM3_IRQHandler(void)
{
 int i=0;
 if(TIM_GetITStatus(TIM3,TIM_IT_Update))
 {
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,DISABLE);//失能TIM3时钟
  for(i=0;i<3;i++)
  {
   TIM_SetCompare1(TIM14,0);  
   delay_ms(1000);
   TIM_SetCompare1(TIM14,4000);  
   delay_ms(1000);
  }
  TIM_SetCompare1(TIM14,0);  
  
 }
 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); 
}

led.h

#ifndef _led_H
#define _led_H

#include "system.h"

#define led1 PFout(9)
#define led2 PFout(10)
void LED_Init(void);

#endif

led.c

#include "led.h"

/*******************************************************************************
* 函 数 名         : LED_Init
* 函数功能     : LED初始化函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void LED_Init()
{
 GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //使能端口F时钟
 
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //输出模式
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//管脚设置F9
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度为100M
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体
 GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
}

beep.h

#ifndef _beep_H
#define _beep_H

#include "system.h"
#define BEEP_Pin (GPIO_Pin_8)  //定义BEEP管脚
#define BEEP_Port (GPIOF) //定义BEEP端口
#define beep PFout(8)  //BEEP PF8
void BEEP_Init(void);

#endif

beep.c

#include "beep.h"

/*******************************************************************************
* 函 数 名         : BEEP_Init
* 函数功能     : 蜂鸣器初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void BEEP_Init(void) 
{
 GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //使能端口F时钟
 
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //输出模式
 GPIO_InitStructure.GPIO_Pin=BEEP_Pin;//管脚设置F8
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度为100M
 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
 GPIO_Init(BEEP_Port,&GPIO_InitStructure); //初始化结构体
 
 GPIO_SetBits(BEEP_Port,BEEP_Pin); //关闭蜂鸣器
}
发布了1 篇原创文章 · 获赞 1 · 访问量 43

猜你喜欢

转载自blog.csdn.net/LLY_A_/article/details/104761538