AS5600使用簡介——(程序員版)
-----------------本文由“智御電子”提供,同時提供范例教程,以便電子愛好者交流學習。----------------
前言:
最近由於工作需要接觸到AS5600這顆磁角度傳感器,以前就對相關的磁應用感到各種高大上(例如霍爾傳感器,磁流體等)。既然接觸到了,就開始搜索相關資料,發現有用的資料並不多,僅限官網上發布的一些。作為程序員看完datasheet,肯定是要搞一份代碼拜讀一下。在這里 吐槽一下這AMS官網的揍性:手冊里寫了官網有ardunio的例子,一頓好找好不容易才找到,接着注冊賬號想下載,竟然提示沒有權限下載(一臉茫然,你個賣芯片的,配套軟件環境掛網上不能下載是什么鬼),功夫不負有心人,還是在好心網友的分享下找到了一些代碼。特此將自己開發經過記錄下來,與君共享!
開發流程:
從手冊了解到AS5600這顆芯片支持IIC通信,但是輸出的信號的方式還有PWM,模擬電壓等多種方式。本文直接上手IIC通信。
接着直接就是設計原理圖了,這部分手冊都有推薦的電路,需要注意的是VDD5V和VDD3V3引腳的選擇。因為本文采用的是STM32F0芯片的主控,供電電壓是3V3,故選擇3.3v Operation的如下電路。
再就是設計模塊PCB,模塊電路PCB打樣回來,如下圖所示。
本文把幾個引腳都留出來,通過杜邦線跟控制板連接,連接線如下表所示。
AS5600模塊 | STM32F0系統板 |
---|---|
VCC | 3.3V |
GND | GND |
DIR | GND |
SCL | PA9 |
SDA | PA10 |
GPO | 3.3V |
緊接着就是程序設計。出去對STM32硬件IIC的敬畏,我選擇敬而遠之,采用普通引腳軟件模擬IIC的通信過程。軟件模擬IIC的過程主要把握兩方面:速率控制和時序控制。
速率控制就是SCL的變化速率,只要控制再AS5600允許的范圍內即可。AS5600支持Fast-mode Plus模式,SCL能達到1MHz。
時序控制就是SCL和SDA變化的規則。有的芯片的IIC還是有點小異同的,所以我們需要對照手冊的時序再進行模式時序。
本文首先利用CubeMX直接生成STM32F0的Keil工程代碼,將PA9(SCL)和PA10(SDA)設置普通的輸出引腳。需要注意的是SCL一直由主機提供,故一直都是輸出模式;但是SDA為數據線,當從機傳數據至主機的時候,主機需要將SDA的模式改為輸入模式。代碼如下
#define SDA1_IN() IIC_SDA_GPIO_Port->MODER &= ~(0x3<<(10*2))
#define SDA1_OUT() IIC_SDA_GPIO_Port->MODER &= ~(0x3<<(10*2));IIC_SDA_GPIO_Port->MODER |= (0x1<<(10*2))
然后就是將IIC的通信協議進行分解,拆解成:
Sim_I2C1_START()、Sim_I2C1_SendByte()、Sim_I2C1_Wait_Ack()、Sim_I2C1_STOP()
最后整合成讀和寫兩個函數,如下所示。
/**
- @brief 模擬IIC的多字節讀
- @param
- @note
- @retval void
- @author 智御電子
*/
uint8_t Sim_I2C_Read8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf)
{
Sim_I2C1_START();
Sim_I2C1_SendByte(moni_dev_addr << 1 | I2C1_Direction_Transmitter);
Sim_I2C1_Wait_Ack();
Sim_I2C1_SendByte(moni_reg_addr);
Sim_I2C1_Wait_Ack();
//Sim_I2C1_STOP();
Sim_I2C1_START();
Sim_I2C1_SendByte(moni_dev_addr << 1 | I2C1_Direction_Receiver);
Sim_I2C1_Wait_Ack();
while (moni_i2c_len)
{
if (moni_i2c_len==1) *moni_i2c_data_buf =Sim_I2C1_ReceiveByte();
else *moni_i2c_data_buf =Sim_I2C1_ReceiveByte_WithACK();
moni_i2c_data_buf++;
moni_i2c_len--;
}
Sim_I2C1_STOP();
return 0x00;
}
/**
- @brief 模擬IIC的多字節寫
- @param
- @note 當啟用check功能的時候,只能是單字節寫的情況,多字接寫不可啟用check功能
- @retval void
- @author 智御電子
*/
int8_t Sim_I2C1_Write8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf)
{
uint8_t i;
Sim_I2C1_START();
Sim_I2C1_SendByte(moni_dev_addr << 1 | I2C1_Direction_Transmitter);
Sim_I2C1_Wait_Ack();
Sim_I2C1_SendByte(moni_reg_addr);
Sim_I2C1_Wait_Ack();
//Sim_I2C1_START();
for (i=0; i<moni_i2c_len; i++)
{
Sim_I2C1_SendByte(moni_i2c_data_buf[i]);
Sim_I2C1_Wait_Ack();
}
Sim_I2C1_STOP();
return 0;
}
下面就是開始對AS5600進行IIC的寄存器設置了。其實AS5600的設置相對來說比較簡單。特別是對於360度旋轉檢測的應用,基本不需要設置,直接讀取raw data寄存器就可以讀出角度信息。但是如果對於小范圍角度檢測的應用場景,AS5600可以設置其實起始角度和終點角度(大於18度)來和實際的應用對應起來。這個時候就需要按照datasheet的設計步驟一步一步初始化相應的寄存器。本文需要360度檢測,故不考慮這種情況。
再main函數中直接利用iic讀取角度寄存器的數值,然后轉化成角度,最后通過串口打印出來。
void Programe_Run(void)
{
uint8_t dect= 0;
dect = detectMagnet();
printf("detectMagnet is %d\r\n",dect);
rawdata = getRawAngle();
printf("rawdata is %d\r\n",rawdata);
degress = convertRawAngleToDegrees(rawdata);
printf("degress is %f\r\n",degress);
}
將磁鐵放置再芯片上面,旋轉。角度信息相應產生變化,導致為止開發測試結束。