本文有麦粒电子撰写,并提供相应产品服务。
AS5047是ams公司研发的14bit精度的磁传感器,只需要一个磁铁悬于芯片上方就可以检测出相应的角度信息。针对不同的应用场景,该芯片还配置了不同的输出接口:SPI、ABI、UVW、PWM等接口。而且该芯还具有OTP一次性烧录配置的功能,一次配置永不改变。
好,话不多说,直接开干。本文选用的是AS5047P的传感器。
一、实例:SPI接口
这款芯片是利用SPI总线进行相应的配置,所以SPI接口是默认什么时候都是使能并且被使用的。所以我们第一步先调试通SPI接口,通过SPI接口能够进行芯片配置,以及传感器信号的采集。
选择电源
AS5047P支持两种电源电压,3.3V和5v模式,这两种的电路是不一样的,需要根据自己的主控电压进行选择,本文选择5V电压。
接着就是与主板的电气线路连接。本文选择的是ardunio主板进行读写控制。
ASM5047P | Ardunio |
---|---|
MOSI | 11 |
MISO | 12 |
SCK | 13 |
SS | 10 |
V5 | 5V |
GND | GND |
接着就是去查看datasheet中查看SPI的读写时序是怎样的。(说一句,一定要从官网下载最新的芯片手册,最新手册会对错误的地方进行勘误。)
SPI配置没什么难点,特点的是AMS给读\写控制命令中加入了一个PARC位的校验和R/W位的填充。
从下图可知PARC是一种偶校验。顾名思义就是在14-0 bit的数据中填充数值1的个数,保证整个16bit数据中数值1的个数位偶数,以此来保证数据传输过程的可靠性。如果操作者没有正确填充正确的PARC位,5047的 ERRFL寄存器会显示Parity error,并且会导致无法读出正确的SPI数据。
接着再了解下读时序。如下图所示,挺简单,第一个字送地址,数据在下一个时钟是送到主机,其实本文要说的就是这个14bit和15bit 的填充。举例子说明:比如读地址0X0016(? 0000 0000 ?0001 1000??)寄存器。因为是读操作,所以14bit位要填入1即(0100 0000 ?0001 1000?),然后1的个数位3个偶数,所以15bit填充1(1100 0000 ?0001 1000?)。这个样实际需要发送的地址为(0XC018)。
在第二个时钟周期返回的数据中,也是带有PARD和EF位的填充的,这个我们在用这些数据的时候,记得去掉这些位的填充即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | uint16_t AMS5047x::Read_Register(uint16_t AddRegister) { uint16_t result=0,AddRegister_Command=0; byte ReadByte=0; //填充校验位、读位 AddRegister_Command = Command_Add(AddRegister,1); byte lowbyte = AddRegister_Command & 0x00ff; byte highbyte = (AddRegister_Command >> 8); digitalWrite(CSn, LOW); SPI.transfer(highbyte); // first byte in result = SPI.transfer(lowbyte); // first byte out digitalWrite(CSn, HIGH); delayMicroseconds(10); digitalWrite(CSn, LOW); int bytesToRead = 2; while (bytesToRead-- > 0) { // shift the first byte left, then get the second byte: result = result << 8; ReadByte = SPI.transfer(0x00); // combine the byte with the previous one: result = result | ReadByte; } // take the chip select high to de-select: digitalWrite(CSn, HIGH); //删除填充位 result = Command_Del(result); return(result); } |
SPI写操作跟读操作差不多,就是先写地址,在写数据(如下图所示),同样的,注意 写命令和数据的校验填充即可。
[
完成读写的函数之后,就可以读取AS5047的数据了。将磁铁放置在芯片上面。然后读取角度数据。
1 2 3 4 5 6 | uint32_t Get_Angle(void) { uint32_t result=0; result = read_register(_angleunc); return result; } |
以上就是一些简答的读取实验。值得注意的是用SPI读取的数据,是绝对角度数据,也是14bit精度的。
实验结果如下图所示