基于蓝牙技术使用stm32制造一个智能小车 (寻迹,避障,遥控)

您所在的位置:网站首页 红外和蓝牙遥控 基于蓝牙技术使用stm32制造一个智能小车 (寻迹,避障,遥控)

基于蓝牙技术使用stm32制造一个智能小车 (寻迹,避障,遥控)

2024-03-28 01:06| 来源: 网络整理| 查看: 265

目录

1.制作智能小车的硬件名单:

3.引脚图

2.先让小车动起来

 1.小车运动

2.代码

3.寻迹

 1.工作原理

2.代码

4.超声波避障

 1.工作原理

2.代码

5.蓝牙遥控

 1.蓝牙工作原理

2.代码

6.oled屏幕

1.工作内容

7.led灯

8.蜂鸣器

9.蓝牙使用代码main

1.制作智能小车的硬件名单:

 STM32C6T6核心板1块L298N电机驱动 1块五路灰度循迹模块   1个带电机轮子的小车底盘(自带tt电机) 1个    12V供电电池1个蓝牙模块1个超声波1个电源转换模块1个OLED屏幕1个LED灯1个蜂鸣器1个

1.小车底盘可以凭自己爱好买两轮或者四轮的。

2.核心板也可以凭性能改变,我觉得c6t6的已经可以完成他们了。

3.引脚图

2.先让小车动起来

 1.小车运动

前进:让所有的轮子正转。

后退:让所有的轮子反转。

左转:左侧轮子不动,右边轮子往正转。

右转:右侧轮子不动,左边轮子往反转。

2.代码 #include "motor.h" //使用定时器2 void PWM_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); 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_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); } void PWM_SetCompare3(uint16_t Compare) { TIM_SetCompare3(TIM2, Compare); } void PWM_SetCompare2(uint16_t Compare) { TIM_SetCompare2(TIM2, Compare); } void Motor_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_3 | GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); PWM_Init(); } //TIM_SetCompare2 TIM_SetCompare3的数值分别对应左右两边的速度,可自行调整 void run(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0; } void back(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 0; IN2 = 1; IN3 = 0; IN4 = 1; } void zhuan1(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 1; } void zhuan2(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 0; IN2 = 1; IN3 = 1; IN4 = 0; } void right(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 1; IN2 = 1; IN3 = 1; IN4 = 0; } void left(u8 s) { TIM_SetCompare2(TIM2,s); TIM_SetCompare3(TIM2,s); IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 1; } void stop() { IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 0; } #ifndef __MOTOR_H #define __MOTOR_H #include "bm.h" #include "stm32f10x.h" // Device header //可以按照此处接线 IN1~4 #define IN1 PAout(6) #define IN2 PAout(5) #define IN3 PAout(4) #define IN4 PAout(3) void Motor_Init(void); void run(u8 s); void left(u8 s); void right(u8 s); void back(u8 s); void stop(void); void zhuan1(u8 s); void zhuan2(u8 s); #endif 3.寻迹

 1.工作原理

黑色返回1,对应的灯不亮。

白色返回0,对应的灯亮。

可以用螺丝刀调节灵敏度。

2.代码 #include "xunji.h" #include "motor.h" #include "Delay.h" //五路寻迹模块 void XUN_GPIO_COnfine(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } extern int l; //寻迹运动 //根据线的宽度来决定; void run1(void ) { if(L2==0&&L1==0&&M==1&&R1==0&&R2==0&&l>20) {run(70);} else if(L2==0&&L1==1&&M==0&&R1==0&&R2==0&&l>20) { run(70);} else if(L2==0&&L1==0&&M==0&&R1==1&&R2==0&&l>20) { run(70);} else if(L2==0&&L1==0&&M==1&&R1==1&&R2==0&&l>20) { run(70);} else if(L2==0&&L1==1&&M==1&&R1==0&&R2==0&&l>20) { run(70);} else if(L2==0&&L1==1&&M==1&&R1==1&&R2==0&&l>20) { run(70);} else if(L2==0&&L1==1&&M==1&&R1==1&&R2==1&&l>20) { left(70);} else if(L2==1&&L1==1&&M==1&&R1==1&&R2==0&&l>20) { right(70);} else if(L2==1&&L1==0&&M==0&&R1==0&&R2==0&&l>20) {right(80);} else if(L2==1&&L1==1&&M==0&&R1==0&&R2==0&&l>20) {right(80);} else if(L2==1&&L1==1&&M==1&&R1==0&&R2==0&&l>20) {right(80);} else if(L2==1&&L1==0&&M==1&&R1==0&&R2==0&&l>20) {right(80);} else if(L2==1&&R2==0&&l20) {left(80);} else if(L2==0&&L1==0&&M==0&&R1==1&&R2==1&&l>20) {left(80);} else if(L2==0&&L1==0&&M==0&&R1==0&&R2==1&&l>20) {left(80);} else if(L2==0&&L1==0&&M==1&&R1==0&&R2==1&&l>20) {left(80);} else if(L2==0&&R2==1&&l>20) {left(80);} else if(L2==1&&L1==1&&M==1&&R1==1&&R2==1&&l>20) { zhuan1(75); Delay_ms(100); stop(); Delay_ms(500); } else if(L2==0&&L1==0&&M==0&&R1==0&&R2==0&&l>20) { zhuan1(75); Delay_ms(100); stop(); Delay_ms(500); } } #ifndef __XUNJI_H #define __XUNJI_H #include "stm32f10x.h" // Device header #define R2 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8) #define R1 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) #define M GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) #define L1 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) #define L2 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) void XUN_GPIO_COnfine(void); void run1(void); #endif 4.超声波避障

 1.工作原理

由于超声波碰到物体返回的特点,利用两者的时间差,以及声音在空中的速度就可以计算出障碍物的距离,进行躲避。

2.代码 #include "sonic.h" //定时器3设置 void hcsr04_NVIC() { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } //IO口初始化 及其他初始化 void Hcsr04Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin =Trig_Pin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB ,Trig_Pin); GPIO_InitStructure.GPIO_Pin = Echo_Pin ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,Echo_Pin); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_DeInit(TIM3); TIM_TimeBaseStructure.TIM_Period = (1000-1); TIM_TimeBaseStructure.TIM_Prescaler =(72-1); TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM3, TIM_FLAG_Update); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); hcsr04_NVIC(); TIM_Cmd(TIM3,DISABLE); } u16 msHcCount = 0; //打开定时器3 static void OpenTimerForHc() { TIM_SetCounter(TIM3,0); msHcCount = 0; TIM_Cmd(TIM3, ENABLE); } //关闭定时器3 static void CloseTimerForHc() { TIM_Cmd(TIM3, DISABLE); } //定时器3终中断 void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); msHcCount++; //计数器开始加 } } //获取定时器3计数器值 u32 GetEchoTimer(void) { u32 t = 0; t = msHcCount*1000; t += TIM_GetCounter(TIM3); TIM3->CNT = 0; //计数器归零 Delay_ms(50); return t; } //通过定时器3计数器值推算距离 float Hcsr04GetLength(void ) { u32 t = 0; int i = 0; float lengthTemp = 0; float sum = 0; u8 ll=0; while(i!=5) //测量五次取平均 { for(ll=0;ll30) { run(70); } if(lBRR=i;} //输出低电平 #define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态 /* 定义控制IO的宏 */ #define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED1_OFF digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED1_ON digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED2_TOGGLE digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED2_OFF digitalHi(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED2_ON digitalLo(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED3_TOGGLE digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN) #define LED3_OFF digitalHi(LED3_GPIO_PORT,LED3_GPIO_PIN) #define LED3_ON digitalLo(LED3_GPIO_PORT,LED3_GPIO_PIN) void LED_GPIO_Config(void); #endif /* __LED_H */ 8.蜂鸣器

#include "Buzzer.h" void Buzzer_GPIO_Config(void) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /*开启LED相关的GPIO外设时钟*/ RCC_APB2PeriphClockCmd( Buzzer_GPIO_CLK , ENABLE); /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = Buzzer_GPIO_PIN; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*调用库函数,初始化GPIO*/ GPIO_Init(Buzzer_GPIO_PORT, &GPIO_InitStructure); //置高电平 GPIO_SetBits(Buzzer_GPIO_PORT, Buzzer_GPIO_PIN); } #ifndef __Buzzer_H #define __Buzzer_H #include "stm32f10x.h" // Device header #define Buzzer_GPIO_PORT GPIOA /* GPIO端口 */ #define Buzzer_GPIO_CLK RCC_APB2Periph_GPIOA /* GPIO端口时钟 */ #define Buzzer_GPIO_PIN GPIO_Pin_7 #define Buzzer_OFF GPIO_ResetBits(Buzzer_GPIO_PORT,Buzzer_GPIO_PIN) #define Buzzer_ON GPIO_SetBits(Buzzer_GPIO_PORT,Buzzer_GPIO_PIN) void Buzzer_GPIO_Config(void); #endif 9.蓝牙使用代码main #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "sonic.h" #include "xunji.h" #include "motor.h" #include #include #include #include "led.h" #include "hc_05.h" #include "Buzzer.h" u8 i=0; int sp,l; unsigned int receive_data; void hc_05_send(void) { if(receive_data =='a') { i=1; receive_data=0; } if(receive_data =='b') { i=2; receive_data=0; } if(receive_data =='c') { i=3; receive_data=0; } if(receive_data =='d') { i=4; receive_data=0; } if(receive_data =='e') { i=5; receive_data=0; } if(receive_data =='f') { i=6; receive_data=0; } if(receive_data =='g') { i=7; receive_data=0; } if(receive_data =='k') { i=8; receive_data=0; } if(receive_data =='j') { i=9; receive_data=0; } if(receive_data =='l') { i=10; receive_data=0; } if(receive_data =='p') { i=11; receive_data=0; } if(receive_data =='v') { i=12; receive_data=0; } } void fying(void) { if(i==1) { OLED_ShowString(1,4," run"); run(90); } if(i==2) { OLED_ShowString(1,4,"black"); back(90); } if(i==3) { OLED_ShowString(1,4,"left "); left(70); } if(i==4) { OLED_ShowString(1,4,"right "); right(70); } if(i==5) { OLED_ShowString(1,4,"zhuan1"); zhuan1(80); } if(i==6) { OLED_ShowString(1,4," stop "); stop(); } if(i==7) { run1(); OLED_ShowString(1,4," xunji"); } if(i==8) { OLED_ShowString(1,4," LEDS "); LED1_OFF;LED2_OFF;LED3_OFF; } if(i==9) { OLED_ShowString(1,4," LEDM "); LED1_ON;LED2_ON;LED3_ON; } if(i==10) { OLED_ShowString(1,4," SONIC "); run2(); } if(i==11) { OLED_ShowString(1,4,"BUZZER"); Buzzer_OFF; } if(i==12) { OLED_ShowString(1,4,"BUZZER"); Buzzer_ON; } } int main(void) { uart1_init(9600); OLED_Init(); Motor_Init(); Hcsr04Init(); XUN_GPIO_COnfine(); LED_GPIO_Config(); Buzzer_GPIO_Config(); while(1) { sp= (L2* 10000) + (L1 * 1000)+ (M * 100) + (R1 * 10) + R2; l=Hcsr04GetLength(); OLED_ShowNum(2,4,l,3); OLED_ShowNum(3,4,sp,5); if(USART_GetFlagStatus(HC_05_USARTX,USART_FLAG_RXNE)==1) { receive_data=USART_ReceiveData(HC_05_USARTX); hc_05_send(); USART_ClearFlag(HC_05_USARTX,USART_FLAG_RXNE); } fying(); if(l10) { Buzzer_ON; LED1_ON; } } }

-----------------------欢迎大家指正交流,有空可以一起讨论代码啊。--------------------------------

完整工程链接:通过百度网盘分享的文件:小车.zip 链接:https://pan.baidu.com/s/1dXtAi0C-9MGuAeWu13SXeQ?pwd=3gv8  提取码:3gv8



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3