当前位置:   article > 正文

STM32智能小车项目

stm32智能小车

1、小车电机驱动

1.接线:L90110S的MOTORA控制小车左轮电机

               L9110S的MOTORB控制小车右轮电机     

引脚设计: B-1A -- PB0          B-2A -- PB1      A-1A -- PB2          A-1B -- PB10

2.STM32CubeMX创建工程,设置PB0,PB1,PB2,PB10引脚为OUTPUT,并拉高电平。

3.在项目目录的/Core/Src新建motor.c,/Core/Inc新建motor.h,添加进工程。

5.motor.h

  1. #ifndef __MOTOR_H__
  2. #define __MOTOR_H__
  3. void goForward(void);
  4. void goBack(void);
  5. void goLeft(void);
  6. void goRight(void);
  7. void stop(void);
  8. #endif

motor.c

  1. #include "motor.h"
  2. #include "gpio.h"
  3. void goForward(void)
  4. {
  5. // 左轮
  6. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
  7. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
  8. // 右轮
  9. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
  10. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
  11. }
  12. void goBack(void)
  13. {
  14. // 左轮
  15. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
  16. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
  17. // 右轮
  18. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
  19. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
  20. }
  21. void goLeft(void)
  22. {
  23. // 左轮
  24. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
  25. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
  26. // 右轮
  27. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
  28. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
  29. }
  30. void goRight(void)
  31. {
  32. // 左轮
  33. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
  34. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
  35. // 右轮
  36. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
  37. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
  38. }
  39. void stop(void)
  40. {
  41. // 左轮
  42. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
  43. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
  44. // 右轮
  45. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
  46. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
  47. }

main.c测试:

  1. #include "motor.h"
  2. //main函数部分:
  3. while (1)
  4. {
  5. goForward();
  6. HAL_Delay(1000);
  7. goBack();
  8. HAL_Delay(1000);
  9. goLeft();
  10. HAL_Delay(1000);
  11. goRight();
  12. HAL_Delay(1000);
  13. stop();
  14. HAL_Delay(1000);
  15. }

2、串口控制小车

STM32CUBEMX打开串口USART1和串口1中断

usart.c:重写fputc和串口接收中断回调函数

  1. #include "string.h"
  2. #include "stdio.h"
  3. #include "motor.h"
  4. //串口接收缓存(1字节)
  5. uint8_t buf=0;
  6. //定义最大接收字节数 200,可根据需求调整
  7. #define UART1_REC_LEN 200
  8. // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
  9. uint8_t UART1_RX_Buffer[UART1_REC_LEN];
  10. // 接收状态
  11. // bit15, 接收完成标志
  12. // bit14, 接收到0x0d
  13. // bit13~0, 接收到的有效字节数目
  14. uint16_t UART1_RX_STA=0;
  15. #define SIZE 12
  16. char buffer[SIZE];
  17. // 接收完成回调函数,收到一个数据后,在这里处理
  18. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  19. {
  20. // 判断中断是由哪个串口触发的
  21. if(huart->Instance == USART1)
  22. {
  23. // 判断接收是否完成(UART1_RX_STA bit15 位是否为1
  24. if((UART1_RX_STA & 0x8000) == 0)
  25. {
  26. // 如果已经收到了 0x0d (回车),
  27. if(UART1_RX_STA & 0x4000)
  28. {
  29. // 则接着判断是否收到 0x0a (换行)
  30. if(buf == 0x0a)
  31. {
  32. // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
  33. UART1_RX_STA |= 0x8000;
  34. // 控制指令
  35. if(!strcmp(UART1_RX_Buffer, "M1"))
  36. goForward();
  37. else if(!strcmp(UART1_RX_Buffer, "M2"))
  38. goBack();
  39. else if(!strcmp(UART1_RX_Buffer, "M3"))
  40. goLeft();
  41. else if(!strcmp(UART1_RX_Buffer, "M4"))
  42. goRight();
  43. else
  44. stop();
  45. memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
  46. UART1_RX_STA = 0;
  47. }
  48. else
  49. // 否则认为接收错误,重新开始
  50. UART1_RX_STA = 0;
  51. }
  52. else // 如果没有收到了 0x0d (回车)
  53. {
  54. //则先判断收到的这个字符是否是 0x0d (回车)
  55. if(buf == 0x0d)
  56. {
  57. // 是的话则将 bit14 位置为1
  58. UART1_RX_STA |= 0x4000;
  59. }
  60. else
  61. {
  62. // 否则将接收到的数据保存在缓存数组里
  63. UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
  64. UART1_RX_STA++;
  65. // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
  66. if(UART1_RX_STA > UART1_REC_LEN - 1)
  67. UART1_RX_STA = 0;
  68. }
  69. }
  70. }
  71. // 重新开启中断
  72. HAL_UART_Receive_IT(&huart1, &buf, 1);
  73. }
  74. }
  75. int fputc(int ch, FILE *f)
  76. {
  77. unsigned char temp[1]={ch};
  78. HAL_UART_Transmit(&huart1,temp,1,0xffff);
  79. return ch;
  80. }

main.c:

  1. #include "motor.h"
  2. extern uint8_t buf;
  3. main函数:
  4. HAL_UART_Receive_IT(&huart1,&buf,1);//开启串口接收中断;

3、点动控制小车

STM32CUBEMX提高滴答定时器的优先级:

 修改usart.c

  1. #include "string.h"
  2. #include "stdio.h"
  3. #include "motor.h"
  4. //串口接收缓存(1字节)
  5. uint8_t buf=0;
  6. //定义最大接收字节数 200,可根据需求调整
  7. #define UART1_REC_LEN 200
  8. // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
  9. uint8_t UART1_RX_Buffer[UART1_REC_LEN];
  10. // 接收状态
  11. // bit15, 接收完成标志
  12. // bit14, 接收到0x0d
  13. // bit13~0, 接收到的有效字节数目
  14. uint16_t UART1_RX_STA=0;
  15. #define SIZE 12
  16. char buffer[SIZE];
  17. // 接收完成回调函数,收到一个数据后,在这里处理
  18. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  19. {
  20. // 判断中断是由哪个串口触发的
  21. if(huart->Instance == USART1)
  22. {
  23. // 判断接收是否完成(UART1_RX_STA bit15 位是否为1
  24. if((UART1_RX_STA & 0x8000) == 0)
  25. {
  26. // 如果已经收到了 0x0d (回车),
  27. if(UART1_RX_STA & 0x4000)
  28. {
  29. // 则接着判断是否收到 0x0a (换行)
  30. if(buf == 0x0a)
  31. {
  32. // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
  33. UART1_RX_STA |= 0x8000;
  34. // 控制指令
  35. if(!strcmp(UART1_RX_Buffer, "M1"))
  36. {
  37. goForward();
  38. HAL_Delay(10);
  39. }
  40. else if(!strcmp(UART1_RX_Buffer, "M2"))
  41. {
  42. goBack();
  43. HAL_Delay(10);
  44. }
  45. else if(!strcmp(UART1_RX_Buffer, "M3"))
  46. {
  47. goLeft();
  48. HAL_Delay(10);
  49. }
  50. else if(!strcmp(UART1_RX_Buffer, "M4"))
  51. {
  52. goRight();
  53. HAL_Delay(10);
  54. }
  55. else
  56. stop();
  57. memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
  58. UART1_RX_STA = 0;
  59. }
  60. else
  61. // 否则认为接收错误,重新开始
  62. UART1_RX_STA = 0;
  63. }
  64. else // 如果没有收到了 0x0d (回车)
  65. {
  66. //则先判断收到的这个字符是否是 0x0d (回车)
  67. if(buf == 0x0d)
  68. {
  69. // 是的话则将 bit14 位置为1
  70. UART1_RX_STA |= 0x4000;
  71. }
  72. else
  73. {
  74. // 否则将接收到的数据保存在缓存数组里
  75. UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
  76. UART1_RX_STA++;
  77. // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
  78. if(UART1_RX_STA > UART1_REC_LEN - 1)
  79. UART1_RX_STA = 0;
  80. }
  81. }
  82. }
  83. // 重新开启中断
  84. HAL_UART_Receive_IT(&huart1, &buf, 1);
  85. }
  86. }
  87. int fputc(int ch, FILE *f)
  88. {
  89. unsigned char temp[1]={ch};
  90. HAL_UART_Transmit(&huart1,temp,1,0xffff);
  91. return ch;
  92. }

mian.c

  1. // main函数里
  2. HAL_NVIC_SetPriority(SysTick_IRQn,0,0); //或者通过cubeMX配置
  3. while(1)
  4. {
  5. stop();
  6. }

4、PWM调速

硬件接线 B-1A -- PA0          B-2A -- PB1         A-1A -- PA1         A-1B -- PB10

STM32CUBEMX打开TM2的PWM:

 PSC配置7199,ARR配置199,T=20ms;

将PB0 PB1 PB2 PB10 改为低电平(电机需要一高一低才可以驱动);

main.c

  1. //main函数:
  2. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  3. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
  4. /* USER CODE END 2 */
  5. /* Infinite loop */
  6. /* USER CODE BEGIN WHILE */
  7. while (1)
  8. {
  9. /* USER CODE END WHILE */
  10. /* USER CODE BEGIN 3 */
  11. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,80);
  12. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,80);
  13. HAL_Delay(1000);
  14. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,100);
  15. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,100);
  16. HAL_Delay(1000);
  17. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,150);
  18. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,150);
  19. HAL_Delay(1000);
  20. }

5、左右轮各自调速

  1. //main函数:
  2. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  3. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
  4. /* USER CODE END 2 */
  5. /* Infinite loop */
  6. /* USER CODE BEGIN WHILE */
  7. while (1)
  8. {
  9. /* USER CODE END WHILE */
  10. /* USER CODE BEGIN 3 */
  11. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,80);
  12. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,150);
  13. HAL_Delay(1000);
  14. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,150);
  15. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,80);
  16. HAL_Delay(1000);
  17. }

6、循迹小车

引脚设计: B-1A -- PB0         B-2A -- PB1         A-1A -- PB2         A-1B -- PB10

循迹模块左:PB3 

循迹模块右:PB4

循迹模块发射红外线,黑色有较强的吸收能力,

遇到黑线,没有红外返回,输出高电平,LED灭;

遇到白线,有红外返回,输出低电平,LED亮;

main.c

  1. #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
  2. #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
  3. //main函数:
  4. while (1)
  5. {
  6. /* USER CODE END WHILE */
  7. /* USER CODE BEGIN 3 */
  8. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
  9. goForward();
  10. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
  11. goLeft();
  12. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
  13. goRight();
  14. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
  15. stop();
  16. }

7. 循迹小车解决转弯平滑问题

硬件接线:       B-1A -- PA0          B-2A -- PB1         A-1A -- PA1         A-1B -- PB10

循迹模块(左) PB3

循迹模块(右) PB4

 PSC配置7199,ARR配置199,T=20ms;

将PB0 PB1 PB2 PB10 改为低电平(电机需要一高一低才可以驱动);

  1. #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
  2. #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
  3. // main函数里
  4. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  5. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
  6. while (1)
  7. {
  8. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
  9. {
  10. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,190);
  11. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,190);
  12. }
  13. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
  14. {
  15. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,150);
  16. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,80);
  17. }
  18. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
  19. {
  20. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,80);
  21. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,150);
  22. }
  23. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
  24. {
  25. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,0);
  26. __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,0);
  27. }
  28. }

8. 跟随小车

硬件接线 B-1A -- PB0          B-2A -- PB1         A-1A -- PB2         A-1B -- PB10

跟随模块(左) -- PB5

跟随模块(右) -- PB6

原理跟循迹模块相同,循迹模块红外发出朝下,跟随模块是朝前;

有物体时,红外返回,输出低电平,LED亮;

没有物体,红外不返回,输出高电平,LED灭

  1. #define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5)
  2. #define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6)
  3. // main函数里
  4. while (1)
  5. {
  6. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
  7. goForward();
  8. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
  9. goRight();
  10. if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
  11. goLeft();
  12. if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
  13. stop();
  14. }

9. 摇头避障小车

9.1 封装摇头功能

硬件接线 sg90 -- PB9

CUBEMX配置:

 sg90.c

  1. #include "sg90.h"
  2. #include "gpio.h"
  3. #include "tim.h"
  4. void initSG90(void)
  5. {
  6. HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4); //启动定时器4
  7. __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15); //将舵机置为90
  8. }
  9. void sgMiddle(void)
  10. {
  11. __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15); //将舵机置为90
  12. }
  13. void sgRight(void)
  14. {
  15. __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0
  16. }
  17. void sgLeft(void)
  18. {
  19. __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 25); //将舵机置为180
  20. }

sg90.h

  1. #ifndef __SG90_H__
  2. #define __SG90_H__
  3. void initSG90(void);
  4. void sgMiddle(void);
  5. void sgRight(void);
  6. void sgLeft(void);
  7. #endif

main.c

  1. initSG90();
  2. HAL_Delay(1000);
  3. while (1)
  4. {
  5. sgLeft();
  6. HAL_Delay(1000);
  7. sgMiddle();
  8. HAL_Delay(1000);
  9. sgRight();
  10. HAL_Delay(1000);
  11. sgMiddle();
  12. HAL_Delay(1000);
  13. }

9.2 封装超声波传感器

超声波模块: Trig   --    PB7

                        Echo     -- PB8

cubeMX配置

sr04.c

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

sr04.h

  1. #ifndef __SR04_H__
  2. #define __SR04_H__
  3. double get_distance(void);
  4. #endif

main.c

  1. #define MIDDLE 0
  2. #define LEFT 1
  3. #define RIGHT 2
  4. char dir;
  5. double disMiddle;
  6. double disLeft;
  7. double disRight;
  8. while (1)
  9. {
  10. if(dir != MIDDLE){
  11. sgMiddle();
  12. dir = MIDDLE;
  13. HAL_Delay(300);
  14. }
  15. disMiddle = get_distance();
  16. if(disMiddle > 35){
  17. //前进
  18. }
  19. else
  20. {
  21. //停止
  22. //测左边距离
  23. sgLeft();
  24. HAL_Delay(300);
  25. disLeft = get_distance();
  26. sgMiddle();
  27. HAL_Delay(300);
  28. sgRight();
  29. dir = RIGHT;
  30. HAL_Delay(300);
  31. disRight = get_distance();
  32. }
  33. }

9.3 封装电机驱动

main.c

  1. while (1)
  2. {
  3. /* USER CODE END WHILE */
  4. /* USER CODE BEGIN 3 */
  5. if(dir != MIDDLE){
  6. sgMiddle();
  7. dir = MIDDLE;
  8. HAL_Delay(300);
  9. }
  10. disMiddle = get_distance();
  11. if(disMiddle > 35){
  12. //前进
  13. goForward();
  14. }else if(disMiddle < 10){
  15. goBack();
  16. }else
  17. {
  18. //停止
  19. stop();
  20. //测左边距离
  21. sgLeft();
  22. HAL_Delay(300);
  23. disLeft = get_distance();
  24. sgMiddle();
  25. HAL_Delay(300);
  26. sgRight();
  27. dir = RIGHT;
  28. HAL_Delay(300);
  29. disRight = get_distance();
  30. if(disLeft < disRight){
  31. goRight();
  32. HAL_Delay(150);
  33. stop();
  34. }
  35. if(disRight < disLeft){
  36. goLeft();
  37. HAL_Delay(150);
  38. stop();
  39. }
  40. }
  41. HAL_Delay(50);
  42. }

10. 小车测速

在项目2的基础上修改:

测速模块: VCC -- 3.3V 不能接5V,否则遮挡一次会触发3次中断 OUT -- PB14

 

  1. unsigned int speedCnt;
  2. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  3. {
  4. if (GPIO_Pin == GPIO_PIN_14)
  5. if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
  6. speedCnt++;
  7. }
  8. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  9. {
  10. printf("speed: %d\r\n", speedCnt);
  11. speedCnt = 0;
  12. }
  13. main函数里:
  14. HAL_TIM_Base_Start_IT(&htim2);

 11.  串口控制小车并使用Oled显示速度

在项目10基础上修改:添加oled.c oled.h oledfont.h

硬件接线 SCL -- PB6 SDA -- PB7

oled.c

  1. #include "oled.h"
  2. #include "i2c.h"
  3. #include "oledfont.h"
  4. void Oled_Write_Cmd(uint8_t dataCmd)
  5. {
  6. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT,
  7. &dataCmd, 1, 0xff);
  8. }
  9. void Oled_Write_Data(uint8_t dataData)
  10. {
  11. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT,
  12. &dataData, 1, 0xff);
  13. }
  14. void Oled_Init(void){
  15. Oled_Write_Cmd(0xAE);//--display off
  16. Oled_Write_Cmd(0x00);//---set low column address
  17. Oled_Write_Cmd(0x10);//---set high column address
  18. Oled_Write_Cmd(0x40);//--set start line address
  19. Oled_Write_Cmd(0xB0);//--set page address
  20. Oled_Write_Cmd(0x81); // contract control
  21. Oled_Write_Cmd(0xFF);//--128
  22. Oled_Write_Cmd(0xA1);//set segment remap
  23. Oled_Write_Cmd(0xA6);//--normal / reverse
  24. Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
  25. Oled_Write_Cmd(0x3F);//--1/32 duty
  26. Oled_Write_Cmd(0xC8);//Com scan direction
  27. Oled_Write_Cmd(0xD3);//-set display offset
  28. Oled_Write_Cmd(0x00);//
  29. Oled_Write_Cmd(0xD5);//set osc division
  30. Oled_Write_Cmd(0x80);//
  31. Oled_Write_Cmd(0xD8);//set area color mode off
  32. Oled_Write_Cmd(0x05);//
  33. Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
  34. Oled_Write_Cmd(0xF1);//
  35. Oled_Write_Cmd(0xDA);//set com pin configuartion
  36. Oled_Write_Cmd(0x12);//
  37. Oled_Write_Cmd(0xDB);//set Vcomh
  38. Oled_Write_Cmd(0x30);//
  39. Oled_Write_Cmd(0x8D);//set charge pump enable
  40. Oled_Write_Cmd(0x14);//
  41. Oled_Write_Cmd(0xAF);//--turn on oled panel
  42. }
  43. void Oled_Screen_Clear(void){
  44. char i,n;
  45. Oled_Write_Cmd (0x20); //set memory addressing mode
  46. Oled_Write_Cmd (0x02); //page addressing mode
  47. for(i=0;i<8;i++){
  48. Oled_Write_Cmd(0xb0+i); //éè??ò3μ??·£¨0~7£?
  49. Oled_Write_Cmd(0x00); //éè????ê??????aáDμíμ??·
  50. Oled_Write_Cmd(0x10); //éè????ê??????aáD??μ??·
  51. for(n=0;n<128;n++)Oled_Write_Data(0x00);
  52. }
  53. }
  54. void Oled_Show_Char(char row,char col,char oledChar){ //row*2-2
  55. unsigned int i;
  56. Oled_Write_Cmd(0xb0+(row*2-2)); //page 0
  57. Oled_Write_Cmd(0x00+(col&0x0f)); //low
  58. Oled_Write_Cmd(0x10+(col>>4)); //high
  59. for(i=((oledChar-32)*16);i<((oledChar-32)*16+8);i++){
  60. Oled_Write_Data(F8X16[i]); //写数据oledTable1
  61. }
  62. Oled_Write_Cmd(0xb0+(row*2-1)); //page 1
  63. Oled_Write_Cmd(0x00+(col&0x0f)); //low
  64. Oled_Write_Cmd(0x10+(col>>4)); //high
  65. for(i=((oledChar-32)*16+8);i<((oledChar-32)*16+8+8);i++){
  66. Oled_Write_Data(F8X16[i]); //写数据oledTable1
  67. }
  68. }
  69. /******************************************************************************/
  70. // 函数名称:Oled_Show_Char
  71. // 输入参数:oledChar
  72. // 输出参数:无
  73. // 函数功能:OLED显示单个字符
  74. /******************************************************************************/
  75. void Oled_Show_Str(char row,char col,char *str){
  76. while(*str!=0){
  77. Oled_Show_Char(row,col,*str);
  78. str++;
  79. col += 8;
  80. }
  81. }

oled.h

  1. #ifndef __OLED_H__
  2. #define __OLED_H__
  3. void Oled_Init(void);
  4. void Oled_Screen_Clear(void);
  5. void Oled_Show_Char(char row,char col,char oledChar);
  6. void Oled_Show_Str(char row,char col,char *str);
  7. #endif

olefont.h

  1. const unsigned char F8X16[]=
  2. {
  3. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  4. 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  5. 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  6. 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  7. 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  8. 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  9. 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  10. 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  11. 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  12. 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  13. 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  14. 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  15. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  16. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  17. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  18. 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  19. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  20. 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  21. 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  22. 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  23. 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  24. 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  25. 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  26. 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  27. 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  28. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  29. 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  30. 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  31. 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  32. 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  33. 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  34. 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  35. 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  36. 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  37. 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  38. 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  39. 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  40. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  41. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  42. 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  43. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  44. 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  45. 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  46. 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  47. 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  48. 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  49. 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  50. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  51. 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  52. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  53. 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  54. 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  55. 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  56. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  57. 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  58. 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  59. 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  60. 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  61. 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  62. 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  63. 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  64. 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  65. 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  66. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  67. 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  68. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  69. 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  70. 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  71. 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  72. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  73. 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  74. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  75. 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  76. 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  77. 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  78. 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  79. 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  80. 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  81. 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  82. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  83. 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  84. 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  85. 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  86. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  87. 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  88. 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  89. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  90. 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  91. 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  92. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  93. 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  94. 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  95. 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  96. 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  97. 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
  98. };

mian.c

  1. #include "motor.h"
  2. #include "stdio.h"
  3. #include "oled.h"
  4. extern uint8_t buf;
  5. unsigned int speedCnt=0;
  6. char speedMes[24];
  7. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  8. {
  9. if (GPIO_Pin == GPIO_PIN_14)
  10. if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
  11. speedCnt++;
  12. }
  13. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  14. {
  15. printf("speed: %d\r\n", speedCnt);//每一秒钟打印一次速度
  16. sprintf(speedMes,"%2d cm/s",speedCnt);
  17. Oled_Show_Str(2,2,speedMes);
  18. speedCnt = 0;
  19. }
  20. HAL_UART_Receive_IT(&huart1,&buf,1);
  21. HAL_TIM_Base_Start_IT(&htim2);//开启定时器
  22. Oled_Init();
  23. Oled_Screen_Clear();

12. Wi-Fi测速小车并本地Oled显示

硬件接线 把esp8266插进串口1

提高滴答定时器的优先级:

 

添加esp8266.c,esp8266.h

  1. #ifndef __ESP8266_H__
  2. #define __ESP8266_H__
  3. void initWifi_AP(void);
  4. void waitConnect(void);
  5. #endif
  1. #include "esp8266.h"
  2. #include "stdio.h"
  3. #include "usart.h"
  4. //工作在路由模式
  5. char LYMO[]="AT+CWMODE=2\r\n";
  6. //使能多链接
  7. char DLJ[]="AT+CIPMUX=1\r\n";
  8. //建立TCPServer
  9. char JLFW[]="AT+CPISERVER=1\r\n";
  10. //发送数据
  11. char FSSJ[]="AT+CPISEND=0,5\r\n";
  12. char AT_OK_Flag = 0;
  13. char AT_Connect_Net_Flag=0;
  14. char Client_Connect_Flag =0;
  15. void initWifi_AP()
  16. {
  17. printf(LYMO);
  18. while(!AT_OK_Flag) HAL_Delay(50);
  19. AT_OK_Flag=0;
  20. printf(DLJ);
  21. while(!AT_OK_Flag) HAL_Delay(50);
  22. AT_OK_Flag=0;
  23. }
  24. void waitConnect()
  25. {
  26. printf(JLFW);
  27. while(!Client_Connect_Flag) HAL_Delay(50);
  28. AT_OK_Flag=0;
  29. }
  1. usart.c
  2. #include "string.h"
  3. #include "stdio.h"
  4. #include "motor.h"
  5. #include "esp8266.h"
  6. extern char AT_OK_Flag ;
  7. extern char AT_Connect_Net_Flag;
  8. extern char Client_Connect_Flag ;
  9. //串口接收缓存(1字节)
  10. uint8_t buf=0;
  11. //定义最大接收字节数 200,可根据需求调整
  12. #define UART1_REC_LEN 200
  13. // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
  14. uint8_t UART1_RX_Buffer[UART1_REC_LEN];
  15. // 接收状态
  16. // bit15, 接收完成标志
  17. // bit14, 接收到0x0d
  18. // bit13~0, 接收到的有效字节数目
  19. uint16_t UART1_RX_STA=0;
  20. #define SIZE 12
  21. char buffer[SIZE];
  22. // 接收完成回调函数,收到一个数据后,在这里处理
  23. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  24. {
  25. // 判断中断是由哪个串口触发的
  26. if(huart->Instance == USART1)
  27. {
  28. // 判断接收是否完成(UART1_RX_STA bit15 位是否为1
  29. if((UART1_RX_STA & 0x8000) == 0)
  30. {
  31. // 如果已经收到了 0x0d (回车),
  32. if(UART1_RX_STA & 0x4000)
  33. {
  34. // 则接着判断是否收到 0x0a (换行)
  35. if(buf == 0x0a)
  36. {
  37. // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
  38. UART1_RX_STA |= 0x8000;
  39. if(!strcmp(UART1_RX_Buffer,"WIFI GOT UP"))
  40. AT_Connect_Net_Flag=1;
  41. if(!strcmp(UART1_RX_Buffer,"OK"))
  42. AT_OK_Flag =1;
  43. if(!strcmp(UART1_RX_Buffer,"0,CONNECT"))
  44. AT_Connect_Net_Flag=1;
  45. // 控制指令
  46. if(!strcmp(UART1_RX_Buffer, "+IPD,0,4:M1"))
  47. goForward();
  48. else if(!strcmp(UART1_RX_Buffer, "+IPD,0,4:M2"))
  49. goBack();
  50. else if(!strcmp(UART1_RX_Buffer, "+IPD,0,4:M3"))
  51. goLeft();
  52. else if(!strcmp(UART1_RX_Buffer, "+IPD,0,4:M4"))
  53. goRight();
  54. else if((!strcmp(UART1_RX_Buffer, "+IPD,0,4:M0")))
  55. stop();
  56. memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
  57. UART1_RX_STA = 0;
  58. }
  59. else
  60. // 否则认为接收错误,重新开始
  61. UART1_RX_STA = 0;
  62. }
  63. else // 如果没有收到了 0x0d (回车)
  64. {
  65. //则先判断收到的这个字符是否是 0x0d (回车)
  66. if(buf == 0x0d)
  67. {
  68. // 是的话则将 bit14 位置为1
  69. UART1_RX_STA |= 0x4000;
  70. }
  71. else
  72. {
  73. // 否则将接收到的数据保存在缓存数组里
  74. UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
  75. UART1_RX_STA++;
  76. // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
  77. if(UART1_RX_STA > UART1_REC_LEN - 1)
  78. UART1_RX_STA = 0;
  79. }
  80. }
  81. }
  82. // 重新开启中断
  83. HAL_UART_Receive_IT(&huart1, &buf, 1);
  84. }
  85. }
  86. int fputc(int ch, FILE *f)
  87. {
  88. unsigned char temp[1]={ch};
  89. HAL_UART_Transmit(&huart1,temp,1,0xffff);
  90. return ch;
  91. }

main.c

  1. #include "motor.h"
  2. #include "stdio.h"
  3. #include "oled.h"
  4. #include "esp8266.h"
  5. extern char FSSJ[];
  6. extern uint8_t buf;
  7. unsigned int speedCnt=0;
  8. char speedMes[24];
  9. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  10. {
  11. if (GPIO_Pin == GPIO_PIN_14)
  12. if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
  13. speedCnt++;
  14. }
  15. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  16. {
  17. printf(FSSJ);
  18. HAL_Delay(50);
  19. sprintf(speedMes,"%2d cm/s",speedCnt);
  20. printf(speedMes);
  21. Oled_Show_Str(2,2,speedMes);
  22. speedCnt = 0;
  23. }
  24. main函数:
  25. HAL_UART_Receive_IT(&huart1,&buf,1);
  26. HAL_TIM_Base_Start_IT(&htim2);//开启定时器
  27. Oled_Init();
  28. Oled_Screen_Clear();
  29. HAL_Delay(1000);
  30. initWifi_AP();
  31. waitConnect();

13. 语音控制小车

 硬件接线 循迹小车: 循迹模块(左) -- PB3         循迹模块(右) -- PB4

                跟随小车: 跟随模块(左) -- PA8         跟随模块(右) -- PA9

                避障小车: sg90:PB9         Trig:PA10         Echo:PA11

                OLED模块: SCL -- PB6         SDA -- PB7

                语音模块: A25 -- PA15 (跟随)         A26 -- PA13 (避障)     A27 -- PA14 (循迹)

CUBEMX配置:

 SU-03配置:

  1. #include "sg90.h"
  2. #include "sr04.h"
  3. #include "motor.h"
  4. #include "oled.h"
  5. #include "string.h"
  6. #define MIDDLE 0
  7. #define LEFT 1
  8. #define RIGHT 2
  9. #define BZ 1
  10. #define XJ 2
  11. #define GS 3
  12. #define LeftWheel_Value_XJ HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)
  13. #define RightWheel_Value_XJ HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
  14. #define LeftWheel_Value_GS HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)
  15. #define RightWheel_Value_GS HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9)
  16. #define XJ_VALUE HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_14)
  17. #define GS_VALUE HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15)
  18. #define BZ_VALUE HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_13)
  19. char dir;
  20. void xunjiMode()
  21. {
  22. if(LeftWheel_Value_XJ == GPIO_PIN_RESET && RightWheel_Value_XJ == GPIO_PIN_RESET)
  23. goForward();
  24. if(LeftWheel_Value_XJ == GPIO_PIN_SET && RightWheel_Value_XJ == GPIO_PIN_RESET)
  25. goLeft();
  26. if(LeftWheel_Value_XJ == GPIO_PIN_RESET && RightWheel_Value_XJ == GPIO_PIN_SET)
  27. goRight();
  28. if(LeftWheel_Value_XJ == GPIO_PIN_SET && RightWheel_Value_XJ == GPIO_PIN_SET)
  29. stop();
  30. }
  31. void gensuiMode()
  32. {
  33. if(LeftWheel_Value_GS == GPIO_PIN_RESET && RightWheel_Value_GS == GPIO_PIN_RESET)
  34. goForward();
  35. if(LeftWheel_Value_GS == GPIO_PIN_SET && RightWheel_Value_GS == GPIO_PIN_RESET)
  36. goRight();
  37. if(LeftWheel_Value_GS == GPIO_PIN_RESET && RightWheel_Value_GS == GPIO_PIN_SET)
  38. goLeft();
  39. if(LeftWheel_Value_GS == GPIO_PIN_SET && RightWheel_Value_GS == GPIO_PIN_SET)
  40. stop();
  41. }
  42. void bizhangMode()
  43. {
  44. double disMiddle;
  45. double disLeft;
  46. double disRight;
  47. if(dir != MIDDLE){
  48. sgMiddle();
  49. dir = MIDDLE;
  50. HAL_Delay(300);
  51. }
  52. disMiddle = get_distance();
  53. if(disMiddle > 35){
  54. //前进
  55. goForward();
  56. }else if(disMiddle < 10){
  57. goBack();
  58. }else
  59. {
  60. //停止
  61. stop();
  62. //测左边距离
  63. sgLeft();
  64. HAL_Delay(300);
  65. disLeft = get_distance();
  66. sgMiddle();
  67. HAL_Delay(300);
  68. sgRight();
  69. dir = RIGHT;
  70. HAL_Delay(300);
  71. disRight = get_distance();
  72. if(disLeft < disRight){
  73. goRight();
  74. HAL_Delay(150);
  75. stop();
  76. }
  77. if(disRight < disLeft){
  78. goLeft();
  79. HAL_Delay(150);
  80. stop();
  81. }
  82. }
  83. HAL_Delay(50);
  84. }
  85. int main(void)
  86. {
  87. int mark = 0;
  88. HAL_Init();
  89. SystemClock_Config();
  90. MX_GPIO_Init();
  91. MX_TIM4_Init();
  92. MX_TIM2_Init();
  93. MX_I2C1_Init();
  94. /* USER CODE BEGIN 2 */
  95. initSG90();
  96. HAL_Delay(1000);
  97. dir = MIDDLE;
  98. Oled_Init();
  99. Oled_Screen_Clear();
  100. Oled_Show_Str(2,2,"-----Ready----");
  101. /* USER CODE END 2 */
  102. /* Infinite loop */
  103. /* USER CODE BEGIN WHILE */
  104. while (1)
  105. {
  106. /* USER CODE END WHILE */
  107. /* USER CODE BEGIN 3 */
  108. //满足循迹模式的条件
  109. if(XJ_VALUE == GPIO_PIN_RESET && GS_VALUE == GPIO_PIN_SET && BZ_VALUE ==
  110. GPIO_PIN_SET)
  111. {
  112. if(mark != XJ)
  113. {
  114. Oled_Screen_Clear();
  115. Oled_Show_Str(2,2,"-----XunJi----");
  116. }
  117. mark = XJ;
  118. xunjiMode();
  119. }
  120. //满足跟随模式的条件
  121. if(XJ_VALUE == GPIO_PIN_SET && GS_VALUE == GPIO_PIN_RESET && BZ_VALUE ==
  122. GPIO_PIN_SET)
  123. {
  124. if(mark != GS)
  125. {
  126. Oled_Screen_Clear();
  127. Oled_Show_Str(2,2,"-----GenSui----");
  128. }
  129. mark = GS;
  130. gensuiMode();
  131. }
  132. //满足避障模式的条件
  133. if(XJ_VALUE == GPIO_PIN_SET && GS_VALUE == GPIO_PIN_SET && BZ_VALUE ==
  134. GPIO_PIN_RESET)
  135. {
  136. if(mark != BZ)
  137. {
  138. Oled_Screen_Clear();
  139. Oled_Show_Str(2,2,"-----BiZhang----");
  140. }
  141. mark = BZ;
  142. bizhangMode();
  143. }
  144. HAL_Delay(50);
  145. }
  146. /* USER CODE END 3 */
  147. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/837980
推荐阅读
相关标签
  

闽ICP备14008679号