基于STM32F103系列的蓝牙控制小车以及PWM调速
代码下载
使用蓝牙模块前,需要先对其进行一些设置:
使用USB转TTL模块将蓝牙模块连接到电脑,蓝牙RX连接USB-TTL的TX;蓝牙TX接UCB-TTLRX;VCC接5V,GND接GND。这样就可以使用串口与蓝牙进行通讯,通过串口发送AT指令对蓝牙进行一些设置。
打开串口调试软件,蓝牙模块默认的波特率为9600,在串口助手中将波特率设置为9600,其他几项默认就可以。
打开串口,发送“AT”,如果蓝牙没有问题,应该就会返回“OK”。此时就可以对蓝牙的波特率、名字、配对密码等进行设置了。
串口调试助手
一般我们用的波特率为115200,发送“AT+BAUD8”,返回“OK”,此时波特率就设置完成了。如果想设置成其他的波特率修改“AT+BAUD8”中的编号“8”就可以了。编号对应波特率如下:1–1200 2–2400 3–4800 4-9600 5–19200 6–38400 7–57600 8–115200 9–230400 A–460800 B–921600 C–1382400
发送:AT+NAMEname,“name”就是想要设置的蓝牙名称,接着发送“AT+RESET”指令,让蓝牙模块重启,就可以在手机或者电脑上搜到你的蓝牙了。
设置配对密码
一般我们使用默认配对密码,默认密码为1234或者0000。但是如果你想设置成其他的配对密码,发送“AT+PINpassword”,“password”为想要设置的密码。至此就完成了蓝牙模块的基本设置,就可以使用手机或者电脑连接蓝牙了。但是想要给蓝牙模块发送消息还需要一个蓝牙串口软件。
先打开手机设置,将蓝牙模块和手机进行配对,然后打开蓝牙串口软件,点击右上角连接到蓝牙模块。连接成功后就可以用手机给蓝牙发送消息了,蓝牙接受到消息后通过串口再将消息发送到电脑上电脑也可以通过蓝牙发送消息到手机上,实现手机电脑的无线通信。
手机串口软件
而遥控小车只是将电脑换成了STM32单片机,通过手机发送指令数据,单片机接收到指令数据就执行指定的程序。通过配置STM32的USART串口与蓝牙模块通信就可以接受数据了。
GPIO_InitTypeDef GPIO_InitStrue; //定义结构体变量
USART_InitTypeDef USART_InitStrue;
NVIC_InitTypeDef NVIC_InitStrue;
//打开各个外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
//usart3的RX与TX引脚配置
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_InitStrue);
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_InitStrue);
USART_InitStrue.USART_BaudRate=115200; //波特率设置与蓝牙一样
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; 无硬件数据流控制
USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//收发模式
USART_InitStrue.USART_Parity=USART_Parity_No; //无奇偶校验位
USART_InitStrue.USART_StopBits=USART_StopBits_1; //一个停止位
USART_InitStrue.USART_WordLength=USART_WordLength_8b; //字长为8位数据格式
USART_Init(USART3,&USART_InitStrue); //初始化
USART_Cmd(USART3,ENABLE);//使能
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//串口中断使能
NVIC_InitStrue.NVIC_IRQChannel=USART3_IRQn; //中断通道选择
NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE; //通道使能
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级
NVIC_InitStrue.NVIC_IRQChannelSubPriority=1; //子优先级
NVIC_Init(&NVIC_InitStrue);
void USART3_IRQHandler(void) //串口3中断服务程序
{
if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET) //接受标志位
{
res= USART_ReceiveData(USART3);//将接收到的数据保存到变量res
USART_SendData(USART3,res); //发送接收到的数据验证是否发送成功
}
}
这样就完成了STM32的串口设置,将蓝牙模块的RX,TX,与PB11,PB10连接,再用手机发送消息到蓝牙,如果手机接收到了发送的消息就表明配置成功。
想要驱动电机,必须得有一个电机驱动器,我这里用的是L298N
逻辑输入接口:左边两个控制输出A,输入00则电机不转,输入10正转,输入01反转。输出B同理。如果想要电机左转或者右转,只需让电机一边正转,一边反转即可。
供电:采用12V的电源接12V供电接口和GND;5V供电可以输出5V的电压,可以用此接口接单片机的VCC,GND接单片机的GND。
调速:如果想要对电机调速,通道A和通道B的跳线帽拿下来,使能口接PWM波即可
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
电机驱动的逻辑输入接口分别接PA4、PA5、PA3、PA8。
void motor_f(void)
{
M1=1;
M2=0;
M3=1;
M4=0;
}
void motor_b(void)
{
M1=0;
M2=1;
M3=0;
M4=1;
}
void motor_r(void)
{
M1=1;
M2=0;
M3=0;
M4=1;
}
void motor_l(void)
{
M1=0;
M2=1;
M3=1;
M4=0;
}
void motor_s(void)
{
M1=0;
M2=0;
M3=0;
M4=0;
}
void motor_control(void)
{
if(res=='5')motor_s();//接收到数据5停止
else if (res=='1')motor_b();//接收到1后退
else if(res=='2')motor_f();//接收到2前进
else if(res=='3')motor_l();//接收到3左转
else if(res=='4')motor_r();//接收到4右转
}
利用手机发送指定指令的数据就可以控制小车的前进,后退,左转,右转了。
如果想要对小车调速,可以使用STM32输出PWM来调速。
采用STM32F103的TIM输出两路可调占空比的PWM来进行电机调速
TIM3配置
void TIM3_CH1_PWM_Init(u16 per,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
// 配置GPIO的模式和IO口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&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(TIM3,&TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;//PWM2模式
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//极性低
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出通道使能
TIM_OC1Init(TIM3,&TIM_OCInitStructure); //输出比较通道1初始化
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC2Init(TIM3,&TIM_OCInitStructure); //输出比较通道2初始化
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器
TIM_Cmd(TIM3,ENABLE); //使能定时器
}
配置好 per和psc值后调用 TIM_SetCompare1(TIM3,xxx)和
TIM_SetCompare2(TIM3,xxx)函数就可以输出PWM波了;通过调整xxx的值来调整占空比实现对电机的调速。
整个工程文件