当前位置:   article > 正文

STM32F103单片机制作的智能小车_stm32f103智能小车设计总结

stm32f103智能小车设计总结

需要实现的项目内容

1.材料清单

材料数量

电机

2
万向轮1
轮胎2
循迹模块2
超声波、舵机1
STM32F103学习板或者最小系统1
L298N1
12V可充电锂电池1
蓝牙模块HC-061

 

1.2图片

                                                          

2.L298N电机驱动(重点)

2.1L298N原理

如上图所示: 输出A和输出B接到电机。12V供电接到锂电池正极,5V接到单片机正极(注意单片机上的5V丝印层字样),GND单片机和锂电池共用。拔掉通道A使能和通道B使能,各接到单片机PC6和PC7口(PWM控制电机速度,用的是TIM3,开启复用模式,详细看PWM输出实验详细示例),IN1IN2为一组( IN1是PA0; //左电机正转,      IN2 = PA1;  //左电机反转),接到单片机P2对应OutA(输出A); IN3IN4为一组(IN3 是PA2;     //右电机正转 ,IN4 是PC3;             //右电机反转),对应OutB(输出B)。注意自己的L298N的IN1IN2IN3IN4驱动电子的方向。ENA和ENB是用来控制小车速度的,给高电平有效。

正反转逻辑(0为低电平,1为高电平)

IN1IN2IN3IN4电机
1001向前
0110向后
0001左转
1000向后
1111停止
0000停止

PWM,STM32的I/O口PC6和PC7,TIM_SetCompare1(TIM3,PWM1)中PWM1控制小车转速即占空比。

2.2代码:

PWM.C

  1. #include "To.h"
  2. void PWM_Init(void)
  3. {
  4. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  5. TIM_OCInitTypeDef TIM_OCInitStruct;
  6. GPIO_InitTypeDef GPIO_InitStruct;
  7. /***************时钟使能*******************/
  8. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  9. /***************TIM使能*******************/
  10. TIM_TimeBaseInitStruct.TIM_Period= 100-1;//重装载值
  11. TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频数
  12. TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
  13. TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  14. TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
  15. TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
  16. /***************PWM使能*******************/
  17. TIM_OCStructInit(&TIM_OCInitStruct);//给结构体成员赋初始值
  18. TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//PWM1模式
  19. TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//设置极性
  20. TIM_OCInitStruct.TIM_Pulse = 50;//占空比
  21. TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;//使能/失能
  22. TIM_OC2Init(TIM3,&TIM_OCInitStruct);
  23. TIM_OC1Init(TIM3,&TIM_OCInitStruct);
  24. TIM_Cmd(TIM3,ENABLE);
  25. }

TO.h  总头文件

  1. #ifndef _TO_H
  2. #define _TO_H
  3. #include "stm32f10x.h"
  4. //管脚初始化
  5. void GPIOx_cofing(void);
  6. //delay
  7. void delay_init(void);
  8. void delay_ms(u16 nms);
  9. void delay_us(u32 nus);
  10. void delay_s(int s);
  11. //PWM
  12. void PWM_Init(void);
  13. //控制电机
  14. void qj(int PWM1,int PWM2);
  15. void zz(int PWM1,int PWM2);
  16. void yz(int PWM1,int PWM2);
  17. void ht(int PWM1,int PWM2);
  18. void tz(int PWM1,int PWM2);
  19. //循迹
  20. void XJ(void);
  21. //蓝牙通信
  22. void usart_Initconfig(void);
  23. void USART_SendByte(USART_TypeDef* USARTx, uint16_t Data);
  24. uint8_t USART_ReceiveByte(USART_TypeDef* USARTx);
  25. extern uint16_t temp;
  26. //遥控
  27. void YKXC(void);
  28. #endif

3.车轮的控制和初始化代码

motor.c

  1. #include "To.h"
  2. //车轮方向控制
  3. void qj(int PWM1,int PWM2)//前进
  4. {
  5. TIM_SetCompare1(TIM3,PWM1);
  6. GPIO_SetBits(GPIOA,GPIO_Pin_0);
  7. GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  8. TIM_SetCompare2(TIM3,PWM2);
  9. GPIO_SetBits(GPIOA,GPIO_Pin_2);
  10. GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  11. }
  12. void zz(int PWM1,int PWM2)//左转
  13. {
  14. TIM_SetCompare1(TIM3,PWM1);
  15. GPIO_SetBits(GPIOA,GPIO_Pin_0);
  16. GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  17. TIM_SetCompare2(TIM3,PWM2);
  18. GPIO_SetBits(GPIOA,GPIO_Pin_2);
  19. GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  20. }
  21. void yz(int PWM1,int PWM2)//右转
  22. {
  23. TIM_SetCompare1(TIM3,PWM1);
  24. GPIO_SetBits(GPIOA,GPIO_Pin_0);
  25. GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  26. TIM_SetCompare2(TIM3,PWM2);
  27. GPIO_SetBits(GPIOA,GPIO_Pin_2);
  28. GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  29. }
  30. void ht(int PWM1,int PWM2)//后退
  31. {
  32. TIM_SetCompare1(TIM3,PWM1);
  33. GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  34. GPIO_SetBits(GPIOA,GPIO_Pin_1);
  35. TIM_SetCompare2(TIM3,PWM2);
  36. GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  37. GPIO_SetBits(GPIOA,GPIO_Pin_3);
  38. }
  39. void tz(int PWM1,int PWM2)//停止
  40. {
  41. TIM_SetCompare1(TIM3,PWM1);
  42. GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  43. GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  44. TIM_SetCompare2(TIM3,PWM2);
  45. GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  46. GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  47. }

4.管脚初始化代码

GPIOX.c  I/O口初始化代码

  1. #include "To.h"
  2. void GPIOx_cofing(void)
  3. {
  4. GPIO_InitTypeDef GPIO_InitStruct;
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
  6. //小车车轮接口
  7. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
  8. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  9. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  10. GPIO_Init(GPIOA, &GPIO_InitStruct);
  11. //LED
  12. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
  13. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  14. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOC, &GPIO_InitStruct);
  16. //小车循迹接口
  17. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1|GPIO_Pin_10| GPIO_Pin_11;
  18. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  19. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  20. GPIO_Init(GPIOB, &GPIO_InitStruct);
  21. //pwm输出/串口
  22. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_9; //GPIO_Pin_9 //TX
  23. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
  24. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  25. GPIO_Init(GPIOA,&GPIO_InitStruct);
  26. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //GPIO_Pin_10
  27. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  28. GPIO_Init(GPIOA,&GPIO_InitStruct);
  29. }

5.循迹

5.1循迹模块的选择

循迹模块有模拟量和数字量的,初学者建议选择数字量,但循迹不丝滑,它的循迹原理就是接收到信号来转向。

5.2循迹代码

  1. #include "To.h"
  2. void XJ(void)
  3. {
  4. if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0&& GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
  5. {
  6. qj(23,23);
  7. }
  8. else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
  9. {
  10. zz(13,25);
  11. }
  12. else if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==1)
  13. {
  14. yz(25,13);
  15. }
  16. else if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==1&&GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==1)
  17. {
  18. tz(0,0);
  19. }
  20. }

6.蓝牙通信

6.1蓝牙的接线方法

请看VCR

Stm32 基于蓝牙的串口通信 详细篇

HC-05蓝牙模块--------手机与STM32通信(代码编写)(上位机配置)保姆级教程

STM32+HC-05蓝牙模块学习与使用

我这里用RCC_APB2Periph_USART1,波特率9600,PA9是TX,PA9接到蓝牙模块的RX,PA10是RX,PA10接到蓝牙模块的TX,单片机和蓝牙模块的这两个口反接。

  1. #include "To.h"
  2. uint16_t temp;
  3. void usart_Initconfig(void)
  4. {
  5. USART_InitTypeDef USART_InitStruct;
  6. NVIC_InitTypeDef NVIC_InitStruct;
  7. RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1,ENABLE);
  8. USART_InitStruct.USART_BaudRate = 9600;//波特率
  9. USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位
  10. USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位长度
  11. USART_InitStruct.USART_Parity = USART_Parity_No;//校验位;无
  12. USART_InitStruct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//发送/接收
  13. USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控
  14. USART_Init(USART1,&USART_InitStruct);
  15. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能usart1的中断
  16. USART_Cmd(USART1, ENABLE);
  17. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  18. NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
  19. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =0 ;
  20. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  21. NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
  22. NVIC_Init(&NVIC_InitStruct);
  23. }
  24. void USART1_IRQHandler()
  25. {
  26. //判断是否接收到数据
  27. if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
  28. {
  29. temp=USART_ReceiveByte(USART1);
  30. //USART_SendByte(USART1,temp);
  31. USART_ClearITPendingBit(USART1,USART_IT_RXNE);
  32. }
  33. }
  34. void USART_SendByte(USART_TypeDef* USARTx, uint16_t Data)
  35. {
  36. assert_param(IS_USART_ALL_PERIPH(USARTx));
  37. assert_param(IS_USART_DATA(Data));
  38. USARTx->DR = (Data & (uint16_t)0x01FF);
  39. while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==0);
  40. }
  41. uint8_t USART_ReceiveByte(USART_TypeDef* USARTx)
  42. {
  43. while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==0);//为0表示没有收到数据;为1表示收到数据
  44. return (uint8_t)USART_ReceiveData(USART1);
  45. }

6.2蓝牙控制代码

  1. #include "To.h"
  2. void YKXC(void)
  3. {
  4. if(temp == 'w') //控制w十六进制为“0x77”,temp == 0x77 也可以
  5. {
  6. qj(25,26);
  7. }
  8. else if(temp == 'a')
  9. {
  10. zz(22,30);
  11. }
  12. else if(temp == 'd')
  13. {
  14. yz(30,22);
  15. }
  16. else if(temp == 's')
  17. {
  18. ht(25,25);
  19. }
  20. else if(temp == 't')
  21. {
  22. tz(0,0);
  23. }
  24. else if(temp == 'x')
  25. {
  26. XJ();
  27. }
  28. }

7.舵机

7.1舵机的接法

信号线(黄色)、正极(红色)、负极(棕色)

信号线连接到P3^4,用定时器0,0.1ms中断一次,0.1*6(中断次数)=1ms(指向右边);0.1*15(中断次数)=1.5ms(舵机指向中间);0.1*20(中断次数)=2ms(舵机指向左边)

180度舵机控制参数
角度脉冲周期脉冲高电平时间占空比
020ms0.5ms2.50%
4520ms1ms5.00%
9020ms1.5ms7.50%
14520ms2ms10.00%
18020ms2.5ms12.50%

7.2例子代码:暂无

8.超声波

8.1超声波接线:

超声波和舵机是接在一起的,一般网上买都有连接材料,超声波可以随便连接I/O口,我这里接的是EchoPin = P3^6;//超声波模块Echo    接收端;TrigPin = P3^5;//超声波模块Trig    控制端。

8.2例子代码:暂无

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

闽ICP备14008679号