TLE5012磁编码器使用记录

话不多说,硬件连接图

单片机SPI的MOSI和MISO脚连一起,加4.7K上拉电阻。

软件使用SPI通信。

#define BMQ_LZ_D                    30//编码器轮子直径30mm
//#define BMQ_pi                      3.141592653     //π值
#define BMQ_motor_L                 (BMQ_LZ_D * M_PI)     //轮子的周长


#define TLE_CSS_PIN    GET_PIN(C, 6)

#define SPI_TX_OFF {GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x40000000;}//把PB15(MOSI)配置成开漏--输入模式
#define SPI_TX_ON  {GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0xB0000000;}//把PB15(MOSI)配置成推挽--输出模式(50MHz)


/* SPI command for TLE5012 */
#define READ_ANGLE_VALUE        0x8021
#define READ_SPEED_VALUE        0x8031
#define READ_CONT_VALUE         0x8041


rt_uint32_t bmq_licheng_value = 0;
rt_uint32_t eeprom_read_value = 0;
rt_uint32_t eeprom_write_value = 0;
rt_uint16_t eeprom_tle_angle = 0;


SPI_HandleTypeDef SPI2_Handler;  //SPI2句柄

int TLE_spi_gpio_enable(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOB_CLK_ENABLE();       //使能GPIOB时钟
    __HAL_RCC_SPI2_CLK_ENABLE();        //使能SPI2时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();

    //PB13,14,15
    GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;              //复用推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;        //快速
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);

    GPIO_Initure.Pin = GPIO_PIN_6;
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_Initure);

    return 0;
}

rt_uint8_t SPI2_ReadWriteByte(rt_uint8_t TxData)
{
    rt_uint8_t Rxdata;
    HAL_SPI_TransmitReceive(&SPI2_Handler,&TxData,&Rxdata,1, 1000);
    return Rxdata;
}
void TLE_SPI2_Init(void)
{
    TLE_spi_gpio_enable();

    SPI2_Handler.Instance = SPI2;                         //SPI2
    SPI2_Handler.Init.Mode = SPI_MODE_MASTER;             //设置SPI工作模式,设置为主模式
    SPI2_Handler.Init.Direction = SPI_DIRECTION_2LINES;   //设置SPI单向或者双向的数据模式:SPI设置为双线模式
    SPI2_Handler.Init.DataSize = SPI_DATASIZE_8BIT;       //设置SPI的数据大小:SPI发送接收8位帧结构
    SPI2_Handler.Init.CLKPolarity = SPI_POLARITY_LOW;    //串行同步时钟的空闲状态为高电平
    SPI2_Handler.Init.CLKPhase = SPI_PHASE_2EDGE;         //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    SPI2_Handler.Init.NSS = SPI_NSS_SOFT;                   //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    SPI2_Handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为256
    SPI2_Handler.Init.FirstBit = SPI_FIRSTBIT_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI2_Handler.Init.TIMode = SPI_TIMODE_DISABLE;        //关闭TI模式
    SPI2_Handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    SPI2_Handler.Init.CRCPolynomial = 10;                  //CRC值计算的多项式
    HAL_SPI_Init(&SPI2_Handler);//初始化

    __HAL_SPI_ENABLE(&SPI2_Handler);                    //使能SPI2
    SPI2_ReadWriteByte(0Xff);                           //启动传输
}
void SPI2_SetSpeed(rt_uint8_t SPI_BaudRatePrescaler)
{
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
    __HAL_SPI_DISABLE(&SPI2_Handler);            //关闭SPI
    SPI2_Handler.Instance->CR1&=0XFFC7;          //位3-5清零,用来设置波特率
    SPI2_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//设置SPI速度
    __HAL_SPI_ENABLE(&SPI2_Handler);             //使能SPI

}
rt_uint8_t tle_tx_buf[10];
rt_uint8_t tle_rx_buf[10];
void SPI2_WriteByte(rt_uint16_t byte)
{
    tle_tx_buf[0] = byte >> 8;
    tle_tx_buf[1] = byte;
    HAL_SPI_Transmit(&SPI2_Handler, tle_tx_buf, 2,100);
}
void SPI2_ReadByte(void)
{
    HAL_SPI_Receive(&SPI2_Handler, tle_rx_buf, 2,100);
}
void SPI2_ReadBuf(void)
{
    HAL_SPI_Receive(&SPI2_Handler, tle_rx_buf, 6,100);
}

void ReadValue(rt_uint16_t u16RegValue,rt_uint8_t read_cont)
{
    rt_pin_write(TLE_CSS_PIN, PIN_LOW);
    SPI2_WriteByte(u16RegValue);
    SPI_TX_OFF;
    if(read_cont == 1)
    {
        SPI2_ReadByte();
    }
    else if(read_cont == 2)
    {
        SPI2_ReadBuf();
    }
    rt_pin_write(TLE_CSS_PIN, PIN_HIGH);
    SPI_TX_ON;
}
void WriteValue(rt_uint16_t addr,rt_uint16_t daat)
{
    rt_pin_write(TLE_CSS_PIN, PIN_LOW);
    SPI2_WriteByte(addr);
    SPI2_WriteByte(daat);
    SPI_TX_OFF;
    SPI2_ReadByte();
    rt_pin_write(TLE_CSS_PIN, PIN_HIGH);
    SPI_TX_ON;
}
void tle_reset(void)
{
    WriteValue(0x00f1,0x0000);//禁用启动BIST
    rt_thread_mdelay(50);
    WriteValue(0x0011,0x5aff);//激活HW复位
}
MSH_CMD_EXPORT(tle_reset, tle_reaet function);
//得到 0~359 度
rt_uint16_t ReadAngle(void)
{
    rt_uint16_t rd = 0;
    ReadValue(READ_ANGLE_VALUE,1);
    rd = tle_rx_buf[0];
    rd <<= 8;
    rd |= tle_rx_buf[1];
    rd &= 0x7FFF;
    rd = (rd * 360) / 32768;
    return rd;
}
//得到角速度
rt_uint16_t ReadSpeed(void)
{
    rt_uint16_t rd = 0;
    ReadValue(READ_SPEED_VALUE,1);
    rd = tle_rx_buf[0];
    rd <<= 8;
    rd |= tle_rx_buf[1];
    rd &= 0x7FFF;
    return rd;
}
//得到角转数
rt_uint16_t ReadCont(void)
{
    rt_uint16_t rd = 0;
    ReadValue(READ_CONT_VALUE,1);
    rd = tle_rx_buf[0];
    rd <<= 8;
    rd |= tle_rx_buf[1];
    rd = rd & 0x01ff;
    return rd;
}
rt_uint16_t tle_angle = 0;
rt_uint16_t tle_speed = 0;
rt_uint16_t tle_cont = 0;
void Read_tle_all(void)
{
    rt_uint16_t rd = 0;

    ReadValue(0x8023,2);
    rd = tle_rx_buf[0];
    rd <<= 8;
    rd |= tle_rx_buf[1];
    rd &= 0x7FFF;
    rd = (rd * 360) / 32768;
    tle_angle = rd;
    rd = tle_rx_buf[2];
    rd <<= 8;
    rd |= tle_rx_buf[3];
    rd &= 0x7FFF;
    tle_speed = rd;
    rd = tle_rx_buf[4];
    rd <<= 8;
    rd |= tle_rx_buf[5];
    rd = rd & 0x01ff;
    tle_cont = rd;
}

通过SPI读取角度,角速度、转数这些值网上有很多的例子,这里就不多说了,基本复制粘贴就可以了。

使用过程中发现有时候需要将转数寄存器的值清零,查了手册发现这个寄存器是只读寄存器,没法修改。

查了半天数据手册,没有发现可以设置这个寄存器的地方,那就只能复位了。

 

 测试发现只需要将这个位置1就可以复位TLE5210了,然后转数寄存器会从零开始计数。

程序源码和数据手册下载地址

https://download.csdn.net/download/qq_25186745/20704305

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值