首页 > 编程知识 正文

stm32 编码器 最高频率,stm32编码器接口

时间:2023-05-06 18:21:20 阅读:286008 作者:3308

(文章背景:正在开发一款基于stm32的远程控制四驱小车)
前言:此文是讲解stm32cube配置电机参数的具体流程。
如果只是调用这个程序,不需要深入理解原理,只看part1学习如何调用就可以。
part1:调用电机驱动
协议讲解:只需要向串口中发送对应的协议就可以驱动电机。

举例(头部加入##,尾部加入&&,用来确定数据完整性)
##s0l0r0f0b0&& //停止
##s1l0r0f1b0&& //前进
##s1l1r0f1b0&& //左转
##s1l0r1f1b0&& //右转
##s1l0r0f0b1&& //后退

协议制定的规则:
1代表执行,0代表相关位停止(放到表格里,二进制,对应ascii码)

s代表启动停止
l左转
r右转
f前进
b后退

代码讲解:

前进后退函数
代码名称:void dianjioutput(int Voltage)
代码功能:调节pwm值,使电机运动或停止
输入:int Voltage(-2000~2000,输入正值就正转,负值就反转,0就停止)
输出:输出电压,供给电机,使电机转动。
转向函数
代码名称:void leftrightoutput(int Turn)
代码功能:根据输入的turn值,判断车辆左转右转
输入:int Turn(2左转,3右转)
输出:输出电压到电机,控制电机转动
以上函数只需要在main.c里声明就可以调用。

Part2:stm32cube配置电机驱动
主要分以下几个步骤:
1.打开stm32cube,选择你所使用的芯片。
2.系统配置:sys里选择serial wire

3.时钟配置在System Core的RCC部分中,一般来说因为控制板都是使用外部的晶振,所以选择Crystal/Ceramic Resonator,剩余选项不用改动。

4.定时器1用来配置pwm输出,选择TIM1,分别为4个通道选择PWM模式,如图

5.定时器2到定时器5,都用做编码器,来检测不同车轮的转速信息,配置方式就是选择编码器模式Encoder Mode,如图:

6.配置对应的电机驱动模块的引脚,原理图如下,电机驱动和电机连接方式也在原理图里。
电机驱动模块1:

电机驱动模块2

一个电机驱动模块可以驱动两个电机,分别为AIN驱动电机1,BIN驱动电机2,驱动方式如下:

然后是配置引脚,根据原理图,PE0~PE7选择GPIO_OUTPUT,如图

7.配置串口通信,选择串口1,配置方式如下图

同时配置串口1的DMA输出,如下图

part3:配置时钟树

晶振选择为8M和32.768M,配置方式如下图

按下回车键,系统自动配置好其余值。
Part4:输出配置
1.给工程起一个英文名字(不能含有中文)
2.选择工程路径
选择编译工具MDK-ARM(版本可能略有不同)

part5:写代码
首先根据电机驱动模块的原理图,写出电机驱动文件motor.c,其中的主要参数已经在part1中讲解过。

这里主要讲解代码逻辑,
1.电机驱动代码
1.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,GPIO_PIN_RESET); //DJ2的AIN1引脚 PE1
2. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_SET); //DJ2的AIN1引脚 PE0
3.
4.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET); //DJ1的BIN1引脚 PE2
5. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_SET); //DJ1的BIN1引脚 PE3
6.
7. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET); //DJ3的AIN1引脚 PE5
8. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_SET); //DJ3的AIN1引脚 PE4
9.
10.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_RESET); //DJ4的BIN1引脚 PE6
11. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_SET); //DJ4的BIN1引脚 PE7
上边是电机驱动函数的正转的逻辑部分
12.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,GPIO_PIN_SET); //DJ2的AIN1引脚 PE1
13. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_RESET); //DJ2的AIN1引脚 PE0
14.
15.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET); //DJ1的BIN1引脚 PE2
16. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_RESET); //DJ1的BIN1引脚 PE3
17.
18. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET); //DJ3的AIN1引脚 PE5
19. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_RESET); //DJ3的AIN1引脚 PE4
20.
21.HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET); //DJ4的BIN1引脚 PE6
22. HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_RESET); //DJ4的BIN1引脚 PE7
上边是电机驱动函数的反转的逻辑部分
HAL_GPIO_WritePin(端口,引脚,让引脚变成0或者1)作用是让引脚置1或者0,GPIO_PIN_SET是值1,GPIO_PIN_RESET是值0。
结合真值表理解代码,

2.串口1接收指令代码:
改写串口1回调函数的代码:
1.void USART1_WRITE_DATA_IN_Buf(unsigned char data)
2.{
3. RxData[i++] = data; //数据存入RxData
4. HAL_UART_Receive_IT(&huart1, &RxBuf, 1);
5.}
6.void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
7.{
8.
9. if(huart == &huart1) //判断是否为串口1发送的数据
10. {
11. flag=1;
12. USART1_WRITE_DATA_IN_Buf(RxBuf);
13.
14. }
15.}

3.响应指令的代码
1.if(strstr(RxData,“s0l0r0f0b0”)!=NULL ) //停
2. {
3. //printf(“s0l0r0f0b0rn”);
4. dianjioutput(0);
5. }
6. else if(strstr(RxData,“s1l0r0f0b0”)!=NULL ) //启
7. {
8. //printf(“s1l0r0f0b0rn”);
9. dianjioutput(0);
10. }
11. else if(strstr(RxData,“s1l0r0f1b0”)!=NULL ) //前进
12. {
13. //printf(“s1l0r0f0b0rn”);
14. dianjioutput(500);
15. }
16. else if(strstr(RxData,“s1l0r0f0b1”)!=NULL ) //后退
17. {
18. //printf(“s1l0r0f0b1rn”);
19. dianjioutput(-300);
20. }
21. else if(strstr(RxData,“s1l0r1f1b0”)!=NULL ) //右转
22. {
23. //printf(“s1l0r1f1b0rn”);
24. leftrightoutput(3);
25. }
26. else if(strstr(RxData,“s1l1r0f1b0”)!=NULL ) //左转
27. {
28. //printf(“s1l1r0f1b0rn”);
29. leftrightoutput(2);
30. }
Strstr()函数的作用是判断前后两个字符串是否相同,相同返回字符串,不相同返回NULL,

if(strstr(RxData,“s1l1r0f1b0”)!=NULL )所以这句代码的意思就是判断接收到的字符串是哪一条指令,并作出相应操作。

至于字符串和其他函数的意义已经在part1解释过了,不再重复。

附录:
1.电机驱动模块原理图
2.小车原理图

源码就不放了,写的一般,有想要的留言吧。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。