硬件修改
多圈绝对值功能需要用一个3.6V的电池接到伺服电机编码器上来实现断电保存多圈数据。电池淘宝地址(带安装座)
![](https://img.haomeiwen.com/i5755028/de6c053d91ee9a13.png)
![](https://img.haomeiwen.com/i5755028/88b0e1bdbec25169.png)
将电池的正负极接到编码器接口的1、2端,正极和编码器红线对应,负极和编码器桃色线对应。
![](https://img.haomeiwen.com/i5755028/4585514a20816b5c.png)
这里可能需要买金属连接件进行配合→淘宝地址
也可以直接把编码器出线上的红色桃色线剪断,和电池电源线焊上。
清除多圈数据得到初始原点:
![](https://img.haomeiwen.com/i5755028/b73e4877484d4945.png)
把PR15的参数设置为0:
![](https://img.haomeiwen.com/i5755028/7cf045e204b1cc6a.png)
多圈绝对值通讯
![](https://img.haomeiwen.com/i5755028/a0f3a0c0cee1c067.png)
![](https://img.haomeiwen.com/i5755028/4db0d3d225d7eec3.png)
STM32主要程序232通讯
u8 UART5_RX_BUF[20]; //接收缓冲,最大20个字节,用于储存编码器位置信息
u8 U5_i=0;
struct _code
{
u32 code_value;//编码器值
u32 cylinder_number;//圈数
u8 check_bit;//校验位
};
//编码器通讯串口5初始化。伺服驱动默认是9600,可修改pr5.29改变
void SERVO_CODE_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE); //使能UART5,GPIOC、GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
//UART5_TX GPIOC.12初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PC.12
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.12
//UART5_RX GPIOD.2初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//PD.2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOD.2
//UART5 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(UART5, &USART_InitStructure); //初始化串口5
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(UART5, ENABLE); //使能串口5
}
//从串口5发送一个字节的函数
void UART5_SendByte(u8 k)
{
USART_SendData(UART5, k);
while(USART_GetFlagStatus(UART5,USART_FLAG_TC)!=SET);//等待发送结束
}
//串口5中断,把伺服编码器的值返回到UART5_RX_BUF[]数组中
void UART5_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //接收中断
{
Res =USART_ReceiveData(UART5);//(UART5->DR); //读取接收到的数据
UART5_RX_BUF[U5_i]=Res;
U5_i++;
if(U5_i>=20)
{U5_i=0;}
}
}
//获得圈数和编码值
struct _code Get_Code(void)
{
struct _code CODE;
CODE.check_bit = 0;//校验位初始化
U5_i = 0;
UART5_SendByte(0x05);
nopdelay_ms(4);
UART5_SendByte(0x00);
UART5_SendByte(0x01);
UART5_SendByte(0xD2);
UART5_SendByte(0x2D);
nopdelay_ms(4);
UART5_SendByte(0x04);
nopdelay_ms(4);
UART5_SendByte(0x06);
//编码值
CODE.code_value = (u32)(UART5_RX_BUF[10]+UART5_RX_BUF[11]*0x100+UART5_RX_BUF[12]*0x10000);//低位+中位*0x100+高位*0x10000
//圈数
CODE.cylinder_number = UART5_RX_BUF[13]+UART5_RX_BUF[14]*0x100;
if(CODE.cylinder_number <= 32767)
CODE.cylinder_number = CODE.cylinder_number + 65536;//32768~65535为负,65536~98303为正,65536为原点
if((UART5_RX_BUF[0]!=0x04)|(UART5_RX_BUF[1]!=0x06)|(UART5_RX_BUF[2]!=0x05)|(UART5_RX_BUF[3]!=0x0B))
{
CODE.code_value = 0x00800000;//读数失败时,返回8388608
CODE.check_bit = 1;//失败
}
U5_i = 0;
return CODE;
}
网友评论