基于STM32 Cortex-M3内核F103制作的智能小车项目

目录

一.简单介绍:

二.硬件支持:

三.软件部分介绍:

四.整体调试:

五.学习总结:

一.简单介绍:

      花上一周的时间制作一个智能小车玩玩吧,一直想要制作一辆自己的智能小车,看多了网上的各种小车,有循迹的,超声波的,蓝牙的,还有WIFI的,总之是各种各样。看别人做自己也想亲手制作一辆。网上的小车动则好几百,少则也得百来块钱,对于初学者真的很不友好。

     怎样花费最少的钱,来制作想要的东西成为了今天的话题,今天就让我来带你用最少的资金最喜欢的小车车。话不多说,先上成品:

基于STM32 Cortex-M3内核F103制作的智能小车项目_第1张图片

二.硬件支持:

一.购买元器件

1.底盘:看到这里大家一定很好奇,这是什么地盘。相信自己的眼睛,那就是一次性筷子粘合在一起的地盘,虽然简陋,但我感觉跟花上20元买的亚克力没有太大区别。

2.直流电机:四个差不多10元。

3.L298N:直流电机驱动模块,可以同时驱动两路电机,我这里一路接了两个电机,一个L298N的驱动能力完全可以带动四个电机,4元。相比于已经停产TB6612要便宜很多。

4.蓝牙模块HC-05:用于手机上位机与小车通信,实现远程遥控,15元

5.超声波模块HC-SR04:用于小车避障功能,3元

6.SG90舵机:这里选择-90°~90°就可以满足条件了,4元

7.0.96寸OLED显示屏:用于显示当前距离,还有模式的切换,6元

8.STM32c8t6:主控芯片,便宜又好用,15元

9.一些电子元器件:几块钱解决

二.绘制PCB电路板

基于STM32 Cortex-M3内核F103制作的智能小车项目_第2张图片

 智能小车原理图

     

基于STM32 Cortex-M3内核F103制作的智能小车项目_第3张图片

 3D主板模型

三.软件部分介绍:

软件部分是基于HAL库来编写的,我也是刚接触不久HAL库,因为ST官方现在主推的HAL库,所以作为一名合格的码农,应该紧跟时代发展。HAL库确实方便了程序的开发,以前需要花费大量的时间在写初始化配置上,现在有了这个工具(CUBEMX)可以说是拿到了程序的句柄,把更多的时间用在实现功能上,大大缩短了开发周期。下面就跟着我的步伐开始配置工程。

1.使能RCC外部高速时钟与低速时钟

基于STM32 Cortex-M3内核F103制作的智能小车项目_第4张图片

 2.将时钟倍频至72MHZ 

基于STM32 Cortex-M3内核F103制作的智能小车项目_第5张图片

3.在SYS中选择Debug->Serial Wire,这一步的配置是为了在下载的时候自动复位,一定要选择,不然很麻烦,我是使用的ST-link烧写器

基于STM32 Cortex-M3内核F103制作的智能小车项目_第6张图片

 4.首先给L298N配置参数,需要两路PWM用于电机调速,CH1,与CH2。还需要四个IO口用于控制电机正反转跟停止,将GPIO设置为推挽模式,参数配置如图。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第7张图片

 基于STM32 Cortex-M3内核F103制作的智能小车项目_第8张图片

5 .将定时器1设置为驱动舵机的PWM信号,配置如下:

基于STM32 Cortex-M3内核F103制作的智能小车项目_第9张图片

 6.将定时器3设置为超声波测距的时钟,配置如下:

这边的配置很关键,一定要将预分频设置为71,主计数器为最大值,用于超声波的定时模式,否则会有错误。 

基于STM32 Cortex-M3内核F103制作的智能小车项目_第10张图片

7.配置定时器4为20ms中断一次,用于不间断的显示OLED上面的信息。防止频闪。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第11张图片

8.这样所有的定时器都设置完成了。还有驱动OLED的引脚没有设置,我们继续配置引脚。这里我使用的是0.96寸OLED,四根线的,也就是iic总线。iic总线有软件和硬件的传输方式,这里我用的是软件的IIC。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第12张图片

 9.由于采用的是HC_05蓝牙模块,采用的是串口通信,那么我们来配置串口,这里需要注意,一定要打开串口的NVIC,在NVIC中把勾勾打上,否则MCU不会接收中断,也接收不到数据。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第13张图片

10.到这里基本的功能已经配置完成,为了方便以后扩展功能,我还增加了四个独立按键。按键要选择上拉输入模式。上拉是为了读取按键的低电平检测,即使外部有上电阻,也最好打开内部上拉电阻。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第14张图片

11.配置完成我们生成大代码。在生成的过程中我们需要注意几点。最好不要有中文路径,我这里讲解就放桌面了,选择使用MDK-arm打开方式。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第15张图片

 选择仅加载需要的文件进行配置,这样可以缩短编译时间。完后生成独立的.c与.h文件,这样会让整个程序看起来清爽干净。最后点击生成完成配置工作。基于STM32 Cortex-M3内核F103制作的智能小车项目_第16张图片

四.整体调试:

完成配置我们打开工程文件,这边我就直接提供各个模块的程序,我把他们都差分出来,方便大家一一对应着理解。

1.小车运动

#define N1_on HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
#define N1_off HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
#define N2_on HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
#define N2_off HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
#define N3_on HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
#define N3_off HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
#define N4_on HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
#define N4_off HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);


void for_word(void);
void back_word(void);
void left_word(void);
void right_word(void);
void off_word(void);
void for_word(void)
{
	N1_on;
	N2_off;		
	N3_on;
	N4_off;	
}

void back_word(void)
{
	N1_off;
	N2_on;		
	N3_off;
	N4_on;
}

void left_word(void)
{
	N1_off;
	N2_on;		
	N3_on;
	N4_off;		
}

void right_word(void)
{
	N1_on;
	N2_off;		
	N3_off;
	N4_on;	
}
void off_word(void)
{
	N1_off;
	N2_off;		
	N3_off;
	N4_off;	
}

启动定时器2,开启通道1与通道2

	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//左路PWM波
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//右路PWM波

设置PWM占空比,我这边PWM占空比达到100%的话,直接放200就可以。

  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 110);
	__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 110);	

2.舵机驱动,这边可以在某宝上面看到怎么使用。只需要给舵机通电(5V),在信号线送入不同占空比的PWM信号就可以控制舵机的旋转角度。

基于STM32 Cortex-M3内核F103制作的智能小车项目_第17张图片

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//舵机PWM

 测试程序

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 5);HAL_Delay(2000);//-90
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 10);HAL_Delay(2000);//-45
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 15);HAL_Delay(2000);//0
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 20);HAL_Delay(2000);//45
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 25);	HAL_Delay(2000);//90	

 4.超声波测距

#define Trig_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET)
#define Trig_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET)
void user_delaynus_tim(uint32_t nus)
{
 uint16_t  differ = 0xffff-nus-5;
  __HAL_TIM_SetCounter(&htim3,differ);//设置定时器2的计数初始值
  HAL_TIM_Base_Start(&htim3);//开启定时器
  while( differ<0xffff-5)
	 {
		differ = __HAL_TIM_GetCounter(&htim3);
	 }
  HAL_TIM_Base_Stop(&htim3);//关闭定时器
}


uint16_t csb_value(void)
{
	uint16_t count=0;
	
		Trig_H ;
		user_delaynus_tim(12);//维持12us高电平
		Trig_L ;
		  
       HAL_TIM_Base_Start(&htim3); //开启定时器3
  		
		while( HAL_GPIO_ReadPin (GPIOB ,GPIO_PIN_0) != GPIO_PIN_SET);
			
		__HAL_TIM_SetCounter(&htim3,0);//将定时器3初始值清零,以便开始从零计数
	
		while(HAL_GPIO_ReadPin (GPIOB ,GPIO_PIN_0) == GPIO_PIN_SET);  //检测到低电平停止计数
		
       HAL_TIM_Base_Stop(&htim3);//关闭定时器3
		
		count = __HAL_TIM_GetCounter(&htim3);//读出计数值
        
//	  distance = (uint16_t )count*0.017;
//		OLED_ShowNum(72,0,distance,4,16);
	    count=(uint16_t )count*0.017;

		//HAL_Delay (500);//两次测量之间间隔时间	
	
	return count;
	
}

5.蓝牙串口通信,这边主要是用于调试串口收发数据,记得蓝牙的波特率与串口一的波特率一定要一致,一般为9600,这一步很关键,否则将无法接收上位机发送的数据。

HAL_UART_Receive_IT(&huart1,arr1,3);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == huart1.Instance)
	{
		if(arr1[0]==0XBF && arr1[1]==0XA1 && arr1[2]==0XFb )
		{
			printf("*");
			HAL_UART_Receive_IT(&huart1,arr1,3);			
		}
		if(arr1[0]==0XBF && arr1[1]==0XA2 && arr1[2]==0XFb )
		{
			printf("&");
			HAL_UART_Receive_IT(&huart1,arr1,3);			
		}		
	}
}

6.OLED 的程序普遍一致,我就不展示了,大家可以去下载别人的程序修改或者私聊我。

 7.主函数程序演示

	if(csbvalue > 20 || csbvalue == 20)
	{
		 
	    for_word();
	}
	else
	{
	    off_word();
	    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 25);
	    HAL_Delay(500);
	    left_distance=csbvalue;
	    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 5);
	    HAL_Delay(500);
	    right_distance=csbvalue;
	   		
	    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 15);
		
	    if(left_distance>right_distance && left_distance>20)
	    {
	  	  left_word();
	  	  HAL_Delay(1000);
	    }
	    else if(right_distance>left_distance && right_distance>20)
	    {
	  	  right_word();
	  	  HAL_Delay(1000);
	    }
	    else
	    {
	  	  back_word();
	  	  HAL_Delay(500);
	    }
	}

五.学习总结:

看到这里相信你已经完成了你的小车,小车整体不难,相比之下调试部分是需要花费一些功夫,比如控制小车转弯的时间,超声波读取回来数据在到小车做出反应的时间,都是需要根据自己的实际情况来调节。相信大家那么聪明一定能用最短的时间做出自己心仪的小车。

我认为小车还有不足的一点,就是在接收障碍物后,小车要停止做出反应,但是由于惯性,小车不可能立即停止,一直与小车会继续前进而撞向障碍物,这样我就不得不增加检测到障碍物的距离。而增加距离的话,看起来会很笨,还没到障碍物就停止了。我能想到的是给它加上PID控制,PID控制我会放在下篇文章来详细给大家分析。感谢支持。

如有错误,欢迎指正,如有帮助,不胜荣幸。

下面再来欣赏一下我这极具性价比的小车吧。


 

你可能感兴趣的:(c语言)