赞
踩
目录
L9110s概述
接通VCC,GND 模块电源指示灯亮, 以下资料来源官方,具体根据实际调试
IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转;
IA1输入低电平,IA1输入高电平,【OA1 OB1】电机反转;
IA2输入高电平,IA2输入低电平,【OA2 OB2】电机正转;
IA2输入低电平,IA2输入高电平,【OA2 OB2】电机反转;
接线参考:
B-1A -- PA0
B-1B -- PB1
A-1A -- PA1
A-1B -- PB10
代码实现:
motor.c
- #include "motor.h"
- void goForward(void)
- {
- // 左轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
- // 右轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
- }
- void goBack(void)
- {
- // 左轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
- // 右轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
- }
- void goLeft(void)
- {
- // 左轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
- // 右轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
- }
- void goRight(void)
- {
- // 左轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
- // 右轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
- }
- void stop(void)
- {
- // 左轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
- // 右轮
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
- }
motor.h
- #ifndef __MOTOR_H__
- #define __MOTOR_H__
- #include "main.h"
- void goForward(void);
- void goBack(void);
- void goLeft(void);
- void goRight(void);
- void stop(void);
- #endif
main.c
- #include "motor.h"
-
- //main函数的while循环部分:
- while (1)
- {
- goForward();
- HAL_Delay(1000);
- goBack();
- HAL_Delay(1000);
- goLeft();
- HAL_Delay(1000);
- goRight();
- HAL_Delay(1000);
- stop();
- HAL_Delay(1000);
- }
代码实现:
usart.c
- #include "usart.h"
-
- #include "string.h"
- #include "stdio.h"
- #include "motor.h"
-
- //串口接收缓存(1字节)
- uint8_t buf=0;
-
- //定义最大接收字节数 200,可根据需求调整
- #define UART1_REC_LEN 200
-
- // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
- uint8_t UART1_RX_Buffer[UART1_REC_LEN];
-
- // 接收状态
- // bit15, 接收完成标志
- // bit14, 接收到0x0d
- // bit13~0, 接收到的有效字节数目
- uint16_t UART1_RX_STA=0;
-
- #define SIZE 12
-
- char buffer[SIZE];
-
- // 接收完成回调函数,收到一个数据后,在这里处理
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- // 判断中断是由哪个串口触发的
- if(huart->Instance == USART1)
- {
- // 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
- if((UART1_RX_STA & 0x8000) == 0)
- {
- // 如果已经收到了 0x0d (回车),
- if(UART1_RX_STA & 0x4000)
- {
- // 则接着判断是否收到 0x0a (换行)
- if(buf == 0x0a)
- {
- // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
- UART1_RX_STA |= 0x8000;
-
- // 灯控指令
- if(!strcmp(UART1_RX_Buffer, "M1"))
- goForward();
- else if(!strcmp(UART1_RX_Buffer, "M2"))
- goBack();
- else if(!strcmp(UART1_RX_Buffer, "M3"))
- goLeft();
- else if(!strcmp(UART1_RX_Buffer, "M4"))
- goRight();
- else
- stop();
-
- memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
- UART1_RX_STA = 0;
- }
- else
- // 否则认为接收错误,重新开始
- UART1_RX_STA = 0;
- }
- else // 如果没有收到了 0x0d (回车)
- {
- //则先判断收到的这个字符是否是 0x0d (回车)
- if(buf == 0x0d)
- {
- // 是的话则将 bit14 位置为1
- UART1_RX_STA |= 0x4000;
- }
- else
- {
- // 否则将接收到的数据保存在缓存数组里
- UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
- UART1_RX_STA++;
-
- // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
- if(UART1_RX_STA > UART1_REC_LEN - 1)
- UART1_RX_STA = 0;
- }
- }
- }
- // 重新开启中断
- HAL_UART_Receive_IT(&huart1, &buf, 1);
- }
- }
-
- int fputc(int ch, FILE *f)
- {
- unsigned char temp[1]={ch};
- HAL_UART_Transmit(&huart1,temp,1,0xffff);
- return ch;
- }
原理:
全速前进是LeftCon1A = 0; LeftCon1B = 1;
完全停止是LeftCon1A = 0;LeftCon1B = 0;
那么单位时间内,比如20ms, 有15ms是全速前进,5ms是完全停止, 速度就会比5ms全速前进,15ms完全停止获得的功率多,相应的速度更快!
开发:借用PWM的舵机控制代码
将控制车轮的4个 GPIO 口配置修改如下,否则小车动不起来。
原因:L9110每个控制口需要一高一低才可以动起来,如果PWM有效电平为高电平,则另一个 GPIO口则需要输出低电平才可以驱动轮子。
代码实现:
main.c
- // main函数里
- HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
- while (1)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 8);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 8);
- HAL_Delay(1000);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 10);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 10);
- HAL_Delay(1000);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 15);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 15);
- HAL_Delay(1000);
- }
右转原理: 左轮速度大于右轮
左转原理: 右轮速度大于左轮
左右轮各自调速代码实现:
- // main函数里
- while (1)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,8);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,15);
- HAL_Delay(1000);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,15);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,8);
- HAL_Delay(1000);
- }
接线方式
由于黑色具有较强的吸收能力,当循迹模块发射的红外线照射到黑线时,红外线将会被黑线吸收,导致 循迹模块上光敏三极管处于关闭状态,此时模块上一个LED熄灭。在没有检测到黑线时,模块上两个LED常亮
总结就是一句话,有感应到黑线,D0输出高电平 ,灭灯
硬件接线
代码示例:
- #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
- #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
-
- // 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)
- goLeft();
- if (LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
- goRight();
- if (LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
- stop();
- }
原理:两轮都有速度且一轮速度大于另一轮
代码实现:
- #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
- #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
- // main函数里
- while (1)
- {
- if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,19);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,19);
- }
- if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,15);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,8);
- }
- if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,8);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,15);
- }
- if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
- {
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,0);
- __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,0);
- }
- }
原理和循迹是一样的,循迹红外观朝下,跟随朝前
硬件接线
代码示例:
- #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);
- }
测试数据通过串口发送到上位机
硬件接线
测速模块:
cubeMX配置
代码实现:
- unsigned int speedCnt;
-
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if (GPIO_Pin == GPIO_PIN_14)
- if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
- speedCnt++;
- }
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- printf("speed: %d\r\n", speedCnt);
- speedCnt = 0;
- }
-
- main函数里:
- HAL_TIM_Base_Start_IT(&htim2);
OLED模块介绍:STM32 OLED屏幕显示详解
硬件接线
代码示例:
oled.c
- #include "oled.h"
- #include "i2c.h"
- #include "oledfont.h"
-
- void Oled_Write_Cmd(uint8_t dataCmd)
- {
-
- HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT,
- &dataCmd, 1, 0xff);
- }
-
- void Oled_Write_Data(uint8_t dataData)
- {
- HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT,
- &dataData, 1, 0xff);
- }
-
- void Oled_Init(void){
- Oled_Write_Cmd(0xAE);//--display off
- Oled_Write_Cmd(0x00);//---set low column address
- Oled_Write_Cmd(0x10);//---set high column address
- Oled_Write_Cmd(0x40);//--set start line address
- Oled_Write_Cmd(0xB0);//--set page address
- Oled_Write_Cmd(0x81); // contract control
- Oled_Write_Cmd(0xFF);//--128
- Oled_Write_Cmd(0xA1);//set segment remap
- Oled_Write_Cmd(0xA6);//--normal / reverse
- Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
- Oled_Write_Cmd(0x3F);//--1/32 duty
- Oled_Write_Cmd(0xC8);//Com scan direction
- Oled_Write_Cmd(0xD3);//-set display offset
- Oled_Write_Cmd(0x00);//
-
- Oled_Write_Cmd(0xD5);//set osc division
- Oled_Write_Cmd(0x80);//
-
- Oled_Write_Cmd(0xD8);//set area color mode off
- Oled_Write_Cmd(0x05);//
-
- Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
- Oled_Write_Cmd(0xF1);//
-
- Oled_Write_Cmd(0xDA);//set com pin configuartion
- Oled_Write_Cmd(0x12);//
-
- Oled_Write_Cmd(0xDB);//set Vcomh
- Oled_Write_Cmd(0x30);//
-
- Oled_Write_Cmd(0x8D);//set charge pump enable
- Oled_Write_Cmd(0x14);//
-
- Oled_Write_Cmd(0xAF);//--turn on oled panel
- }
-
- void Oled_Screen_Clear(void){
- char i,n;
- Oled_Write_Cmd (0x20); //set memory addressing mode
- Oled_Write_Cmd (0x02); //page addressing mode
-
- for(i=0;i<8;i++){
- Oled_Write_Cmd(0xb0+i);
- Oled_Write_Cmd(0x00);
- Oled_Write_Cmd(0x10);
- for(n=0;n<128;n++)Oled_Write_Data(0x00);
- }
- }
-
- void Oled_Show_Char(char row,char col,char oledChar){ //row*2-2
- unsigned int i;
- Oled_Write_Cmd(0xb0+(row*2-2)); //page 0
- Oled_Write_Cmd(0x00+(col&0x0f)); //low
- Oled_Write_Cmd(0x10+(col>>4)); //high
- for(i=((oledChar-32)*16);i<((oledChar-32)*16+8);i++){
- Oled_Write_Data(F8X16[i]); //写数据oledTable1
- }
-
- Oled_Write_Cmd(0xb0+(row*2-1)); //page 1
- Oled_Write_Cmd(0x00+(col&0x0f)); //low
- Oled_Write_Cmd(0x10+(col>>4)); //high
- for(i=((oledChar-32)*16+8);i<((oledChar-32)*16+8+8);i++){
- Oled_Write_Data(F8X16[i]); //写数据oledTable1
- }
- }
-
-
- /******************************************************************************/
- // 函数名称:Oled_Show_Char
- // 输入参数:oledChar
- // 输出参数:无
- // 函数功能:OLED显示单个字符
- /******************************************************************************/
- void Oled_Show_Str(char row,char col,char *str){
- while(*str!=0){
- Oled_Show_Char(row,col,*str);
- str++;
- col += 8;
- }
- }
main.c
- extern uint8_t buf;
- unsigned int speedCnt = 0;
- char speedMes[24]; //主程序发送速度数据的字符串缓冲区
-
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if (GPIO_Pin == GPIO_PIN_14)
- if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
- speedCnt++;
- }
-
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- printf("speed: %d\r\n", speedCnt);
- sprintf(speedMes,"speed:%2d cm/s",speedCnt);//串口数据的字符串拼装,speed是格子,每个格子1cm
- Oled_Show_Str(2,2,speedMes);
- speedCnt = 0;
- }
串口透传技术:
代码实现:
整合前面串口控制小车代码,接入蓝牙模块
- if (!strcmp(UART1_RX_Buffer, "M1"))
- {
- goForward();
- HAL_Delay(10);
- }
- else if (!strcmp(UART1_RX_Buffer, "M2"))
- {
- goBack();
- HAL_Delay(10);
- }
- else if (!strcmp(UART1_RX_Buffer, "M3"))
- {
- goLeft();
- HAL_Delay(10);
- }
- else if (!strcmp(UART1_RX_Buffer, "M4"))
- {
- goRight();
- HAL_Delay(10);
- }
- else
- stop();
原理:运用上面讲到的蓝牙模块和测速模块,将两者代码整合
AT指令介绍:
硬件接线
使用方法:
Wifi模块-ESP-01s_esp01s波特率-CSDN博客
原理:运用EC03-DNC4G通信模块
模块介绍:
代码不做修改,直接基于蓝牙小车整合, 4g模块只要做好外网透传就可以了
使用SU-03T / LD3320
具体介绍看我之前写过的博客:SU-03T语音模块的使用_罗小白的干爹的博客-CSDN博客
硬件接线:
循迹小车:
跟随小车:
避障小车:
OLED模块:
语音模块:
cubeMX配置
代码示例:
- #include "main.h"
- #include "i2c.h"
- #include "tim.h"
- #include "gpio.h"
-
- #include "sg90.h"
- #include "sr04.h"
- #include "motor.h"
- #include "oled.h"
-
- #define MIDDLE 0
- #define LEFT 1
- #define RIGHT 2
-
- #define BZ 1
- #define XJ 2
- #define GS 3
-
- #define LeftWheel_Value_XJ HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
- #define RightWheel_Value_XJ HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
-
- #define LeftWheel_Value_GS HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)
- #define RightWheel_Value_GS HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9)
-
- #define A25 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15)
- #define A26 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_13)
- #define A27 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_14)
-
- void SystemClock_Config(void);
-
- char dir;
-
- void xunjiMode()
- {
- if(LeftWheel_Value_XJ == GPIO_PIN_RESET && RightWheel_Value_XJ == GPIO_PIN_RESET)
- goForward();
- if(LeftWheel_Value_XJ == GPIO_PIN_SET && RightWheel_Value_XJ == GPIO_PIN_RESET)
- goLeft();
- if(LeftWheel_Value_XJ == GPIO_PIN_RESET && RightWheel_Value_XJ == GPIO_PIN_SET)
- goRight();
- if(LeftWheel_Value_XJ == GPIO_PIN_SET && RightWheel_Value_XJ == GPIO_PIN_SET)
- stop();
- }
-
- void gensuiMode()
- {
- if(LeftWheel_Value_GS == GPIO_PIN_RESET && RightWheel_Value_GS == GPIO_PIN_RESET)
- goForward();
- if(LeftWheel_Value_GS == GPIO_PIN_SET && RightWheel_Value_GS == GPIO_PIN_RESET)
- goRight();
- if(LeftWheel_Value_GS == GPIO_PIN_RESET && RightWheel_Value_GS == GPIO_PIN_SET)
- goLeft();
- if(LeftWheel_Value_GS == GPIO_PIN_SET && RightWheel_Value_GS == GPIO_PIN_SET)
- stop();
- }
-
- void bizhangMode()
- {
- double disMiddle;
- double disLeft;
- double disRight;
-
- 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);
- }
-
- int main(void)
- {
- int mark = 0;
-
- HAL_Init();
-
-
- SystemClock_Config();
-
-
- MX_GPIO_Init();
- MX_TIM4_Init();
- MX_TIM2_Init();
- MX_I2C1_Init();
-
- initSG90();
- HAL_Delay(1000);
- dir = MIDDLE;
- Oled_Init();
- Oled_Screen_Clear();
- Oled_Show_Str(2,2,"-----Ready----");
-
- while (1)
- {
-
- //满足寻迹模式的条件
- if(A25 == 1 && A26 == 1 && A27 == 0){
- if(mark != XJ){
- Oled_Screen_Clear();
- Oled_Show_Str(2,2,"-----XunJi----");
- }
- mark = XJ;
- xunjiMode();
- }
- //满足跟随模式的条件
- if(A25 == 0 && A26 == 1 && A27 == 1){
- if(mark != GS){
- Oled_Screen_Clear();
- Oled_Show_Str(2,2,"-----GenSui----");
- }
- mark = GS;
- gensuiMode();
- }
- //满足避障模式的条件
- if(A25 == 1 && A26 == 0 && A27 == 1){
- if(mark != BZ){
- Oled_Screen_Clear();
- Oled_Show_Str(2,2,"-----BiZhang----");
- }
- mark = BZ;
- bizhangMode();
- }
- }
- }
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。