基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)

今天我们一起来学习如何制作基于STM32F1系列的蓝牙小车
需要硬件:STM32开发板,HC-05蓝牙模块,四个电机和L298N电机驱动模块
分别介绍:

  • STM32F1系列开发板(我是用的是正点原子的mini开发板)
    基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第1张图片
    STM32mini开发板

  • HC-05模块
    大家在使用HC-05模块之前别忘了要配置AT指令,不然将无法进行串口通信
    配置方法:1:配置AT指令
    2:若1看不懂,可在这里查找

  • L298N的介绍:

  • L298N的图片如下:基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第2张图片
    因为我们要使用PWM模式,所以要去掉通道A,B上的跳帽线

**

OK,下来我们看看软件部分

:**
首先是主函数main:

#include "stm32f10x.h"
#include "dianji.h"
#include "delay.h"
#include
#include "sys.h"
#include

int main(void)
{
	uart_init(9600);	
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
	Motor_12_Config();
	delay_init();
	TIM4_PWM_Init(899,0);//PWM
	TIM3_PWM_Init(899,0);//PWM
	while(1)
{
	delay_ms(100);
}
}

电机部分:
电机头文件

#ifndef __MOTOR_H
#define __MOTOR_H
void Motor_12_Config(void);  
void Motor1_FORWARD(void);  
void Motor1_BACKWARD(void);
void Motor2_FORWARD(void);
void Motor2_BACKWARD(void);
#endif 

电机代码:

#include
#include
void Motor_12_Config(void)
{

  GPIO_InitTypeDef GPIO_InitStructure;   
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
  GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);         
}


	void Motor1_FORWARD() 
	{
		
	GPIO_ResetBits(GPIOA,GPIO_Pin_2); 
	GPIO_SetBits(GPIOA,GPIO_Pin_3);	
	}
	
	void Motor1_BACKWARD(void) 
	{
	GPIO_ResetBits(GPIOA,GPIO_Pin_3);
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
	
	}
	void Motor2_FORWARD()  
	{
		
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);
	GPIO_SetBits(GPIOA,GPIO_Pin_5);	
	}
	void Motor2_BACKWARD(void) 
	{
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	
	}
	

注:ResetBits 低 setBits ¸高
*PWM调速:
作为其中一个PWM通道
*另一个PWM通道
PWM头文件:

#ifndef __PWM_H
#define __PWM_H	 
#include "sys.h"
void TIM3_PWM_Init(u16 arr,u16 psc);
void TIM4_PWM_Init(u16 guo,u16 wen);
#endif

PWM代码:

#include "pwm.h"
#include


void TIM3_PWM_Init(u16 guo,u16 wen)   
{  
	 GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); 
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	TIM_TimeBaseStructure.TIM_Period = guo;
	TIM_TimeBaseStructure.TIM_Prescaler =wen; 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC1Init(TIM3, &TIM_OCInitStructure); 


	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  

	
	TIM_Cmd(TIM3, ENABLE);  
 
   
}

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

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); 	         
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); 
	                                                                     	

  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &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(TIM4, &TIM_TimeBaseStructure); 

 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC1Init(TIM4, &TIM_OCInitStructure);  


	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  
	

	
	TIM_Cmd(TIM4, ENABLE); 
 
   
}

串口通信:
头文件:

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" 

#define USART_REC_LEN  			
#define EN_USART1_RX 			
	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; 
extern u16 USART_RX_STA;         	

void uart_init(u32 bound);
#endif

串口通信代码部分:

#include "stm32f10x.h"
#include "dianji.h"
#include "delay.h"
#include
#include "sys.h"
#include

#if 1
#pragma import(__use_no_semihosting)             
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ    
_sys_exit(int x) 
{ 
	x = x; 
} 
//Öض¨Òåfputcº¯Êý 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

 
 
#if EN_USART1_RX   //Èç¹ûʹÄÜÁ˽ÓÊÕ
//´®¿Ú1ÖжϷþÎñ³ÌÐò
//×¢Òâ,¶ÁÈ¡USARTx->SRÄܱÜÃâĪÃûÆäÃîµÄ´íÎó   	
u8 USART_RX_BUF[USART_REC_LEN];     //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬	½ÓÊÕÍê³É±êÖ¾
//bit14£¬	½ÓÊÕµ½0x0d
//bit13~0£¬	½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART_RX_STA=0;       //½ÓÊÕ״̬±ê¼Ç	  
  
void uart_init(u32 bound){
  //GPIO¶Ë¿ÚÉèÖÃ
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//ʹÄÜUSART1£¬GPIOAʱÖÓ
  
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//¸´ÓÃÍÆÍìÊä³ö
  GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.9
   
  //USART1_RX	  GPIOA.10³õʼ»¯
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
  GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10  

  //Usart1 NVIC ÅäÖÃ
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//×ÓÓÅÏȼ¶3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQͨµÀʹÄÜ
	NVIC_Init(&NVIC_InitStructure);	//¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷
  
   //USART ³õʼ»¯ÉèÖÃ

	USART_InitStructure.USART_BaudRate = bound;//´®¿Ú²¨ÌØÂÊ
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
	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(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖжÏ
  USART_Cmd(USART1, ENABLE);                    //ʹÄÜ´®¿Ú1 

}
 u16 flag;
void USART1_IRQHandler(void)                	//´®¿Ú1ÖжϷþÎñ³ÌÐò
	{
			u8 Res;
			u16 speed=0;    
	    u8 dir=1;
		Motor_12_Config();
	delay_init();
	TIM3_PWM_Init(899,0);
	TIM4_PWM_Init(899,0);

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
		{
		Res =USART_ReceiveData(USART1);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
			
			if(Res==0x01)   //Ç°½ø
			{
		Motor1_BACKWARD();
    TIM_SetCompare1(TIM4,150); 
	   	Motor2_BACKWARD();
     TIM_SetCompare1(TIM3,150);
			}
			
				if(Res==0x02)   //ºóÍË
			{
		Motor1_FORWARD();
     TIM_SetCompare1(TIM4,150);
	  Motor2_FORWARD();
    TIM_SetCompare1(TIM3,150);
			}
			
							if(Res==0x03)   //×óת
			{
		Motor1_BACKWARD();
    TIM_SetCompare1(TIM4,150);	
	  Motor2_FORWARD();
    TIM_SetCompare1(TIM3,150);
			}
			
							if(Res==0x04)   //ÓÒת
			{
	    Motor1_FORWARD();
      TIM_SetCompare1(TIM4,150);
				Motor2_BACKWARD();
     TIM_SetCompare1(TIM3,150);
			}
			
				if(Res==0x05)   //Ç°½ø1
			{
		Motor1_BACKWARD();
    TIM_SetCompare1(TIM4,500); 
	   	Motor2_BACKWARD();
     TIM_SetCompare1(TIM3,500);
			}
			
				if(Res==0x06)   //Ç°½ø2
			{
	Motor1_BACKWARD();
    TIM_SetCompare1(TIM4,1); 
	   	Motor2_BACKWARD();
     TIM_SetCompare1(TIM3,1);
			}
			
			if(Res==0x07)   //Ç°½ø3
		{
	Motor1_BACKWARD();
	TIM_SetCompare1(TIM4,899); 
		Motor2_BACKWARD();
	 TIM_SetCompare1(TIM3,899);
		}
			
						if(Res==0x08)   //Öð²½¼ÓËÙ
				{
	//				delay_ms(100);
	//				speed--;
	//				if(speed==0)
	//				{
	//				speed=850;
	//				}
					for(speed=500;speed>100;speed--)
					{
			Motor1_BACKWARD();
			TIM_SetCompare1(TIM4,speed); 
				Motor2_BACKWARD();
			 TIM_SetCompare1(TIM3,speed);
				}
			}
				USART_ClearITPendingBit(USART1,USART_IT_RXNE);
		
 
     } 

} 

#endif	

至此,整个软件部分完成;

硬件连接:

电机连接 STM引脚
IN1 PA2
IN2 PA3
IN3 PA4
IN4 PA5
ENA PA6
ENB PB6

HC-05模块根据其引脚与PA10,PA9接,这里不再重复。
然后上电,连接蓝牙,连接蓝牙APP软件(推荐使用(蓝牙串口 bluespp))
基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第3张图片

打开后连接HC-05模块:
基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第4张图片
注:难以连接上蓝牙的原因:
1.外接电源电量不足,蓝牙时断时续
2.接线错误
3.AT指令配对有问题(要9600的波特率)
4.蓝牙可能坏了。。。(这个机率比较低)去这吧,小伙子
5.手机与APP还有模块不兼容(比如IOS系统)
接下来在APP上设置返回值:
基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第5张图片
基于STM32F1系列的蓝牙小车(可调速,调速使用PWM)_第6张图片

设置成功后,连接蓝牙,上电。
至此,基于STM32F1系列的蓝牙小车制作完毕。

你可能感兴趣的:(STM32)