赞
踩

原理和循迹是一样的,循迹红外观朝下,跟随朝前
硬件接线
代码示例:
- #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5)
- #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6)
- // main函数里
- while (1)
- {
- if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
- goForward();
- if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
- goRight();
- if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
- goLeft();
- if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
- stop();
- }
使用超声波模块,型号:HC-SR04

时序图:

1. 什么是舵机
如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制 用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等 常见的有0-90°、0-180°、0-360°

2. 怎么控制舵机
向黄色信号线“灌入”PWM信号
PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右
确定周期/频率:

如果周期为20ms,则 PSC=7199,ARR=199
角度控制
0.5ms-------------0度; 2.5% 对应函数中CCRx为5
1.0ms------------45度; 5.0% 对应函数中CCRx为10
1.5ms------------90度; 7.5% 对应函数中CCRx为15
2.0ms-----------135度; 10.0% 对应函数中CCRx为20
2.5ms-----------180度; 12.5% 对应函数中CCRx为25
硬件接线
cubeMX配置
代码实现
sg90.c
- #include "sg90.h"
- #include "gpio.h"
- #include "tim.h"
- void initSG90(void)
- {
- HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4); //启动定时器4
- __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 17); //将舵机置为90度
- }
- void sgMiddle(void)
- {
- __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 17); //将舵机置为90度
- }
- void sgRight(void)
- {
- __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度
- }
- void sgLeft(void)
- {
- __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 25); //将舵机置为180度
- }

sg90.h
- #ifndef __SG90_H__
- #define __SG90_H__
-
- void initSG90(void);
- void sgMiddle(void);
- void sgRight(void);
- void sgLeft(void);
-
- #endif
main.c
- initSG90();
- HAL_Delay(1000);
-
- while (1)
- {
- sgLeft();
- HAL_Delay(1000);
- sgMiddle();
- HAL_Delay(1000);
- sgRight();
- HAL_Delay(1000);
- sgMiddle();
- HAL_Delay(1000);
- }
封装超声波传感器
超声波模块接线:
cubeMX配置


代码实现
sr04.c
- #include "sr04.h"
- #include "gpio.h"
- #include "tim.h"
-
- //使用TIM2来做us级延时函数
- void TIM2_Delay_us(uint16_t n_us)
- {
- /* 使能定时器2计数 */
- __HAL_TIM_ENABLE(&htim2);
- __HAL_TIM_SetCounter(&htim2, 0);
- while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
- /* 关闭定时器2计数 */
- __HAL_TIM_DISABLE(&htim2);
- }
-
- double get_distance(void)
- {
- int cnt=0;
- //1. Trig ,给Trig端口至少10us的高电平
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);//拉高
- TIM2_Delay_us(20);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);//拉低
-
- //2. echo由低电平跳转到高电平,表示开始发送波
- //波发出去的那一下,开始启动定时器
- while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET);//等待输入电平拉高
- HAL_TIM_Base_Start(&htim2);
- __HAL_TIM_SetCounter(&htim2,0);
-
- //3. 由高电平跳转回低电平,表示波回来了
- while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET);//等待输入电平变低
- //波回来的那一下,我们开始停止定时器
- HAL_TIM_Base_Stop(&htim2);
-
- //4. 计算出中间经过多少时间
- cnt = __HAL_TIM_GetCounter(&htim2);
-
- //5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
- return (cnt*340/2*0.000001*100); //单位:cm
- }

sr04.h
- #ifndef __SR04_H__
- #define __SR04_H__
-
- double get_distance(void);
-
- #endif
main.c
- while (1)
- {
- if(dir != MIDDLE){
- sgMiddle();
- dir = MIDDLE;
- HAL_Delay(300);
- }
- disMiddle = get_distance();
-
- if(disMiddle > 35){
- //前进
- }
- else
- {
- //停止
- //测左边距离
- sgLeft();
-
- HAL_Delay(300);
- disLeft = get_distance();
-
- sgMiddle();
- HAL_Delay(300);
-
- sgRight();
- dir = RIGHT;
- HAL_Delay(300);
- disRight = get_distance();
- }
- }

封装电机驱动
代码实现:
- while (1)
- {
- if(dir != MIDDLE){
- sgMiddle();
- dir = MIDDLE;
- HAL_Delay(300);
- }
- disMiddle = get_distance();
-
- if(disMiddle > 35){
- //前进
- goForward();
- }else if(disMiddle < 10){
- goBack();
- }else
- {
- //停止
- stop();
- //测左边距离
- sgLeft();
- HAL_Delay(300);
- disLeft = get_distance();
-
- sgMiddle();
- HAL_Delay(300);
-
- sgRight();
- dir = RIGHT;
- HAL_Delay(300);
- disRight = get_distance();
-
- if(disLeft < disRight){
- goRight();
- HAL_Delay(150);
- stop();
- }
- if(disRight < disLeft){
- goLeft();
- HAL_Delay(150);
- stop();
- }
- }
- HAL_Delay(50);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。