赞
踩
程序只要按照上面的连接都是可以直接使用,如果硬件有改动我也有定义宏可以直接做更改。
代码里面的注释比较详细,这里只是将重要的代码放上来,稍作讲解,最好是直接下载来看。
下载地址,提取码:qsmu
#include "stm32f10x.h" // Device header #include "MTR_GPIO.h" #include "USART.h" #include "LED.h" #include "blueTooth.h" #include "PWM_GeneralTim.h" int main(void){ USART_Config();//串口 MTR_GPIOInit();//电机引脚 GENERAL_TIM_Init();//定时器PWM初始化,用于小车转向 blueToothInit();//蓝牙初始化 LEDInit(); printf("-----指令-----\n\ 0x01:小车后退\n\ 0x02:小车向左\n\ 0x03:小车向右\n\ 0x04:小车前进\n\ 0x05:小车刹车\n\ 0x06:电机停止\n\ 0x07:小车逆时针\n\ 0x08:小车转向停止\n\ 0x09:小车顺时针\n"); while(1){ //如果蓝牙断开,小车会一直在刹车状态 if(BLUE_TOOTH_STATE != Bit_SET){ MTR_CarBrakeAll(); } } }
void DEBUG_USART_IRQHandler(void){ uint8_t CMD = 0;//接收的命令 if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET){ LED1_ON; CMD = USART_ReceiveData(DEBUG_USARTx);//读取一个 switch(CMD){ case 0x06: //电机停止 MTR_CarBrakeAll(); printf("0x06"); break; case 0x08: //小车转向停止 PWM_CarMaxGo(); printf("0x08"); break; case 0x05: //小车刹车 MTR_CarBrakeAll(); printf("0x05"); break; case 0x02: //小车向左 PWM_CarLeft(); printf("0x02"); break; case 0x03: //小车向右 PWM_CarRight(); printf("0x03"); break; case 0x04: //小车前进 MTR_CarGo(); printf("0x04"); break; case 0x01: //小车后退 MTR_CarBackGo(); printf("0x01"); break; case 0x07: //小车逆时针 MTR_CarCCW(); printf("0x07"); break; case 0x09: //小车顺时针 MTR_CarCW(); printf("0x09"); break; } LED1_OFF;//让LED闪烁来表示数据的接收 } USART_ClearFlag(DEBUG_USARTx,USART_FLAG_RXNE); }
#include "MTR_GPIO.h" //刹车 void MTR_CarBrakeAll(void){ MTR1_BRAKE; MTR2_BRAKE; MTR3_BRAKE; MTR4_BRAKE; } //前进 void MTR_CarGo(void){ MTR1_CW; MTR2_CW; MTR3_CCW; MTR4_CCW; } //后退 void MTR_CarBackGo(void){ MTR1_CCW; MTR2_CCW; MTR3_CW; MTR4_CW; } //顺时针 void MTR_CarCW(void){ MTR1_CCW; MTR2_CCW; MTR3_CCW; MTR4_CCW; } //逆时针 void MTR_CarCCW(void){ MTR1_CW; MTR2_CW; MTR3_CW; MTR4_CW; } void MTR_GPIOInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(MTR1_GPIO_CLK|MTR2_GPIO_CLK|MTR3_GPIO_CLK|MTR4_GPIO_CLK,ENABLE);//时钟 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 //电机1 GPIO_InitStructure.GPIO_Pin = MTR1_GPIO_PIN; GPIO_Init(MTR1_GPIO_PORT, &GPIO_InitStructure); //电机2 GPIO_InitStructure.GPIO_Pin = MTR2_GPIO_PIN; GPIO_Init(MTR2_GPIO_PORT, &GPIO_InitStructure); //电机3 GPIO_InitStructure.GPIO_Pin = MTR3_GPIO_PIN; GPIO_Init(MTR3_GPIO_PORT, &GPIO_InitStructure); //电机4 GPIO_InitStructure.GPIO_Pin = MTR4_GPIO_PIN; GPIO_Init(MTR4_GPIO_PORT, &GPIO_InitStructure); //小车刹车 MTR_CarBrakeAll(); }
注意:因为单片机是控制驱动板从而间接的控制电机,为了简单我直接把控制驱动板的引脚看成是控制电机的。
#ifndef __MTR_GPIO_H #define __MTR_GPIO_H #include "stm32f10x.h" /* 小车四轮驱动 电机1:右上 电机2:右下 电机3:左上 电机4:左下 */ #define MTR1_GPIO_PORT GPIOB #define MTR1_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR1_GPIO_PIN GPIO_Pin_6|GPIO_Pin_7 #define MTR1_CW {GPIO_ResetBits(MTR1_GPIO_PORT,GPIO_Pin_6);GPIO_SetBits(MTR1_GPIO_PORT,GPIO_Pin_7);}//顺时针 #define MTR1_CCW {GPIO_SetBits(MTR1_GPIO_PORT,GPIO_Pin_6);GPIO_ResetBits(MTR1_GPIO_PORT,GPIO_Pin_7);}//逆时针 #define MTR1_BRAKE GPIO_ResetBits(MTR1_GPIO_PORT,MTR1_GPIO_PIN); #define MTR2_GPIO_PORT GPIOB #define MTR2_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR2_GPIO_PIN GPIO_Pin_8|GPIO_Pin_9 #define MTR2_CW {GPIO_ResetBits(MTR2_GPIO_PORT,GPIO_Pin_8);GPIO_SetBits(MTR2_GPIO_PORT,GPIO_Pin_9);}//顺时针 #define MTR2_CCW {GPIO_SetBits(MTR2_GPIO_PORT,GPIO_Pin_8);GPIO_ResetBits(MTR2_GPIO_PORT,GPIO_Pin_9);}//逆时针 #define MTR2_BRAKE GPIO_ResetBits(MTR2_GPIO_PORT,MTR2_GPIO_PIN); #define MTR3_GPIO_PORT GPIOB #define MTR3_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR3_GPIO_PIN GPIO_Pin_12|GPIO_Pin_13 #define MTR3_CW {GPIO_ResetBits(MTR3_GPIO_PORT,GPIO_Pin_12);GPIO_SetBits(MTR3_GPIO_PORT,GPIO_Pin_13);}//顺时针 #define MTR3_CCW {GPIO_SetBits(MTR3_GPIO_PORT,GPIO_Pin_12);GPIO_ResetBits(MTR3_GPIO_PORT,GPIO_Pin_13);}//逆时针 #define MTR3_BRAKE GPIO_ResetBits(MTR3_GPIO_PORT,MTR3_GPIO_PIN); #define MTR4_GPIO_PORT GPIOB #define MTR4_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR4_GPIO_PIN GPIO_Pin_14|GPIO_Pin_15 #define MTR4_CW {GPIO_ResetBits(MTR4_GPIO_PORT,GPIO_Pin_14);GPIO_SetBits(MTR4_GPIO_PORT,GPIO_Pin_15);}//顺时针 #define MTR4_CCW {GPIO_SetBits(MTR4_GPIO_PORT,GPIO_Pin_14);GPIO_ResetBits(MTR4_GPIO_PORT,GPIO_Pin_15);}//逆时针 #define MTR4_BRAKE GPIO_ResetBits(MTR4_GPIO_PORT,MTR4_GPIO_PIN); void MTR_CarBrakeAll(void); //小车刹车 void MTR_CarGo(void); //小车前进 void MTR_CarBackGo(void); //小车后退 void MTR_CarCW(void); //小车顺时针转 void MTR_CarCCW(void); //小车逆时针转 void MTR_GPIOInit(void); #endif
#include "PWM_GeneralTim.h" static void GENERAL_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 输出比较通道1 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure); // 输出比较通道2 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH2_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH2_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure); // 输出比较通道3 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH3_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH3_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH3_PORT, &GPIO_InitStructure); // 输出比较通道4 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH4_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH4_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure); } ///* // * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有 // * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可, // * 另外三个成员是通用定时器和高级定时器才有. // *----------------------------------------------------------------------------- // *typedef struct // *{ TIM_Prescaler 都有 // * TIM_CounterMode TIMx,x[6,7]没有,其他都有 // * TIM_Period 都有 // * TIM_ClockDivision TIMx,x[6,7]没有,其他都有 // * TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有 // *}TIM_TimeBaseInitTypeDef; // *----------------------------------------------------------------------------- // */ /* ---------------- PWM信号 周期和占空比的计算--------------- */ // ARR :自动重装载寄存器的值 // CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 72M/(psc+1) // PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M // 占空比P=CCR/(ARR+1) static void GENERAL_TIM_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 开启定时器时钟,即内部时钟CK_INT=72M GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE); /*--------------------时基结构体初始化-------------------------*/ // 配置周期 // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断 TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period; // 驱动CNT计数器的时钟 = Fck_int/(psc+1) TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler; // 时钟分频因子 ,配置死区时间时需要用到 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 计数器计数模式,设置为向上计数 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重复计数器的值,没用到不用管 TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // 初始化定时器 TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure); /*--------------------输出比较结构体初始化-------------------*/ // 配置为PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // 输出使能 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出通道电平极性配置 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出比较通道 1 TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // 输出比较通道 2 TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // 输出比较通道 3 TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // 输出比较通道 4 TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // 使能计数器 TIM_Cmd(GENERAL_TIM, ENABLE); } void GENERAL_TIM_Init(void) { GENERAL_TIM_GPIO_Config(); GENERAL_TIM_Mode_Config(); } //小车左转 void PWM_CarLeft(void){ TIM_SetCompare1(GENERAL_TIM,0); TIM_SetCompare2(GENERAL_TIM,0); TIM_SetCompare3(GENERAL_TIM,4000); TIM_SetCompare4(GENERAL_TIM,4000); } //小车右转 void PWM_CarRight(void){ TIM_SetCompare1(GENERAL_TIM,4000); TIM_SetCompare2(GENERAL_TIM,4000); TIM_SetCompare3(GENERAL_TIM,0); TIM_SetCompare4(GENERAL_TIM,0); } //小车最大速度 void PWM_CarMaxGo(void){ TIM_SetCompare1(GENERAL_TIM,0); TIM_SetCompare2(GENERAL_TIM,0); TIM_SetCompare3(GENERAL_TIM,0); TIM_SetCompare4(GENERAL_TIM,0); } /*********************************************END OF FILE**********************/
PS:完整的程序太多了,最好下载下来慢慢看。
做到这里就剩只蓝牙遥控器的配置了,软件呢随便哪个都行,只要能收发数据就行。
不过我推荐用我这个,因为长得好看。
下载地址,提取码:kvar。此软件为安卓,ios没有
printf("-----指令-----\n
0x01:小车后退\n
0x02:小车向左\n
0x03:小车向右\n
0x04:小车前进\n
0x05:小车刹车\n
0x06:电机停止\n
0x07:小车逆时针\n
0x08:小车转向停止\n
0x09:小车顺时针\n");
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。