精华内容
下载资源
问答
  • STM32小车
    千次阅读 多人点赞
    2021-06-30 15:09:34

    一、设计内容

    1、 已有材料:STM32小车相关硬件
    2、 开发工具:Keil uVision5
    3、 资料:相关硬件说明书、指导老师提供的部分基础工程代码及教学视频
    4、 实现功能:小车基本动作控制驱动、小车调速控制、蓝牙实现小车遥控、小车的自动避障(超声波+红外线)、小车的循迹功能

    二、芯片引脚介绍

    在这里插入图片描述

    三、开发环境配置

    1) 安装MDK——keil5.28
    ① 下载md528a.exe
    ② Customer information全部空格 安装
    ③ 安装Keil.STM32F1xx_DFP.1.0.5.pack直接next
    ④ 解压keygen_new2032.rar 管理员身份运行 破解keil5
    在这里插入图片描述
    2) 新建STM32F103工程

    ① 选择工程路径和命名

    在这里插入图片描述

    ② 芯片型号选择
    在这里插入图片描述

    ③ 函数库选择
    在这里插入图片描述

    ④ 创建一个.c文件 保存为main.c 加入keil中
    在这里插入图片描述

    ⑤ 编译
    在这里插入图片描述

    ⑥ 出错解决
    在这里插入图片描述

    3) 将程序下载进小车
    ① 跳线帽接好,芯片对应的USB线连接电脑
    在这里插入图片描述

    ② 下载程序
    在这里插入图片描述

    ③ 成功标志

    在这里插入图片描述

    三、小车基本动作控制驱动

    1、原理分析
    在这里插入图片描述

    1. 双路电机驱动对应的接口为M1+ M1- M2+ M2-
    2. 通过上面的芯片引脚端口图,找到对应的芯片引脚为GPIOB组的Pin_6 Pin7 Pin8 Pin9
    3. 可以看到M1+ M1-是控制同条电路,而M2+ M2-是控制另外一条电路
    4. 也就是说,小车左边前后轮为一组控制,小车右边前后轮为一组控制
    5. M1+对应的是右前轮,M1-对应的是右后轮,而M2则为左边
    6. 当M1+与M1-输出相同电平,都无法唯一确定电流的去向,表现为右轮不动
    7. 当M1+与M1-输出相反电平,若M1+ M1-为10,则右边前进,而01则为右边后退

    2、代码编写步骤

    1. 开启使能时钟
    2. GPIO结构体初始化 端口配置->速度配置->模式选择
    3. 引脚高低电平设置 GPIO_SetBits() GPIO_ResetBits()

    3、 实现代码

    (电机初始化)

    void Motor_Init(void){
    	//1、使能GPIO时钟---STM32芯片编程模块必须先做这一步
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	
    	//2、GPIO的结构体初始化
    	GPIO_InitTypeDef  aaa;//定义一个用来初始化GPIO的结构体
    	aaa.GPIO_Pin  = GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8 | GPIO_Pin_9;//PB6 PB7 PB8 PB9对应电机四个轮  PB5对应使能电池
    	aaa.GPIO_Speed  = GPIO_Speed_50MHz;
    	aaa.GPIO_Mode   = GPIO_Mode_Out_PP;//普通推挽输出
    	GPIO_Init(GPIOB,&aaa);//调用官方的初始化函数 完成对PB组引脚初始化
    	
    	//3、PB5 = 1,使能电池供电
    	GPIO_SetBits(GPIOB,GPIO_Pin_5);
    }
    

    (小车基础动作)

    //小车前进函数
    void Car_Forward()
    {
    	//PB6 = 1  PB8 =1
    	GPIO_SetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_8);
    	//PB7 = 0  PB9 = 0
    	GPIO_ResetBits(GPIOB,GPIO_Pin_7 | GPIO_Pin_9);
    }
    
    //小车后退函数
    void Car_Back()
    {
    	//PB7 = 1  PB9 = 1
    	GPIO_SetBits(GPIOB,GPIO_Pin_7 | GPIO_Pin_9);
    	
    	//PB6 = 0  PB8 = 0
    	GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_8);
    }
    //小车停止函数
    void Car_Stop()
    {
    	//PB6 = 1  PB7 = 1
    	GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7);
    	
    	//PB8 = 0  PB9 = 0
    	GPIO_ResetBits(GPIOB,GPIO_Pin_8 | GPIO_Pin_9);
    }
    //小车前左转函数
    void Car_Left()
    {
    	//PB6 = 1  PB7 = 1  PB8 = 1
    	GPIO_SetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8);
    	
    	//PB9 = 0
    	GPIO_ResetBits(GPIOB,GPIO_Pin_9);
    }
    //小车前右转函数
    void Car_Right()
    {
    	//PB8 = 1  PB9 = 1  PB6 = 1
    	GPIO_SetBits(GPIOB,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_6);
    	
    	//PB7=0
    	GPIO_ResetBits(GPIOB,GPIO_Pin_7);
    }
    

    四、小车调速控制

    1、原理分析

    使用计数器,控制高电平在总时间的比例,实现小车的速度控制。
    例如
    在20us时间里,高电平输出时间为10us,实现小车半速前行;
    在20us时间里,高电平输出时间为5us,实现小车1/4速度前行;
    

    2、代码编写步骤

    1. 开启GPIOB、AFIO、TIM4的使能时钟
    2. 初始化GPIO
    3. 初始化基本定时器
    4. 利用定时器实现对应通道的电平输出控制
    5. 开启定时器

    3、实现代码

    (电机初始化)

    void Motor_Init(void){
    	//1、开始使能时钟---STM32芯片编程模块必须先做这一步
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//电机调速添加
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//电机调速添加
    	
    	//2、GPIO结构初始化 将对应端口设置作复用功能
    	GPIO_InitTypeDef  aaa;//定义一个用来初始化GPIO的结构体
    	aaa.GPIO_Pin  = GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 | GPIO_Pin_9;//
    	aaa.GPIO_Speed  = GPIO_Speed_50MHz;
    	aaa.GPIO_Mode   = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIO_Init(GPIOB,&aaa);//调用官方的初始化函数 完成对PB组引脚初始化
    	
    	//3、基本定时器TIM4初始化(分频系数  计数模式  自动重装载值  分频因子)
    	TIM_TimeBaseInitTypeDef ccc;
    	ccc.TIM_Prescaler = 72-1;//72Mhz/72 = 1Mhz  1个脉冲对应1us
    	ccc.TIM_CounterMode = TIM_CounterMode_Up;//递增计数模式
    	ccc.TIM_Period      = 2000-1;//ARR 2000  自动重装载值  刚好周期为2ms
    	ccc.TIM_ClockDivision = TIM_CKD_DIV1;//上面的预分频系数够了  这里设置为1分频即不分频
    	TIM_TimeBaseInit(TIM4,&ccc);
    	
    	//4、定时器TIM4输出通道1 2 3 4的初始化
    	TIM_OCInitTypeDef ddd;
    	ddd.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1---递增模式下  CNT<CCR时输出有效电平   CNT>CCR时输出另一种电平
    	ddd.TIM_OCPolarity = TIM_OCPolarity_High;//极性高----高电平有效  配合上面的模式,即左边输出高 右边输出低
    	ddd.TIM_Pulse      = 0;// 比较值 0就是默认都只输出100%低电平
    	ddd.TIM_OutputState = TIM_OutputState_Enable;
    	TIM_OC1Init(TIM4,&ddd);//注意这里是OC1---对应通道1
    	TIM_OC2Init(TIM4,&ddd);//注意这里是OC2---对应通道2
    	TIM_OC3Init(TIM4,&ddd);//注意这里是OC3---对应通道3
    	TIM_OC4Init(TIM4,&ddd);//注意这里是OC4---对应通道4
    
    	//5、开启定时器4计数器--开始工作计数
    	TIM_Cmd(TIM4,ENABLE);
    }
    

    (小车基础动作的调速->通过一个函数实现小车的五种基础动作)

    //speed->[0,1999]
    void Car_Speed_Init(int Speed1,int Speed2,int Speed3,int Speed4){
    	TIM4->CCR1 = Speed1;
    	TIM4->CCR2 = Speed2;
    	TIM4->CCR3 = Speed3;
    	TIM4->CCR4 = Speed4;
    }
    

    (例子说明)

    CCR1CCR2CCR3CCR4功能
    1500015000前进
    0160001600后退
    1000012000差速左转
    1400010000差速右转

    五、蓝牙遥控小车

    1、原理分析

    蓝牙 与芯片 与手机连接示意图:

    AT指令模式:蓝牙->芯片 默认波特率38400
    透穿模式:蓝牙->手机 默认波特率9600

    2、蓝牙连接电脑

    1. 按照小车底板的排座接口接好蓝牙
    2. 将板子的USB直连 同时用USB线连到电脑 即蓝牙直接和电脑相连
    3. 电脑端运行串口助手软件 开始使用AT指令调试蓝牙
      在这里插入图片描述
    4. 运行XCOM串口助手 连接上蓝牙
      在这里插入图片描述
    5. 拔下蓝牙 按住蓝牙上的小按键 不松开再插回去 蓝牙慢闪
    6. 通过发送文本框输入
    a)	AT回车            蓝牙会反馈OK
    b)	AT+NAME? 回车    蓝牙会反馈自己的名称
    c)	AT+NAME=你设置的新蓝牙名字 回车  设置新的蓝牙名称
    d)	AT+UART? 回车        查询蓝牙透传模式下的通信波特率
    e)	AT+UART=9600,0,0 回车 设置蓝牙波特率为9600 停止位1  无校验位
    

    3、蓝牙连接手机

    1. 跳线帽短接STM32和蓝牙
      在这里插入图片描述
    2. 下载<蓝牙串口>app
    3. 输入<1234>实现手机与蓝牙的连接

    4、蓝牙遥控小车

    代码编写步骤

    1. 开启使能 GPIOA USART1 AFIO 时钟
    2. 配置USART1 USART_Init()
    3. 配置GPIOA的 PA9 PA10——对应蓝牙端口的引脚
    4. 开启串口接收中断USART_ITConfig()
    5. 开启串口 USART_Cmd()

    实现代码

    void UART1_Init(void)
    {
    	//1、使能 GPIOA USART1 AFIO 时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    	
    	//2、配置串口1
    	USART_InitTypeDef aaa;
    	aaa.USART_BaudRate   = 9600;// 和蓝牙一致的波特率
    	aaa.USART_WordLength = USART_WordLength_8b;//有效数据长度8bit
    	aaa.USART_StopBits   = USART_StopBits_1;//1bit停止位
    	aaa.USART_Parity     = USART_Parity_No;//不要校验位
    	aaa.USART_Mode       = USART_Mode_Tx | USART_Mode_Rx;//收发模式
    	aaa.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不需要硬件流控
    	USART_Init(USART1,&aaa);
    	
    	//3、初始化GPIOA结构体  配置蓝牙对应的引脚
    	GPIO_InitTypeDef  bbb;
    	bbb.GPIO_Pin  = GPIO_Pin_9;//TX
    	bbb.GPIO_Speed  = GPIO_Speed_50MHz;
    	bbb.GPIO_Mode   = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIO_Init(GPIOA,&bbb);
    	bbb.GPIO_Pin  = GPIO_Pin_10;//RX
    	bbb.GPIO_Speed  = GPIO_Speed_50MHz;
    	bbb.GPIO_Mode   = GPIO_Mode_IN_FLOATING;//浮空输入模式
    	GPIO_Init(GPIOA,&bbb);
    	
    	//3、配置USART1的中断优先级
    	NVIC_InitTypeDef  ccc;//定义一个用来初始化中断优先级的结构体
    	ccc.NVIC_IRQChannel = USART1_IRQn;//USART1全局中断号,类似大家的身份证号  让芯片知道是哪个中断
    	ccc.NVIC_IRQChannelPreemptionPriority = 0x01;//第一优先级数值 0x00~0x0F  数字越小 优先级越高
    	ccc.NVIC_IRQChannelSubPriority = 0x01;//第二优先级数值 0x00~0x0F  数字越小 优先级越高
    	ccc.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&ccc);
    	
    	//4、开启串口接收中断  串口1有数据过来就会跳转到中断函数运行代码
    	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    	
    	//5、开启串口
    	USART_Cmd(USART1,ENABLE);
    }
    
    //处理串口1的中断函数
    void USART1_IRQHandler(void)
    {
    	char RData=0;//定义一个用来临时存放串口接收数据的变量
    	//先读取并判断串口的接收数据中断标志位有没有触发 
    	if(USART_GetITStatus(USART1,USART_IT_RXNE)==1)
    	{
    		
    		USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除串口1的接收中断标志位
    		RData = USART1->DR;//接收串口1的一个字节数据 这个函数是库函数
    
    		//接收完成再判断该变量  手机发过来不同的数字 小车有不同的动作
    		if(RData == '0')
    			Car_Stop();//小车停止
    		else if(RData == '1')
    			Car_Forward();//小车前进
    		else if(RData == '2')
    			Car_Back();//小车后退
    		else if(RData == '3')
    			Car_Left();//小车前左转
    		else if(RData == '4')
    			Car_Right();//小车前右转
    	}
    }
    

    六、小车超声波避障

    1、舵机转向位置控制

    1. 原理
     利用计时器,根据不同的值给予不同时间的高电平,使其转动不同的方向。
     1、该舵机要求提供的PWM周期为20ms
     2、舵机控制角度为0~180° 0.5ms~2.5ms的高电平周期对应的转动角度是0~180°
     3、调整其20ms pwm周期内的高电平比例可控制其输出角度
    
    1. 代码步骤
    1.使能时钟  GPIOB1   AFIO  TIM3
    2.GPIO PB1初始化
    3.基本定时器TIM3初始化(分频系数  计数模式  自动重装载值  分频因子)
    4.定时器TIM3输出通道4的初始化
    5.开启定时器3计数器--开始工作计数
    
    1. 代码实现

    (舵机初始化)

    void steeringEngine_Init(void)
    {
    	//1、使能时钟  GPIOB1   AFIO  TIM3
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	
    	//2、GPIO PB1初始化
    	GPIO_InitTypeDef  bbb;
    	bbb.GPIO_Pin  = GPIO_Pin_1;//TX
    	bbb.GPIO_Speed  = GPIO_Speed_50MHz;
    	bbb.GPIO_Mode   = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIO_Init(GPIOB,&bbb);
    	
    	
    	//3、基本定时器TIM3初始化(分频系数  计数模式  自动重装载值  分频因子)
    	TIM_TimeBaseInitTypeDef ccc;
    	ccc.TIM_Prescaler = 72-1;//72Mhz/72 = 1Mhz  1个脉冲对应1us
    	ccc.TIM_CounterMode = TIM_CounterMode_Up;//递增计数模式
    	ccc.TIM_Period      = 20000-1;//ARR 20000  自动重装载值  刚好周期为20ms
    	ccc.TIM_ClockDivision = TIM_CKD_DIV1;//上面的预分频系数够了  这里设置为1分频即不分频
    	TIM_TimeBaseInit(TIM3,&ccc);
    	
    	//4、定时器TIM3输出通道4的初始化
    	TIM_OCInitTypeDef ddd;
    	ddd.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1---递增模式下  CNT<CCR时输出有效电平   CNT>CCR时输出另一种电平
    	ddd.TIM_OCPolarity = TIM_OCPolarity_High;//极性高----高电平有效  配合上面的模式,即左边输出高 右边输出低
    	ddd.TIM_Pulse      = 500;// 比较值  CCR500*1us = 500us = 0.5ms高电平  默认舵机转到0°位置
    	ddd.TIM_OutputState = TIM_OutputState_Enable;
    	TIM_OC4Init(TIM3,&ddd);//注意这里是OC4---对应通道4
    
    	//5、开启定时器3计数器--开始工作计数
    	TIM_Cmd(TIM3,ENABLE);
    }
    
    

    (舵机位置赋值)

    TIM3->CCR4 = 500;//0*
    TIM3->CCR4 = 1000;//45*
    TIM3->CCR4 = 1500;//90*
    TIM3->CCR4 = 2000;//135*
    TIM3->CCR4 = 2500;//180*
    

    2、超声波模块驱动与测距

    1. 原理分析
      在这里插入图片描述
      在这里插入图片描述
    2. 代码步骤
    //超声波模块初始化
    1.启动使能时钟 GPIOB GPIOA TIM2
    2.特定的引脚初始化——PB11 PB12
    3.定时器初始化——TIM2
    4.先关闭定时器
    
    //超声波测距
    1.先控制TRIG引脚输出一个至少10us高电平  启动超声波模块
    2.等待ECHO引脚被超声波模块自己拉高 在拉高的瞬间我们开始计时即可
    3.高电平开始计时
    4.跳出来时  count是多少就代表高电平持续了多少us
    
    //超声波避障
    while(1){
    1.小车距离障碍物大于30 前进
    2.小车距离障碍物小于30 停止
    3.当小车距离障碍物小于40  一边后退一边查找方向
    }
    
    //查找方向
    1.右转45?
    2.右转90?
    3.左转45?
    4.左转90?
    5.继续后退
    
    1. 代码实现
      (超声波模块初始化)
    void HCSR_Init(void)
    {
    	//1、使能时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	//2、配置PB11--TRIG 为输出模式
    	GPIO_InitTypeDef  aaa;//定义一个用来初始化GPIO的结构体
    	aaa.GPIO_Pin   = GPIO_Pin_11;
    	aaa.GPIO_Speed = GPIO_Speed_50MHz;
    	aaa.GPIO_Mode  = GPIO_Mode_Out_PP;//普通推挽输出
    	GPIO_Init(GPIOB,&aaa);
    
    	//3、配置PB12--ECHO 为输入模式
    	aaa.GPIO_Pin   = GPIO_Pin_12;
    	aaa.GPIO_Speed = GPIO_Speed_50MHz;
    	aaa.GPIO_Mode  = GPIO_Mode_IPU;//上拉输入模式(自行百度了解上拉)
    	GPIO_Init(GPIOB,&aaa);
    	
    	//4、测距时计时用的定时器的配置 TIM3  TIM4 已经用了  TIM2
    	TIM_TimeBaseInitTypeDef ccc;//初始化定时器用的结构体
    	ccc.TIM_Prescaler = 72-1;//72Mhz/72 = 1Mhz  1个脉冲对应1us
    	ccc.TIM_CounterMode = TIM_CounterMode_Up;//递增计数模式
    	ccc.TIM_Period      = 65536-1;//ARR 20000  16Bit定时器 自动重装载值  刚好周期为20ms
    	ccc.TIM_ClockDivision = TIM_CKD_DIV1;//上面的预分频系数够了  这里设置为1分频即不分频
    	TIM_TimeBaseInit(TIM2,&ccc);
    	
    	//5、先关闭定时器TIM2
    	TIM_Cmd(TIM2,DISABLE);
    }
    

    (超声波测距)

    //获取超声波测距的函数--单位厘米
    float HCSR_GetDistance(void)
    {
    	//1、先控制TRIG引脚输出一个至少10us高电平  启动超声波模块
    	GPIO_SetBits(GPIOB,GPIO_Pin_11);
    	delay_us(15);
    	GPIO_ResetBits(GPIOB,GPIO_Pin_11);
    
    	//2、等待ECHO引脚被超声波模块自己拉高 在拉高的瞬间我们开始计时即可
    	while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 0);
    	//开启定时器2让TIM2的计数器开始计数 并且在开启计数前  清空计数值
    	TIM2->CNT = 0;//设置计数器的计数值初值为0
    	TIM_Cmd(TIM2,ENABLE);
    	
    	//3、高电平开始计时
    	while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 1);
    	//ECHO高电平结束  结束计数
    	TIM_Cmd(TIM2,DISABLE);
    	
    	//4、跳出来时  count是多少就代表高电平持续了多少us
    	//可以开始计算距离  厘米单位
    	return 0.017*(TIM2->CNT); //0.017根据公式计算而得
    }
    

    (超声波避障实现)

    void turn_to_find(){
    	while(1){
    		TIM3->CCR4 = 1000;//right 45*
    		if(HCSR_GetDistance()>30.0){//大于30  小车右转45度
    			Car_Speed_Init(1999,0,0,0);
    			delay_ms(300);
    			break;
    		}
    		TIM3->CCR4 = 500;//right 90*
    		if(HCSR_GetDistance()>30.0){//大于30  小车右转90度
    			Car_Speed_Init(1999,0,0,0)
    			delay_ms(600);
    			break;
    		}
    		TIM3->CCR4 = 2000;//left 45*
    		if(HCSR_GetDistance()>30.0){//大于30  小车左转45度
    			Car_Speed_Init(0,0,1999,0)
    			delay_ms(300);
    			break;
    		}
    		TIM3->CCR4 = 2500;//left 90*
    		if(HCSR_GetDistance()>30.0){//大于30  小车左转90度
    			Car_Speed_Init(0,0,1999,0)
    			delay_ms(600);
    			break;
    		}
    		//都找不到 小车继续后退
    		Car_Speed_Init(0,1999,0,1999);
    		delay_ms(100);
    		break;
    	}
    	TIM3->CCR4 = 1500;//舵机摆正
    };
    
    //main函数
    TIM3->CCR4 = 1500;//舵机摆正
    while(1)
    {
    //1. 大于30 小车前进
    Car_Speed_Init(1800,0,1800,0);
    while(HCSR_GetDistance()>30.0) delay_ms(500);
    
    //2. 小于30 小车停止
    Car_Speed_Init(0,0,0,0);
    
    //3. 小于40 小车一边后退一边找方向
    while(HCSR_GetDistance()<40.0)
    {Car_Back(0,1800,0,1800);delay_ms(500);turn_to_find();}
    }
    

    七、小车红外避障(结合超声波避障)

    1、原理分析

    通过判断红外线的返回信号,判断左右两边是否有障碍物。
    

    2、代码步骤

    //红外线避障模块初始化
    1.使能时钟
    2.特定引脚初始化
    
    //红外避障+超声波避障
    1. 大于30且两边无障碍 小车前进
    2. 大于30但左边有障碍 小车在右边45 90找方向
    3. 大于30但右边有障碍 小车在左边45 90找方向
    4. 小于30 小车一边后退一边查找方向
    

    3、代码实现
    (红外线避障模块初始化)

    void hongwai_init(void){
    	//1、使能时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	//2、初始化端口红外线端口 PB10 PA11
    	GPIO_InitTypeDef  aaa;//定义一个用来初始化GPIO的结构体
    	aaa.GPIO_Pin   = GPIO_Pin_10;
    	aaa.GPIO_Speed = GPIO_Speed_50MHz;
    	aaa.GPIO_Mode  = GPIO_Mode_IPU;//上拉输入模式
    	GPIO_Init(GPIOB,&aaa);
    	bbb.GPIO_Pin   = GPIO_Pin_11;
    	bbb.GPIO_Speed = GPIO_Speed_50MHz;
    	bbb.GPIO_Mode  = GPIO_Mode_IPU;//上拉输入模式
    	GPIO_Init(GPIOA,&aaa);
    }
    
    //GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10)==0 为左边有障碍
    //GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==0 为右边有障碍
    

    (红外避障+超声波避障)

    TIM3->CCR4 = 1500;//舵机摆正
    while(1)
    {
    //1. 大于30且两边无障碍 小车前进
    Car_Speed_Init(1800,0,1800,0);
    while(HCSR_GetDistance()>30.0&&GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==1&&GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==1) 
    delay_ms(500);
    
    //2. 大于30但左边有障碍而右边无障碍 小车在右边45 90找方向
    if(HCSR_GetDistance()>30.0&&GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==1&&GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0)
    	turn_right_to_find();
    	
    //3. 大于30但右边有障碍而左边无障碍 小车在左边45 90找方向
    if(HCSR_GetDistance()>30.0&&GGPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==0&&GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==1)
    	turn_left_to_find();
    
    //4. 小于30 小车一边后退一边查找方向
    if(HCSR_GetDistance()<30.0){
    	while(HCSR_GetDistance()<40.0)
    	{Car_Back(0,1800,0,1800);delay_ms(500);turn_to_find();}
    }
    }
    

    八、小车沿白线循迹

    1、原理分析

    1.使用4路红外循迹返回的信号,完成小车沿线循迹功能的实现
    2.车头4路循迹模块对应的芯片引脚为(从左到右)分别为PA12,PB13,PB14,PB15
    3.端口遇到白色信号为0,未遇到信号未1
    

    2、代码实现

    (循迹模块初始化)

    void xunji_init(void)
    {
    	//1、使能时钟  GPIOB GPIOA
    	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    	
    	//2、GPIO PB13 PB14 PB15初始化
    	GPIO_InitTypeDef eee;	
    	eee.GPIO_Pin =  GPIO_Pin_13 | GPIO_Pin_14  | GPIO_Pin_15;
    	eee.GPIO_Mode = GPIO_Mode_IPU;//配置GPIO模式,输入上拉       
    	eee.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &eee);
    
    	//3、GPIO PA12 初始化
    	eee.GPIO_Pin =  GPIO_Pin_12;
    	eee.GPIO_Mode = GPIO_Mode_IPU;//配置GPIO模式,输入上拉       
    	eee.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &eee);
    };
    

    (获取循迹模块的信号)

    //从左到右读入四个端口的信号
    uint8_t read_xunji_data(void){
    	uint16_t buff = 0; 
    	buff = (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)<<3)+
    			(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13)<<2)+
    			(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)<<1)+
    			(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15)<<0);
    	return buff;
    };
    

    (实现小车沿白线循迹——如果沿黑线只需要调换01)

    //main()
    while(1){
    	//1.白线在左车头
    	if(data==0111||data==1011||data==0011||data==0001){
    		Car_Speed_Init(1800,0,0,0);
    		delay_ms(500);
    	}
    	//2.白线在右车头
    	else if(data==1110||data==1101||data==1100||data==1000){
    		Car_Speed_Init(0,0,1800,0);
    		delay_ms(500);
    	}
    	//3.其他情况直行
    	else{
    		Car_Speed_Init(1800,0,1800,0);
    		delay_ms(500);
    	}
    }
    

    九、实验总结——嵌入式开发的流程步骤

    1. 了解硬件背后原理,信号状态代表了现实情况的什么信息。
    2. 根据系统的库函数,对特定使用的模块进行初始化。
    3. 巧妙利用计时器,实现电平不同时间的输出来操作硬件,以及获取关键信息。
    4. 根据基础的功能实现,自己按照一定的逻辑,实现智能小车的避障等功能。

    十、小车实物图介绍

    在这里插入图片描述

    更多相关内容
  • stm32小车控制程序

    2018-01-15 16:14:39
    stm32小车控制程序stm32小车控制程序stm32小车控制程序
  • 智能小车使用红外探头避障,适应不同颜色标志
  • 基于stm32vet6小车程序,通信模块为ESP8266,采用手机APP控制
  • stm32小车_蓝牙小车_

    2021-10-01 18:42:49
    stm32+hc06+舵机转向的蓝牙遥控小车
  • 基于STM32F103RC 的蓝牙智能小车
  • 基于stm32f103c8t6单片机开发,通过2.4G无线串口将手势端收集的陀螺仪数据发送到小车小车执行指令。
  • 智能小车使用红外探头避障,适应不同颜色标志
  • 编程实现红外循迹小车的执行程序,工作环境是stm32开发板
  • 移动机器人开源代码,可对小车进行速度调控,方向调控,角度调控
  • STM32平衡小车代码开源。基于stm32f013平台,pid算法的平衡小车开源代码。
  • stm32小车程序

    2018-04-03 11:24:50
    基于stm32vet6小车程序,通信模块为ESP8266,采用手机APP控制
  • 电子-stm32小车程序.rar

    2019-09-05 18:36:51
    电子-stm32小车程序.rar,单片机/嵌入式STM32-F0/F1/F2
  • 这是我们学校智能车竞赛我们组的程序,这个好像是个半成品,仅供参考
  • stm32的智能小车程序,小车运行的不错,大家可以参考一下
  • 基于stm32及proteus智能小车仿真,前两个按键分别控制对应电机正反转,第三个控制两个电机转速。
  • 实现小车循迹和避障功能,只能同时实现小车循迹或避障中 的一个
  • 3.4 STM32 的最小系统 3.4.1 电源电路 3.4.2 晶振电路 3.4.3 SWD接口电路 3.4.4 串口通信电路 3.5 本章小结 4 智能小车避障系统的设计与实现 4.1 避障流程设计 4.2 基于固定区域分割原理的避障算法 4.3 ...
  • 配合本人上传的stm32驱动控制电路PCB使用,此程序通过串口接收数据控制小车运行,大家可以根据自己需要进行修改,电机驱动以及数据转换的轮子已经造好了,供大家使用。
  • 这是基于STM32f407单片机的超声波避障蓝牙遥控小车的Keil程序。这份文件包含了蜂鸣器报警beep.c,电机驱动PWM控制car.c,蓝牙遥控小车行驶方向car_turn.c,超声波避障hc_sr04.c,OLED显示距离、行驶方向和报警状态...
  • 火星探险小车主控程序,单片机STM32控制多路直流电机,
  • stm32的云台初始化程序,用于小车的运行上,包含了CAN通信程序等
  • 该程序源代码用于stm32f103c8t6智能小车循迹+测速实验。 1、源代码开发软件:KEIL4; 2、程序对应处理器是:STM32F103C8T6; 3、智能小车电机驱动芯片是:L293D; 4、智能小车电机为:TT直流减速电机; 5、需要用到...
  • 设计基于STM32F103ZET6主控芯片的智能避障小车,由电源模块、障碍物检测模块、电机驱动模块、红外遥控模块部分组成,其中HC-SR04超声波传感器、HJ-IR2红外传感器、MMA7361L倾角传感器协同组成障碍物检测部分完成障碍物...
  • 基于STM32的智能小车使用红模块智能避障程序
  • gps电子罗盘智能导航,集成模式1,2寻迹避障。
  • 系统以 STM32 单片机作为控制核心。采用调制激光传感器进行路径信息采集,将实际路径信号转换为电信号传送到单片机进行处理,然后结合 PID 算法以及记忆算法实现路径最优及路径记忆;对于障碍物的检测,可采用光电...
  • stm32f103为控制芯片的光电循迹小车源代码,打开工程后可直接在keil MDK运行编译。 以stm32f103为控制芯片的光电循迹小车源代码,打开工程后可直接在keil MDK运行编译。
  • stm32红外循迹小车硬件原理图
  • 这个是正点原子精英版的小车工程,利用hc-05蓝牙,l298电机驱动进行前进,后退,左转,右转。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,447
精华内容 2,578
关键字:

STM32小车