1. 程式人生 > >AS5600磁編碼器開發記錄

AS5600磁編碼器開發記錄

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);
}

將磁鐵放置再晶片上面,旋轉。角度資訊相應產生變化,導致為止開發測試結束。