AS5047P磁性编码器的SPI读取

一、AS5047P介绍

        AS5047P是14 位同轴磁性旋转位置传感器,集成动态角度误差补偿 (DAEC™)延时极低,同时拥有SPI ABZ PWM UVW多种数据输出方式。

        内部寄存器地址及含义:

/*内容随外界变化的寄存器 可读不可写*/
#define NOP_ADDR      0x0000 //启动读取过程寄存器地址
#define ERRFL_ADDR    0x0001 //错误寄存器地址
#define PROG_ADDR     0x0003 //编程寄存器地址
#define DIAAGC_ADDR   0x3FFC //诊断和AGC寄存器地址
#define MAG_ADDR      0x3FFD //CORDIC寄存器地址
#define ANGLEUNC_ADDR 0x3FFE //无动态角度误差补偿的测量角度寄存器地址
#define ANGLECOM_ADDR 0x3FFF //带动态角度误差补偿的测量角度寄存器地址

/*配置选项寄存器 可读可写*/
#define ZPOSM         0x0016
#define ZPOSL         0x0017
#define SETTINGS1     0x0018
#define SETTINGS2     0x0019

二、AS5047P的SPI时序及读写帧格式

1.SPI时序

        AS5047P的SPI工作在模式1 ( CPOL=0 CPHA=1 ),即空闲状态下时钟CLK为低电平,在CLK的第二个边沿进行数据采样,片选信号为低电平选中,数据高位先发送 ( MSB ),数据宽度16位,最高可支持10MHz时钟。我们需要严格设置主机配置与其相同

2.偶校验

        偶校验就是保证一个数中的位1个数为偶数,AS5047P采用偶校验来保证数据传输的正确性,具体来说其返回的数据最高位15位是偶校验位,当位14-0有偶数个位1那么最高位为0 否则为1,这里有很多方法可以进行判断数据到底有多少位1

unsigned int even_check(unsigned int x)
{
    unsigned int count = 0;
    //1.计算位1个数
    while(x)
    {
        x = x & (x-1);
        count++;
    }
    //2.奇数个1 返回1 偶数个1 返回0
    return (count % 2) == 0 ? 0 : 1;
}
unsigned int even_check(unsigned int v)
{
      if(v == 0) return 0;
      v ^= v >> 8;
      v ^= v >> 4;
      v ^= v >> 2;
      v ^= v >> 1;
      return v & 1;
}

3.读写帧格式

        AS50047P拥有三种帧格式,分别为命令帧、读取帧、写入帧

命令帧格式:bit15偶校验位  bit14 R(1)W(0)  bit13-0为寄存器地址 该帧由主机发送给AS5047P

读取帧格式:bit15偶校验位  bit14 前一次指令错误(1) bit13-0为读取的数据 该帧由AS5047P返回给主机

写入帧格式:bit15偶校验位 bit14 固定为0 bit13-0为写入的数据 该帧由主机发送给AS5047P

        这里我们需要注意SPI为同步通信,主机写入数据同时也会返回数据,但是返回的数据是上一次指令所获取的数据!所以实际的读写操作往往包括连续的两次写入!

读取数据:发送一帧读命令 接着发送一帧读取NOP命令 从而得到我们想要的数据

写入数据:发送一帧写命令,后再发一个数据帧,数据帧发送后得到一个该地址上次的值

三、常用寄存器及错误处理

        我们常用的寄存器为ANGLECOM (0x3FFF) 带动态角度误差补偿的测量角度寄存器,ERRFL (0x0001) 错误寄存器,NOP (0x0000) 

        读取ANGLECOM可以获得角度数据,读取ERRFL会清除错误标记,读取NOP相当于一次空操作,当返回的读数据帧中第高14位为1时说明出现错误,我们需要发送读取ERRFL的帧清除错误

        由寄存器地址和读可以生成常用的读取指令:

/*读取数据命令*/
#define READ_ANGLECOM 0xFFFF
#define READ_NOP      0xC000
#define READ_ERRFL    0x4001

四、读取角度及错误处理函数

unsigned int Read_Form_AS5047P(unsigned int cmd)
{
    unsigned int data = 0;
    (void)send_and_receive_16(cmd);//发送指令
 
    data = send_and_receive_16(READ_NOP);//返回的是上一次命令返回的数据 也就是获取的数据
    
    //3.检查错误及校验
    if(data & (1<<14))
    {
        //有错误 发送清除错误指令
		(void)send_and_receive_16(READ_ERRFL);
		
		//获取错误原因
        spi_error = send_and_receive_16(READ_NOP); 
        spi_error = spi_error & 0x0003;
		return 0;
    }
    else//无错误
    {
        //偶校验最高位 通过则读取数据
        if((data>>15) == even_check(data & 0x7FFF))
        {
            return (data & 0x3FFF);
        }
        else{return 0;}
    }  
}

、实际读取AS5407P角度数据

  for(;;)
  {
    run_flag++;
    delay_ms(200);
    //读取AS5047的返回值                   
    val = Read_Form_AS5047P(READ_ANGLECOM);
    angle = (double)val*360.0/16384.0;
    //通过UART打印
    (void)printf("AS5047P = %u %.2f\n",val,angle);
  }

        需要注意没有放置好磁铁与IC上方时,其角度数据是随机值!好了,SPI读取AS5047P数据基本实现了,使用其他类型MCU都是一样的,后面将实现ABZ脉冲的读取
 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值