🚗🚗🚗🚗🚗
博客就当作学习过程中的笔记
博客提供了几乎所有需要敲的代码
可以借鉴,但不要面向「CSDN 编程」哦
奶奶要努力变强💪
前言(BB Time)
疫情假期的时候开始学习 STM32 ,因为在家所以疯狂划水,进度落下了很多,所以非常感谢返校后学长还有组内其他小伙伴的协助。
小车自然是嵌入式学习过程中的第一个「大项目」。从看「正点原子」的样例代码,实现相近功能,到自己动手做一辆小车车 着实是不小的跨步。
@万里羊 和 @nidie508 两位学长的博客对我提供了非常大的帮助(哈哈哈,面向 CSDN 编程),也是看了他们的博客让我下定决心认真写博客,记录自己所学,毕竟要对得起资料里的「5年码龄」😂。
👇BB 结束,正片开始👇
硬件
一、选型
1、开发板
小板子
实验室提供的 Mini STM32
寄存器版本
学长说库函数可能相对比较简单(我并没有这么觉得 微笑.jpg),而且后期的话一些功能使用库函数不方便(小声BB,我可能前期就被现实锤爆了根本没有后期 哈哈哈)
2、其他元件
底盘和小车轮
不知名的脏兮兮底盘和两个可爱的小电机
电机驱动模块
TB6612,噗嗤小伙伴焊的时候焊反了,但记住 IO 口就行了,问题不大👌
超声波模块
HC-SR04
红外模块
FC-03
蓝牙模块
唔,我找不到了哈哈哈🤦♂️
二、原理
1、电机
通过 TB6612FNG 来驱动电机,因为该模块是双驱动,所以只需一个即可驱动一对电机
- VM:连接 12V 以内电源
- VCC:连接 5V 以内电源
- GND:连接电源负极
- STBY:该口清零则两组电机全部停转,置1后通过 AIN、BIN 控制正反转
- PWMA、PWMB:分别连接控制左右电机 PWM 输出的 IO 口
- AO、BO:1、2分别连接连接电机正负极
- AIN、BIN:
接口 | 停止 | 正转 | 反转 |
---|---|---|---|
AIN1 | 0 | 0 | 1 |
AIN2 | 0 | 1 | 0 |
接口 | 停止 | 正转 | 反转 |
---|---|---|---|
BIN1 | 0 | 0 | 1 |
BIN2 | 0 | 1 | 0 |
2、超声波
- VCC:连接 5V 以内电源
- GND:连接电源负极
- TRLG:连接开发板上控制超声波发射的 IO 口
- ECHO:连接开发板上处理超声波接收信号的 IO 口
3、红外
红外发射端发射光线到地面,红外光线遇到白色被反射,接收端检测到反射光线后输出低电平;遇到黑色被吸收,接收端未检测到反射光线,输出高电平
- VCC:连接开发板 5V 电源
- GND:连接电源负极
- D0:连接开发板接收红外信号的 IO 口
颜色 | 电平 |
---|---|
白色 | 0 |
黑色 | 1 |
4、蓝牙
小伙伴的部分
功能
我和小伙伴合作的小车主要有三个功能,不同的功能通过 STM32 开发板上的按键进行切换。
一、车轮滚滚
1、原理
- 直行:左轮和右轮同时正转
- 后退:左轮和右轮同时反转
- 停止:左轮和右轮同时停止
- 左转:左轮反转,右轮正转
- 右转:左轮正转,右轮反转
2、代码
wheel.h
#ifndef __WHEEL_H
#define __WHEEL_H
#include "sys.h"
//TB6612连接
#define LEFT PAout(2)
#define LIN1 PAout(0)
#define LIN2 PAout(1)
#define RIGHT PAout(3)
#define RIN1 PAout(4)
#define RIN2 PAout(5)
//#define STBY PBout(0) //因为 STBY 直接连接到 3.3V 电源了,所以不需要使用 IO 口
#define left_PWM TIM2->CCR3//占空比
#define right_PWM TIM2->CCR4//占空比
void Wheel_Init(u16 arr,u16 psc);
void GO(void);//执行直行操作
void STOP(void);//执行停止操作
void BACK(void);//执行后退操作
void turnLEFT(void);//执行左转操作
void turnRIGHT(void);//执行右转操作
#endif
wheel.c
#include "wheel.h"
#include "delay.h"
void Wheel_Init(u16 arr,u16 psc) {
RCC->APB1ENR |=1<<0;//TIM2时钟使能
RCC->APB2ENR |=1<<2;
GPIOA->CRL &=0XFF000000;//PA2,3复用输出
GPIOA->CRL |=0X0033BB33;//PA0,1,4,5推挽输出
TIM2->ARR=arr;//自动重装载值
TIM2->PSC=psc;//预分频系数
TIM2->CCMR2|=7<<4; //CH3 PWM2 模式//比较捕获模式配置寄存器
TIM2->CCER|=1<<8; //输出使能 //捕获/比较使能寄存器
TIM2->CCMR2|=7<<12; //CH4 PWM2 模式//比较捕获模式配置寄存器
TIM2->CCER|=1<<12; //输出使能 //捕获/比较使能寄存器
TIM2->CR1 |=0X0001;//使能定时器2
}
void GO(void) {
LIN1=0;LIN2=1;
RIN1=0;RIN2=1;
}
void STOP(void) {
LIN1=0;LIN2=0;
RIN1=0;RIN2=0;
}
void BACK(void) {
LIN1=1;LIN2=0;
RIN1=1;RIN2=0;
}
void turnLEFT(void) {
//TURN LEFT/L0R1
LIN1=0;LIN2=1;
RIN1=1;RIN2=0;
}
void turnRIGHT(void) {
//TURN RIGHT/L1R0
LIN1=1;LIN2=0;
RIN1=0;RIN2=1;
}
3、注意
- 电机连接时正负极方向
二、按键切换功能
1、原理
这里有两种思路:
- 思路一 在主函数中设置两个死循环,第一个循环负责扫描按键,接收到输入之后确定使用的功能,进入第二个循环执行功能。这种方法缺点是 切换功能之前需要通过复位键重置
- 思路二 将上述两个循环放在一起,设置 modeNUM 代表功能选择,每循环过程中检查 modeNUM 数值执行对应操作。若接收到按键输入则改变 modeNUM 为对应数值
我使用的是方法一
2、代码
key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0_PRES 1
#define KEY1_PRES 2
#define WKUP_PRES 3
#define KEY0 PCin(5)
#define KEY1 PAin(15)
#define WK_UP PAin(0)
void KEY_Init(void);
int KEY_Scan(u8 mode);
#endif
key.c
#include "key.h"
#include "delay.h"
void KEY_Init(void) { //初始化按键 a0 a15 c5
RCC->APB2ENR|=1<<2;
RCC->APB2ENR|=1<<4;
GPIOA->CRL&=0xFFFFFFF0;
GPIOA->CRL|=0x00000008;
GPIOA->CRH&=0x0FFFFFFF;
GPIOA->CRH|=0x80000000;
GPIOA->ODR|=1<<15;
GPIOC->CRL&=0xFF0FFFFF;
GPIOC->CRL|=0x00800000;
GPIOC->ODR|=1<<5;
}
int KEY_Scan(u8 mode) { //扫描按键
static u8 key_up=1;//按键按松开标志
if(KEY0==0||KEY1==0||WK_UP==1) {
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)
return KEY0_PRES;
else if(KEY1==0)
return KEY1_PRES;
else if
(WK_UP==1)return WKUP_PRES;
}
else if(KEY0==1&&KEY1==1&&WK_UP==0)
key_up=1;
return 0;// 无按键按下
}
test.c 按键切换部分
while(1)
{
key=KEY_Scan(0);
switch(key) {
case KEY0_PRES:
GO1();
break;
case KEY1_PRES:
GO2();
break;
case WKUP_PRES:
GO3();
break;
default:
delay_ms(10);
}
}
三、通过三路超声波实现避障
1、代码
hc6.h
#ifndef __HC6_H
#define __HC6_H
#include "sys.h"
void HCSR04_Init(u16 arr,u16 psc);
u32 DIS_Init(u8 *STA,u16 VAL);
void Ultrasound(void);
#endif
hc6.c
#include "hc6.h"
#include "sys.h"
#include "delay.h"
#include "wheel.h"
#include "usart.h"
void HCSR04_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<2; //TIM4 ±÷” πƒ‹
RCC->APB2ENR|=1<<2; // πƒ‹PORTA ±÷”
RCC->APB2ENR|=1<<3; // πƒ‹PORTB ±÷”
RCC->APB2ENR|=1<<4; // πƒ‹PORTC ±÷”
GPIOB->CRL&=0X00FFFFFF;//PB6~9«Â≥˝÷Æ«∞…Ë÷√
GPIOB->CRL|=0X88000000;//PB6~9∏°ø’ ‰»Î
GPIOB->CRH&=0XF000FF00;
GPIOB->CRH|=0X03330088;
GPIOB->ODR|=0<<6;
GPIOB->ODR|=0<<7; //PB7œ¬¿≠
GPIOB->ODR|=0<<8;
GPIOB->ODR|=0<<9;
GPIOB->ODR|=1<<12; //PB4 ‰≥ˆ∏fl
GPIOB->ODR|=1<<13;
GPIOB->ODR|=1<<14;
TIM4->ARR=arr; //…Ë∂®º∆ ˝∆˜◊‘∂Ø÷ÿ◊∞÷µ
TIM4->PSC=psc; //‘§∑÷∆µ∆˜
TIM4->CCMR1|=1<<0; //CC1S=01 —°‘Ò ‰»Î∂ÀIC1”≥…‰µΩTI1
TIM4->CCMR1|=1<<4; //IC1F=0001 ≈‰÷√¬À≤®∆˜ “‘Fck_int≤…—˘£¨¡Ω∏ˆ ¬º˛∫Û”––ß
TIM4->CCMR1|=0<<2; //IC1PS=00 ≈‰÷√ ‰»Î∑÷∆µ£¨≤ª∑÷∆µ
TIM4->CCER|=0<<1; //CC1P=0 …œ…˝—ÿ≤∂ªÒ
TIM4->CCER|=1<<0; //CC1E=1 ‘ –Ì≤∂ªÒº∆ ˝∆˜µƒ÷µµΩ≤∂ªÒºƒ¥Ê∆˜÷–
TIM4->CCMR1|=1<<8; //CC2S=01 —°‘Ò ‰»Î∂ÀIC1”≥…‰µΩTI1
TIM4->CCMR1|=1<<12; //IC2F=0001 ≈‰÷√¬À≤®∆˜ “‘Fck_int≤…—˘£¨¡Ω∏ˆ ¬º˛∫Û”––ß
TIM4->CCMR1|=0<<10; //IC2PS=00 ≈‰÷√ ‰»Î∑÷∆µ£¨≤ª∑÷∆µ
TIM4->CCER|=0<<5; //CC2P=0 …œ…˝—ÿ≤∂ªÒ
TIM4->CCER|=1<<4; //CC2E=1 ‘ –Ì≤∂ªÒº∆ ˝∆˜µƒ÷µµΩ≤∂ªÒºƒ¥Ê∆˜÷–
TIM4->CCMR2|=1<<0; //CC3S=01 —°‘Ò ‰»Î∂ÀIC1”≥…‰µΩTI1
TIM4->CCMR2|=1<<4; //IC3F=0001 ≈‰÷√¬À≤®∆˜ “‘Fck_int≤…—˘£¨¡Ω∏ˆ ¬º˛∫Û”––ß
TIM4->CCMR2|=0<<2; //IC3PS=00 ≈‰÷√ ‰»Î∑÷∆µ£¨≤ª∑÷∆µ
TIM4->CCER|=0<<9; //CC3P=0 …œ…˝—ÿ≤∂ªÒ
TIM4->CCER|=1<<8; //CC3E=1 ‘ –Ì≤∂ªÒº∆ ˝∆˜µƒ÷µµΩ≤∂ªÒºƒ¥Ê∆˜÷–
TIM4->CCMR2|=1<<8; //CC4S=01 —°‘Ò ‰»Î∂ÀIC1”≥…‰µΩTI1
TIM4->CCMR2|=1<<12; //IC4F=0001 ≈‰÷√¬À≤®∆˜ “‘Fck_int≤…—˘£¨¡Ω∏ˆ ¬º˛∫Û”––ß
TIM4->CCMR2|=0<<10; //IC4PS=00 ≈‰÷√ ‰»Î∑÷∆µ£¨≤ª∑÷∆µ
TIM4->CCER|=0<<13; //CC4P=0 …œ…˝—ÿ≤∂ªÒ
TIM4->CCER|=1<<12; //CC4E=1 ‘ –Ì≤∂ªÒº∆ ˝∆˜µƒ÷µµΩ≤∂ªÒºƒ¥Ê∆˜÷–
TIM4->DIER|=1<<1;
TIM4->DIER|=1<<2; //‘ –Ì≤∂ªÒ÷–∂œ
TIM4->DIER|=1<<3; //‘ –Ì≤∂ªÒ÷–∂œ
TIM4->DIER|=1<<4; //‘ –Ì≤∂ªÒ÷–∂œ
TIM4->DIER|=1<<0; //‘ –Ì∏¸–¬÷–∂œ
TIM4->CR1|=0X01; // πƒ‹∂® ±∆˜2
MY_NVIC_Init(2,0,TIM4_IRQn,2);//«¿’º2£¨◊””≈œ»º∂0£¨◊È2
}
u8 TIM4CH1_CAPTURE_STA=0; // ‰»Î≤∂ªÒ◊¥Ã¨
u16 TIM4CH1_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
u8 TIM4CH2_CAPTURE_STA=0; // ‰»Î≤∂ªÒ◊¥Ã¨
u16 TIM4CH2_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
u8 TIM4CH3_CAPTURE_STA=0; // ‰»Î≤∂ªÒ◊¥Ã¨
u16 TIM4CH3_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
u8 TIM4CH4_CAPTURE_STA=0; // ‰»Î≤∂ªÒ◊¥Ã¨
u16 TIM4CH4_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
//∂® ±∆˜4÷–∂œ∑˛ŒÒ≥ÖÚ
void TIM4_IRQHandler(void)
{
u16 tsr;
tsr=TIM4->SR;
if((TIM4CH1_CAPTURE_STA&0X80)==0)//ªπŒ¥≥…π¶≤∂ªÒ
{
if(tsr&0X01)//“Á≥ˆ
{
if(TIM4CH1_CAPTURE_STA&0X40)//“—æ≠≤∂ªÒµΩ∏flµÁ∆Ω¡À
{
if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//∏flµÁ∆Ωô≥§¡À
{
TIM4CH1_CAPTURE_STA|=0X80;//±Íº«≥…π¶≤∂ªÒ¡À“ª¥Œ
TIM4CH1_CAPTURE_VAL=0XFFFF;
}else TIM4CH1_CAPTURE_STA++;
}
}
if(tsr&0x02)//≤∂ªÒ1∑¢…˙≤∂ªÒ ¬º˛
{
if(TIM4CH1_CAPTURE_STA&0X40) //≤∂ªÒµΩ“ª∏ˆœ¬Ωµ—ÿ
{
TIM4CH1_CAPTURE_STA|=0X80; //±Íº«≥…π¶≤∂ªÒµΩ“ª¥Œ∏flµÁ∆Ω¬ˆøÌ
TIM4CH1_CAPTURE_VAL=TIM4->CCR1;//ªÒ»°µ±«∞µƒ≤∂ªÒ÷µ
TIM4->CCER&=~(1<<1); //CC1P=0 …Ë÷√Œ™…œ…˝—ÿ≤∂ªÒ
}else //ªπŒ¥ø™ º£¨µ⁄“ª¥Œ≤∂ªÒ…œ…˝—ÿ
{
TIM4CH1_CAPTURE_VAL=0;
TIM4CH1_CAPTURE_STA=0X40; //±Íº«≤∂ªÒµΩ¡À…œ…˝—ÿ
TIM4->CNT=0; //º∆ ˝∆˜«Âø’
TIM4->CCER|=1<<1; //CC1P=1 …Ë÷√Œ™œ¬Ωµ—ÿ≤∂ªÒ
}
}
}
if((TIM4CH2_CAPTURE_STA&0X80)==0)//ªπŒ¥≥…π¶≤∂ªÒ
{
if(tsr&0X01)//“Á≥ˆ
{
if(TIM4CH2_CAPTURE_STA&0X40)//“—æ≠≤∂ªÒµΩ∏flµÁ∆Ω¡À
{
if((TIM4CH2_CAPTURE_STA&0X3F)==0X3F)//∏flµÁ∆Ωô≥§¡À
{
TIM4CH2_CAPTURE_STA|=0X80;//±Íº«≥…π¶≤∂ªÒ¡À“ª¥Œ
TIM4CH2_CAPTURE_VAL=0XFFFF;
}else TIM4CH2_CAPTURE_STA++;
}
}
if(tsr&0x04)//≤∂ªÒ1∑¢…˙≤∂ªÒ ¬º˛
{
if(TIM4CH2_CAPTURE_STA&0X40) //≤∂ªÒµΩ“ª∏ˆœ¬Ωµ—ÿ
{
TIM4CH2_CAPTURE_STA|=0X80; //±Íº«≥…π¶≤∂ªÒµΩ“ª¥Œ∏flµÁ∆Ω¬ˆøÌ
TIM4CH2_CAPTURE_VAL=TIM4->CCR2;//ªÒ»°µ±«∞µƒ≤∂ªÒ÷µ
TIM4->CCER&=~(1<<5); //CC1P=0 …Ë÷√Œ™…œ…˝—ÿ≤∂ªÒ
}else //ªπŒ¥ø™ º£¨µ⁄“ª¥Œ≤∂ªÒ…œ…˝—ÿ
{
TIM4CH2_CAPTURE_VAL=0;
TIM4CH2_CAPTURE_STA=0X40; //±Íº«≤∂ªÒµΩ¡À…œ…˝—ÿ
TIM4->CNT=0; //º∆ ˝∆˜«Âø’
TIM4->CCER|=1<<5; //CC1P=1 …Ë÷√Œ™œ¬Ωµ—ÿ≤∂ªÒ
TIM4->CR1|=0x01;
}
}
}
if((TIM4CH3_CAPTURE_STA&0X80)==0)//ªπŒ¥≥…π¶≤∂ªÒ
{
if(tsr&0X01)//“Á≥ˆ
{
if(TIM4CH3_CAPTURE_STA&0X40)//“—æ≠≤∂ªÒµΩ∏flµÁ∆Ω¡À
{
if((TIM4CH3_CAPTURE_STA&0X3F)==0X3F)//∏flµÁ∆Ωô≥§¡À
{
TIM4CH3_CAPTURE_STA|=0X80;//±Íº«≥…π¶≤∂ªÒ¡À“ª¥Œ
TIM4CH3_CAPTURE_VAL=0XFFFF;
}else TIM4CH3_CAPTURE_STA++;
}
}
if(tsr&0x08)//≤∂ªÒ1∑¢…˙≤∂ªÒ ¬º˛
{
if(TIM4CH3_CAPTURE_STA&0X40) //≤∂ªÒµΩ“ª∏ˆœ¬Ωµ—ÿ
{
TIM4CH3_CAPTURE_STA|=0X80; //±Íº«≥…π¶≤∂ªÒµΩ“ª¥Œ∏flµÁ∆Ω¬ˆøÌ
TIM4CH3_CAPTURE_VAL=TIM4->CCR3;//ªÒ»°µ±«∞µƒ≤∂ªÒ÷µ
TIM4->CCER&=~(1<<9); //CC1P=0 …Ë÷√Œ™…œ…˝—ÿ≤∂ªÒ
}else //ªπŒ¥ø™ º£¨µ⁄“ª¥Œ≤∂ªÒ…œ…˝—ÿ
{
TIM4CH3_CAPTURE_VAL=0;
TIM4CH3_CAPTURE_STA=0X40; //±Íº«≤∂ªÒµΩ¡À…œ…˝—ÿ
TIM4->CNT=0;
TIM4CH3_CAPTURE_VAL=TIM4->CCR3; //º∆ ˝∆˜«Âø’
TIM4->CCER|=1<<9; //CC1P=1 …Ë÷√Œ™œ¬Ωµ—ÿ≤∂ªÒ
TIM4->CR1|=0x01;
}
}
}
if((TIM4CH4_CAPTURE_STA&0X80)==0)//ªπŒ¥≥…π¶≤∂ªÒ
{
if(tsr&0X01)//“Á≥ˆ
{
if(TIM4CH4_CAPTURE_STA&0X40)//“—æ≠≤∂ªÒµΩ∏flµÁ∆Ω¡À
{
if((TIM4CH4_CAPTURE_STA&0X3F)==0X3F)//∏flµÁ∆Ωô≥§¡À
{
TIM4CH4_CAPTURE_STA|=0X80;//±Íº«≥…π¶≤∂ªÒ¡À“ª¥Œ
TIM4CH4_CAPTURE_VAL=0XFFFF;
}else TIM4CH4_CAPTURE_STA++;
}
}
if(tsr&0x10)//≤∂ªÒ1∑¢…˙≤∂ªÒ ¬º˛
{
if(TIM4CH4_CAPTURE_STA&0X40) //≤∂ªÒµΩ“ª∏ˆœ¬Ωµ—ÿ
{
TIM4CH4_CAPTURE_STA|=0X80; //±Íº«≥…π¶≤∂ªÒµΩ“ª¥Œ∏flµÁ∆Ω¬ˆøÌ
TIM4CH4_CAPTURE_VAL=TIM4->CCR4;//ªÒ»°µ±«∞µƒ≤∂ªÒ÷µ
TIM4->CCER&=~(1<<13); //CC1P=0 …Ë÷√Œ™…œ…˝—ÿ≤∂ªÒ
}else //ªπŒ¥ø™ º£¨µ⁄“ª¥Œ≤∂ªÒ…œ…˝—ÿ
{
TIM4CH4_CAPTURE_VAL=0;
TIM4CH4_CAPTURE_STA=0X40; //±Íº«≤∂ªÒµΩ¡À…œ…˝—ÿ
TIM4->CNT=0; //º∆ ˝∆˜«Âø’
TIM4->CCER|=1<<13; //CC1P=1 …Ë÷√Œ™œ¬Ωµ—ÿ≤∂ªÒ
TIM4->CR1|=0x01;
}
}
}
TIM4->SR=0;//«Â≥˝÷–∂œ±Í÷挪
}
u32 DIS_Init(u8 *STA,u16 VAL)//∂®“º∆À„懿Î∫Ø ˝
{
u32 temp;
u32 lenth;
if((*STA)&0X80)//≥…π¶≤∂ªÒµΩ¡À“ª¥Œ∏flµÁ∆Ω
{
temp=(*STA)&0X3F;
temp*=65536; //“Á≥ˆ ±º‰◊‹∫Õ
temp+=VAL; //µ√µΩ◊‹µƒ∏flµÁ∆Ω ±º‰
lenth=temp*0.017; //º∆À„≥§∂»
*STA=0; //ø™∆Ùœ¬“ª¥Œ≤∂ªÒ
}
return lenth;
}
#define Trig1 PBout(14) // PB13
#define Trig2 PBout(13)
#define Trig3 PBout(12)
extern u8 TIM4CH2_CAPTURE_STA; // ‰»Î≤∂ªÒ◊¥Ã¨
extern u16 TIM4CH2_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
extern u8 TIM4CH3_CAPTURE_STA; // ‰»Î≤∂ªÒ◊¥Ã¨
extern u16 TIM4CH3_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
extern u8 TIM4CH4_CAPTURE_STA; // ‰»Î≤∂ªÒ◊¥Ã¨
extern u16 TIM4CH4_CAPTURE_VAL; // ‰»Î≤∂ªÒ÷µ
void Ultrasound(void)
{
u32 lenth1;
u32 lenth2;
u32 lenth3;
Trig1=1;
delay_us(20); // ‰»Î“ª∏ˆ20usµƒ∏flµÁ∆Ω
Trig1=0;
lenth1=DIS_Init(&TIM4CH2_CAPTURE_STA,TIM4CH2_CAPTURE_VAL);
delay_us(20);
Trig2=1;
delay_us(20); // ‰»Î“ª∏ˆ20usµƒ∏flµÁ∆Ω
Trig2=0;
lenth2=DIS_Init(&TIM4CH3_CAPTURE_STA,TIM4CH3_CAPTURE_VAL);
delay_us(20);
Trig3=1;
delay_us(20);
Trig3=0;
lenth3=DIS_Init(&TIM4CH4_CAPTURE_STA,TIM4CH4_CAPTURE_VAL);
printf("length1:%d",lenth1);
printf("length2:%d",lenth2);
printf("length3:%d",lenth3);
if((lenth1>20)&&(lenth3>10)&&(lenth2>10))
{
printf("GO \r\n");
GO();
}
else if(lenth3<10)
{
printf("LEFT \r\n");
turnLEFT();
delay_ms(20);
}
else if(lenth2<10)
{
printf("RIGHT \r\n");
turnRIGHT();
delay_ms(20);
}
else
{
printf("BACK \r\n");
BACK();
delay_ms(500);
turnLEFT();
delay_ms(300);
}
STOP();
}
GO2 函数
void GO2(void) {
while(1)
Ultrasound();
}
四、通过两个红外模块实现黑线循迹
1、原理
如图,在小车正前方并排安装两个红外模块,确保黑线位于两个红外模块之间,若左侧检测到黑线,说明车身偏右,即执行左转操作;若右侧检测到黑线,说明车身偏左,即执行右转操作
2、代码
inred.h
#ifndef __INRED_H
#define __INRED_H
#include "sys.h"
#define Linred PAin(6);
#define Rinred PAin(7);
void Inred_Init(void);
#endif
inred.c
#include "inred.h"
void Inred_Init(void) {
RCC->APB2ENR |= 1<<2;
GPIOA->CRL &= 0X00FFFFFF;
GPIOA->CRL |= 0X88000000;
}
GO1 函数
void GO1(void) {
while(1) {
if(PAin(6)==1 && PAin(7)==0) {
turnRIGHT();
delay_ms(50);
}
else if(PAin(6)==1 && PAin(7)==1)
GO();
else if(PAin(6)==0 && PAin(7)==1) {
turnLEFT();
delay_ms(50);
}
else
GO();
}
}
3、注意
- 在写 test.c 的过程中遇到了一个小问题,if(Linred == X) 语句一直在报错,后来把 Linred 改成了对应的 IO 口解决了问题,但是问题出在哪还是不太清楚
- 通过 PWM 调节车轮转速时,值越大转速越慢
- 左右电机存在速度差,只要调节到近似相等即可
- @万里羊学长提醒的:开发板只需要接收红外模块检测返回后的结果即可,无需输出信息,因此使用 in 而非 out
五、通过手机蓝牙遥控车辆
1、代码
bluetooth.h
#ifndef __BLUETOOTH_H
#define __BLUETOOTH_H
#include "sys.h"
#include "stdio.h"
#define USART_REC_LEN 200 //∂®“Â◊Ó¥ÛΩ” ’◊÷Ω⁄ ˝ 200
#define EN_USART3_RX 1 // πƒ‹£®1£©/Ω˚÷π£®0£©¥Æø⁄1Ω” ’
extern u8 USART3_RX_BUF[USART_REC_LEN]; //Ω” ’ª∫≥Â,◊Ó¥ÛUSART_REC_LEN∏ˆ◊÷Ω⁄.ƒ©◊÷Ω⁄Œ™ªª––∑˚
extern u16 USART3_RX_STA; //Ω” ’◊¥Ã¨±Íº«
//»Áπ˚œÎ¥Æø⁄÷–∂œΩ” ’£¨«Î≤ª“™◊¢ Õ“‘œ¬∫Í∂®“Â
void uart3_init(u32 pclk2,u32 bound);
void USART3_IRQHandler(void);
#endif
bluetooth.c
#include "bluetooth.h"
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "wheel.h"
#include "stdio.h"
u8 BTFlag;
#if EN_USART3_RX //»Áπ˚ πƒ‹¡ÀΩ” ’
//¥Æø⁄1÷–∂œ∑˛ŒÒ≥ÖÚ
//◊¢“‚,∂¡»°USARTx->SRƒ‹±‹√‚ƒ™√˚∆‰√Óµƒ¥ÌŒÛ
u8 USART3_RX_BUF[USART_REC_LEN]; //Ω” ’ª∫≥Â,◊Ó¥ÛUSART_REC_LEN∏ˆ◊÷Ω⁄.
//Ω” ’◊¥Ã¨
//bit15£¨ Ω” ’ÕÍ≥…±Í÷æ
//bit14£¨ Ω” ’µΩ0x0d
//bit13~0£¨ Ω” ’µΩµƒ”––ß◊÷Ω⁄ ˝ƒø
u16 USART3_RX_STA=0; //Ω” ’◊¥Ã¨±Íº«
void USART3_IRQHandler(void)
{
u8 res;
//delay_ms(50);
if(USART3->SR&(1<<5)) //Ω” ’µΩ ˝æ›
{
//delay_ms(10);
res=USART3->DR;
printf("\r\n%d",res);
if(res == 250)
{
GO();
printf("\r\nGO");
}
else if(res == 253)
{
BACK();
printf("\r\nBack");
}
else if(res== 251)
{
turnLEFT();
printf("\r\nLeft");
}
else if(res==255)
{
turnRIGHT();
printf("\r\nRight");
}
else if(res==173)
{
STOP();
printf("\r\nStop");
}
}
}
#endif
//≥ı ºªØIO ¥Æø⁄3
//pclk2:PCLK2 ±÷”∆µ¬ (Mhz)
//bound:≤®Ãÿ¬
void uart3_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//µ√µΩUSARTDIV
mantissa=temp; //µ√µΩ’˚ ˝≤ø∑÷
fraction=(temp-mantissa)*16; //µ√µΩ–° ˝≤ø∑÷
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<3; // πƒ‹PORTBø⁄ ±÷”
RCC->APB1ENR|=1<<18; // πƒ‹¥Æø⁄3 ±÷”
GPIOB->CRH&=0XFFFF00FF;//IO◊¥Ã¨…Ë÷√
GPIOB->CRH|=0X00008B00;//IO◊¥Ã¨…Ë÷√
RCC->APB2RSTR|=1<<18; //∏¥Œª¥Æø⁄3
RCC->APB2RSTR&=~(1<<18);//Õ£÷π∏¥Œª
//≤®Ãÿ¬ …Ë÷√
USART3->BRR=mantissa; // ≤®Ãÿ¬ …Ë÷√
USART3->CR1|=0X200C; //1ŒªÕ£÷π,Œfi–£—ÈŒª.
//#if EN_USART1_RX //»Áπ˚ πƒ‹¡ÀΩ” ’
// πƒ‹Ω” ’÷–∂œ
//USART3->CR1|=1<<8; //PE÷–∂œ πƒ‹
USART3->CR1|=1<<5; //Ω” ’ª∫≥«¯∑«ø’÷–∂œ πƒ‹
USART3_RX_STA=0;
MY_NVIC_Init(3,3,USART3_IRQn,2);//◊È2£¨◊ÓµÕ”≈œ»º∂
//#endif
}
GO3 函数
void GO3(void) {
USART3->CR1 |= 1<5;
}
总结
- 多烧录实践 代码烧到板子上比干瞪眼看有效多了
- 不耻下问 写完电机代码我瞅了半天找不到问题,大佬来看了一眼就解决了。。。唔,@是智造哎牛逼(破音~)
- 正负极 注意正负极,注意正负极,注意正负极!!!
- 😹Detroit: Become Human 故事太让人感动了
- 💪买了 Ring Fit Adventure,每天锻炼,加油
转载:https://blog.csdn.net/KANGYICHEN1/article/details/108985671