前言
这是笔者第一次尝试在CSDN这个平台上编写文章,主要是想借此来记录一下自己做过的一些小项目,算是为生活添加乐趣叭~(^&^)
本文介绍的是基于STM32的蓝牙遥控避障小车,其主要实现两个功能,分别为遥控模式以及自主避障模式。
提示:以下是本篇文章正文内容,下面案例可供参考
一、组成部件及功能介绍
1.采用STM32F103系列为主控芯片
2.采用C-SR04超声波模块避障。
- SR04超声波测距模块可提供约2cm到400厘米的非接触式距离感测功能,测距精度可达高到3毫米;模块包括超声波发射器,接收器与控制电路像智能小车的测距以及转向,或是一些项目中,常常会用到。智能小车测距可以及时发现前方的障碍物,使智能小车可以及时转向,避开障碍物。给超声波模块接入电源和地给脉冲触发引脚(trig)输入一个长为20us的高电平方波输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;当超声波返回被模块接收到时,回波引脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长根据声音中的速度为344米/秒,即可计算出所测的距离。
在一些初始化函数调用后,对Echo的引脚进行测量。倘若改引脚变为高,则是开始推测。当它变成0的时候,则是探测结束。之后对于时间进行计算便可以得到距离。
3.采用HC-05蓝牙模块进行远程遥控控制小车的行进方向。
此模块实现了无线电远距离控制小车的停启、方向行驶的功能,在整个小车系统中起到不可忽视的作用。
无线遥控工作原理
此蓝牙的型号是HC-05
工作简化图如下:
HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式(AT)和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。
模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;
PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。
在蓝牙模块中有一个小按键,按一下就置高一次PIO11。也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。
在蓝牙模块上有灯,当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。
配置好相应的PWM后,直接通过手机蓝牙与他相接,通过相应的软件进行调节发送指令,单片机通过串口会得到指令,产生相应的动作。
HC-05的状态现象很明显,操作也很方便。
4.采用SG90舵机辅助超声波模块进行转向避障
选择使用SG90舵机,其性能强且不易于损坏。而且舵机本身十分轻巧方便组装,能够实现0~180度范围的转向。
舵机是一种根据输入PWM信号占空比来控制输出角度的装置输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms。通过输入不同占空比的PWM来控制舵机的不同转向角度,从而带动超声波模块旋转以实现避障功能。
二、代码实列
1.main函数
主函数里面其实主要就做了一个事情,那就是在while(1)中不断判断串口传来的数据是多少,小车再通过传过来的数据来具体做出对应的判断
#include "stm32f10x.h" // Device header
#include "oled.h"
#include "timer.h"
#include "DELAY.h"
#include "YunTai.h"
#include "Dianji.h"
#include "CaoSenBo.h"
#include "USART.h"
int g_USART1_FLAG = 0; //蓝牙标志位
int Mode = 0; //模式标志位
extern int dis;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Dianji_Init();
OLED_Init();
OLED_Clear();
//SR04_GPIO_Init(); // Trign PC10
ultrasonic_Init();
Init_TIM5_PWM(19999 ,71);//云台
Init_TIM8_PWM(899,7);//电机
uart_init(115200); //蓝牙
TIME3_Init();//超声波
//TIM2_Cap_Init(0XFFFF,72-1);//以1MHZ的频率计数
SERVO_SetAng(90);
while(1)
{
if(Mode == 1) //避障模式
{
HC_SR04_Avoid();
OLED_ShowNum(1,1,dis,3);
}
if(Mode == 2)//遥控模式
{
SERVO_SetAng(90);
if(g_USART1_FLAG == 1)
{
run(); //前进
g_USART1_FLAG = 0;
}
if(g_USART1_FLAG == 2)
{
Retreat(); //后退
g_USART1_FLAG = 0;
}
if(g_USART1_FLAG == 3)
{
go_left(); //左转
g_USART1_FLAG = 0;
}
if(g_USART1_FLAG == 4)
{
go_right(); //右转
g_USART1_FLAG = 0;
}
if(g_USART1_FLAG ==5)
{
Stop(); //停车
g_USART1_FLAG = 0;
}
}
}
}
2.定时器初始化
#include "stm32f10x.h" // Device header
#include "sys.h"
void Init_TIM5_PWM(u16 arr ,u16 psc) //云台即舵机
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_InternalClockConfig(TIM5);
TIM_TimeBaseInitTypeDef TIM_TimrBaseInitStructure;
TIM_TimrBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimrBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimrBaseInitStructure.TIM_Period = arr ;
TIM_TimrBaseInitStructure.TIM_Prescaler = psc;
TIM_TimrBaseInitStructure.TIM_RepetitionCounter = 0 ;
TIM_TimeBaseInit(TIM5, &TIM_TimrBaseInitStructure);
TIM_ClearFlag(TIM5, TIM_FLAG_Update);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure); //为了避免因部分结构体成员未赋初使值而导致可能的错误,这里先将结构体赋初值,再改变部分结构体成员的值就行了
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //设置输出比较的模式
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置输出比较的极性,这里是极性不翻转
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //设置输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //用于设置CCR
TIM_OC4Init(TIM5, &TIM_OCInitStructure);
//TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM5, ENABLE);
}
void Init_TIM8_PWM(u16 arr, u16 psc) //电机
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH1 ----A PC6
TIM_OC2Init(TIM8, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH2 ----B PC7
TIM_OC3Init(TIM8, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH3 ----C PC8
TIM_OC4Init(TIM8, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH4 ----D PC9
TIM_CtrlPWMOutputs(TIM8, ENABLE);
TIM_ARRPreloadConfig(TIM8, ENABLE);
TIM_Cmd(TIM8, ENABLE);
TIM_SetCompare1(TIM8, 0); // BL
TIM_SetCompare2(TIM8, 0); // FL
TIM_SetCompare3(TIM8, 0); // FR
TIM_SetCompare4(TIM8, 0); // BR
}
void TIME3_Init(void) //超声波
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseInitStructure.TIM_Period=99; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=17; //PSC
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_ClockDivision=1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
}
//下面注释的部分是我尝试用定时器输入捕获的方式来运行超声波
//结果发现效果并不理想就放弃了
//TIM_ICInitTypeDef TIM2_ICInitStructure;
//void TIM2_Cap_Init(u16 arr,u16 psc) //超声波
//{
// GPIO_InitTypeDef GPIO_InitStructure;
// TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
// GPIO_ResetBits(GPIOA,GPIO_Pin_2);
//
//
// TIM_TimeBaseStructure.TIM_Period = arr;
// TIM_TimeBaseStructure.TIM_Prescaler =psc;
// TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
// TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
// TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//
// TIM2_ICInitStructure.TIM_Channel = TIM_Channel_3;
// TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
// TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// TIM2_ICInitStructure.TIM_ICFilter = 0x00;
// TIM_ICInit(TIM2, &TIM2_ICInitStructure);
//
//
// NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//
// TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC3,ENABLE);
//
// TIM_Cmd(TIM2,ENABLE );
//}
//u8 TIM5CH1_CAPTURE_STA=0;
//u16 TIM5CH1_CAPTURE_VAL;
//
//
//void TIM2_IRQHandler(void)
//{
// if((TIM5CH1_CAPTURE_STA&0X80)==0)
// {
// if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
//
// {
// 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(TIM2, TIM_IT_CC3) != RESET)
// {
// if(TIM5CH1_CAPTURE_STA&0X40)
// {
// TIM5CH1_CAPTURE_STA|=0X80;
// TIM5CH1_CAPTURE_VAL=TIM_GetCapture3(TIM2);
// TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
// }else
// {
// TIM5CH1_CAPTURE_STA=0;
// TIM5CH1_CAPTURE_VAL=0;
// TIM_SetCounter(TIM2,0);
// TIM5CH1_CAPTURE_STA|=0X40;
// TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);
// }
// }
// }
//
// TIM_ClearITPendingBit(TIM2, TIM_IT_CC3|TIM_IT_Update);
//
//}
3.串口部分
串口部分只需要再其数据接收部分添加对接收信号的判断并赋值就行了,其他的程序可以参考引用正点原子关于串口部分的模板
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(数据必须是0xod 0xoa结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if(Res == 'A') g_USART1_FLAG = 1;//前进
if(Res == 'B') g_USART1_FLAG = 2;//后退
if(Res == 'C') g_USART1_FLAG = 3;//左
if(Res == 'D') g_USART1_FLAG = 4;//右
if(Res == 'E') g_USART1_FLAG = 5;//停
if(Res == 'F') Mode = 1;//打开避障模式
if(Res == 'G') Mode = 2;//打开遥控模式
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没接收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//如果SYSTEM_SUPPORT_OS为真,则需要支持OS
}
}
}
}
4.超声波部分
#include "stm32f10x.h" // Device header
#include "CaoSenBo.h"
#include "timer.h"
#include "oled.h"
#include "Dianji.h"
#include "YunTai.h"
#include "DELAY.h"
int time = 0;
unsigned int delay_u;;
int Count = 0;
int Distance0 = 0;
int Distance1 = 0;
int dis = 0;
//extern u8 TIM5CH1_CAPTURE_STA; //??????
//extern u16 TIM5CH1_CAPTURE_VAL; //?????
//void SR04_GPIO_Init(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure;
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12; //trio
// GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
// GPIO_Init(GPIOC,&GPIO_InitStructure);
//
// GPIO_SetBits(GPIOC,GPIO_Pin_0);
//}
//int SR04_Distance(void)
//{
// Trign = 0;
// Delay(13);
// Trign = 1;
//
// if(TIM5CH1_CAPTURE_STA&0X80)
// {
// time=TIM5CH1_CAPTURE_STA&0X3F;
// time*=65536;
// time+=TIM5CH1_CAPTURE_VAL;
// Distance = time*0.034/2;
// //printf("HIGH:%d us\r\n",time);
// TIM5CH1_CAPTURE_STA=0;
// }
// return Distance;
//}
//上面注释掉的这段是原本用输入捕获方式来运行的程序
void ultrasonic_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12; //trio
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; //echo
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}
int GetDistance(void)
{
int i;
for(i=5;i>0;i--) //循环6次采集距离
{
GPIO_ResetBits(GPIOC,GPIO_Pin_12);
GPIO_SetBits(GPIOC,GPIO_Pin_12); //拉高trig
Delay(13); //保持10us
GPIO_ResetBits(GPIOC,GPIO_Pin_12); //拉低trig
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==0); //等待echo管脚输出高电平后打开TIM3计时
TIM_Cmd(TIM3,ENABLE); //打开TIM3,捕获时间
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==1); //等待声音信号结束
TIM_Cmd(TIM3,DISABLE); //关闭TIM3
Count=TIM_GetCounter(TIM3); //获取TIM3的该次计数值,即读取TIM3寄存器CNT
Distance0=calculer(Count); //调用函数计算距离
Distance1=Distance1+Distance0; //距离的累加,用于后续计算平均距离
}
Distance1=Distance1/6; //平均距离
return Distance1;
}
u32 calculer(u32 count)
{
u32 Distance;
Distance=((float)(count+100*time)*0.425)/100; //距离计算公式
time=0; //清空TIM3的中断次数
return Distance;
}
void TIM3_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_Update)!=RESET)
{
time++; //中断标志自加1
TIM_ClearFlag(TIM3,TIM_FLAG_Update); //清楚中断标志位
}
}
void HC_SR04_Avoid(void) //根据距离来进行转向判断
{
dis = GetDistance();
if(dis>60)
{
run();
}
else if(dis<40)
{
Stop();
Delay_ms(1000);
SERVO_SetAng(180); //此为舵机角度函数
Delay_ms(1000);
dis = GetDistance();
if(dis>=60)
{
go_left();
Delay_ms(625);
SERVO_SetAng(90);
Delay_ms(20);
run();
}
else if(dis<60)
{
SERVO_SetAng(0);
Delay_ms(20);
go_right();
Delay_ms(625);
SERVO_SetAng(90);
Delay_ms(20);
run();
}
}
}
5.舵机
#include "stm32f10x.h" // Device header
void SERVO_SetAng(float Angle)
{
TIM_SetCompare4(TIM5, Angle/180*2000+500);
}
6.电机转向
#include "stm32f10x.h" // Device header
#include "timer.h"
void Dianji_Init(void)//电机初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Mhz速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Mhz速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
}
void run(void)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
GPIO_SetBits(GPIOB, GPIO_Pin_3); //左轮
TIM_SetCompare1(TIM8, 600); // 右
TIM_SetCompare2(TIM8, 610); // 左
}
void go_left(void)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
GPIO_ResetBits(GPIOB, GPIO_Pin_3); //左轮
TIM_SetCompare1(TIM8, 500); // 右
TIM_SetCompare2(TIM8, 500); // 左
}
void go_right(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_2); //右轮
GPIO_SetBits(GPIOB, GPIO_Pin_3); //左轮
TIM_SetCompare1(TIM8, 500); // 右
TIM_SetCompare2(TIM8, 500); // 左
}
void Stop(void)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
GPIO_SetBits(GPIOB, GPIO_Pin_3); //左轮
TIM_SetCompare1(TIM8, 0); // 右
TIM_SetCompare2(TIM8, 0); // 左
}
void Retreat(void) //后退
{
GPIO_SetBits(GPIOB, GPIO_Pin_2); //右轮
GPIO_ResetBits(GPIOB, GPIO_Pin_3); //左轮
TIM_SetCompare1(TIM8, 545); // 右
TIM_SetCompare2(TIM8, 550); // 左
}
以上便是代码部分的内容了(^^)
三、实物展示
注:这里用来连接蓝牙的手机软件随便在网上就可以找到的。
总结
以上便是这篇文章的全部内容啦!呼~想不到还是有些累的(**)
笔者在这里也是想对看到这篇文章的朋友说几句话,或许你现在正因为各种程序呀电路呀等等等等。。问题所困扰,请一定不要着急,慢慢来仔细想,冷静面对问题才能将其迎刃而解哦!!
收工!