-----------------本文由「智御電子」提供,同時提供範例教程,以便電子愛好者交流學習。----------------程序員
最近因爲工做須要接觸到AS5600這顆磁角度傳感器,之前就對相關的磁應用感到各類高大上(例如霍爾傳感器,磁流體等)。既然接觸到了,就開始搜索相關資料,發現有用的資料並很少,僅限官網上發佈的一些。做爲程序員看完datasheet,確定是要搞一份代碼拜讀一下。在這裏 吐槽一下這AMS官網的揍性:手冊裏寫了官網有ardunio的例子,一頓好找好不容易纔找到,接着註冊帳號想下載,居然提示沒有權限下載(一臉茫然,你個賣芯片的,配套軟件環境掛網上不能下載是什麼鬼),功夫不負有心人,仍是在好心網友的分享下找到了一些代碼。特此將本身開發通過記錄下來,與君共享!函數
從手冊瞭解到AS5600這顆芯片支持IIC通訊,可是輸出的信號的方式還有PWM,模擬電壓等多種方式。本文直接上手IIC通訊。學習
接着直接就是設計原理圖了,這部分手冊都有推薦的電路,須要注意的是VDD5V和VDD3V3引腳的選擇。由於本文采用的是STM32F0芯片的主控,供電電壓是3V3,故選擇3.3v Operation的以下電路。
測試
再就是設計模塊PCB,模塊電路PCB打樣回來,以下圖所示。ui
本文把幾個引腳都留出來,經過杜邦線跟控制板鏈接,鏈接線以下表所示。設計
AS5600模塊 | STM32F0系統板 |
---|---|
VCC | 3.3V |
GND | GND |
DIR | GND |
SCL | PA9 |
SDA | PA10 |
GPO | 3.3V |
緊接着就是程序設計。出去對STM32硬件IIC的敬畏,我選擇敬而遠之,採用普通引腳軟件模擬IIC的通訊過程。軟件模擬IIC的過程主要把握兩方面:速率控制和時序控制。code
速率控制就是SCL的變化速率,只要控制再AS5600容許的範圍內便可。AS5600支持Fast-mode Plus模式,SCL能達到1MHz。htm
時序控制就是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); }
將磁鐵放置再芯片上面,旋轉。角度信息相應產生變化,致使爲止開發測試結束。