hex.pp.ua

Использование датчика AS5050 с STM8

Датчик угла поворота AS5050 и STM8




В этой заметке будет рассказано о том, как использовать датчик угла поворота AS5050 с микроконтроллером STM8. Для STM8 я использую компилятор Raisonance и среду разработки Ride7. Магнитный сенсор AS5050 передаёт данные по протоколу SPI. Приведённая здесь информация может относится также и к датчику AS5055, так как он похож на AS5050. Датчик AS5050 по магнитному полю определяет своё положение относительно магнита и выдаёт угол поворота.

Обмен по SPI

По сравнению с кодом инициализации SPI, приведённым здесь, изменился лишь один параметр в функции SPI_Init(). Вместо SPI_CLOCKPHASE_2EDGE нужно поставить SPI_CLOCKPHASE_1EDGE, иначе обмен по SPI происходит неправильно. В остальном всё осталось так же.

Сама функция обмена тоже изменилась. Дело в том, что в заметке «Использование SPI с STM8» я приводил 8-битную функцию обмена, а с датчиком AS5050 используется 16-битный обмен. Поэтому функция выглядит так:

#define CS_1    WRITE_1(AS5050_PORT, AS5050_SELECT_PIN)
#define CS_0    WRITE_0(AS5050_PORT, AS5050_SELECT_PIN)

static u16 SPI_ReadWrite(u16 uPackage)
{ 
  u16 uResult = 0;
  u8  uHigh;
  
  CS_0;
  
  while ((SPI->SR & (u8)SPI_FLAG_TXE) == RESET) { ; }
  SPI->DR = (u8)(uPackage >> 8);

  while ((SPI->SR & (u8)SPI_FLAG_RXNE) == RESET) { ; }
  uHigh = SPI->DR;
  
  while ((SPI->SR & (u8)SPI_FLAG_TXE) == RESET) { ; }
  SPI->DR = (u8)(uPackage & 0x00FF); 
  
  while ((SPI->SR & (u8)SPI_FLAG_RXNE) == RESET) { ; }
  uResult = SPI->DR; 
  
  CS_1;
  
  uResult |= (u16)uHigh << 8; 
  
  return uResult;
} 

Суть функции в том, что регистр DR 8-битный. Обмен идёт одновременно в обе стороны. Поэтому сначала посылаем старшие биты слова, и принимаем старшие биты ответа. Затем, соотвественно, посылаем младшие биты, и принимаем младшие биты. Особенность датчика AS5050 такова, что он шлёт ответ на команду после посылки следующей команды. Это надо учитывать при обмене данными с датчиком.

Чётность

Данные, принимающие участие в обмене с датчиком, должны иметь бит чётности (это первый бит в слове). Иными словами, количество бит «1» в посылаемом слове должно быть чётным. Для проверки этого и для установки бита чётность я написал следующие функции:

#define PARITY_BIT 0x0001

// Проверка чётности
static bool CheckEvenParity(u16 uWord)
{
  u8 uOnes = 0;
  u8 uMask = 1;
  u8 i;
  
  for (i = 0; i < 16; i++)
  {
    if (uWord & (uMask << i))
      uOnes++;
  }    

  return (0 == (uOnes % 2));
}

// количество бит "1" должно быть чётным
static void SetEvenParity(u16 *uWord)
{
  if (NULL == uWord)
    return;
  
  if (!CheckEvenParity(*uWord))
  {
    *uWord |= PARITY_BIT;
  }  
}

Команды и ответы

Команды для обмена с AS5050 содержат в себе адрес, бит чётности и бит, определяющий, служит ли команда для чтения или для записи. Бит чётности вычисляется для всего слова в целом. Для формирования команды я написал такую функцию:

typedef bool AS_RWTYPE;
#define AS_READ   false
#define AS_WRITE  true

static u16 MakeCommand(u16 uAddress, AS_RWTYPE bWrite)
{
  u16 uResult;  
  
  uResult = uAddress << 1;

  if (bWrite)
    uResult &= ~WRITE_BIT;
  else
    uResult |=  WRITE_BIT;
  
  SetEvenParity(&uResult);
  
  return uResult;
}

Адреса могут быть такими:

// Регистры AS5050
#define POWER_ON_RESET 0x3F22 /* чтение/запись */
#define SOFTWARE_RESET 0x3C00 /* запись */
#define MASTER_RESET   0x33A5 /* запись */
#define CLR_ERROR_FLAG 0x3380 /* чтение */
#define NO_OPERATION   0x0000 /* запись */
#define AUTO_GAIN_CTRL 0x3FF8 /* чтение/запись */
#define ANGULAR_DATA   0x3FFF /* чтение */
#define ERROR_STATUS   0x33A5 /* чтение */

Проверить полученный с датчика ответ можно функцией, в которой проверяется чётность и наличие бита ошибки.

static bool CheckData(u16 uData)
{ 
  bool bResult = true;
  
  if (!CheckEvenParity(uData))
  {
    #ifdef DEBUG_RS232
    printf("Нарушена чётность" CRLF);
    #endif
    bResult = false;
  }    
  
  if (uData & ERROR_BIT)
  {
    #ifdef DEBUG_RS232
    printf("Установлен бит ошибки" CRLF);
    #endif
    bResult = false;
  }
  
  return bResult;
} 

Ну и ещё одна функция, которая формирует дополнительный пакет данных, который можно использовать с некоторыми командами. Мне он не пригодился, но функцию я всё равно написал. Подробнее читайте PDF'ку на микросхему.

static u16 MakePackage(u16 uData)
{
  u16 uResult;    
  uResult = uData << 2;
  SetEvenParity(&uResult);  
  return uResult;
}

Получение угла с датчика AS5050

Используя вышеописанные функции, можно, наконец, получить угол с датчика. Для этого потребуется три команды:

  • Послать ANGULAR_DATA для запроса угла.
  • Послать NO_OPERATION, в качестве ответа придёт результат предыдущего запроса, то есть угол.
  • Проверить результат и послать команду CLR_ERROR_FLAG в случае, если до этого возникли ошибки.
Сразу после включения ошибки действительно ненадолго могут возникать, но дальше датчик входит в нормальный режим работы и посылает угол без ошибок. Ну а до этого команда CLR_ERROR_FLAG сбрасывает флаг ошибки, и так до тех пор, пока угол не начнёт выдаваться нормально.

s16 GetAngle_AS5050(void)
{
  s16 iAngle;
  u16 uData;

  SPI_ReadWrite(MakeCommand(ANGULAR_DATA, AS_READ));
  uData = SPI_ReadWrite(MakeCommand(NO_OPERATION, AS_WRITE));
  
  if (CheckData(uData))
  {
    iAngle = (uData >> 2) & 0x3FF;
  } else
  {
    SPI_ReadWrite(MakeCommand(CLR_ERROR_FLAG, AS_READ));
    iAngle = ANGLE_ERROR;    
  }

  return iAngle;
}

Преобразование угла в градусы

Полученное значение угла — это 10-битное целое число. Но, допустим, требуется узнать угол поворота в градусах. Очень легко можно преобразовать это значение в градусы. Делается это так:

iResult = GetAngle_AS5050();
iResult /= 2.84444; // преобразование в градусы, 0-359°
система комментирования CACKLE

Автор: амдф
Дата: 05.02.2012


Разделы сайта
Главная
Блог
Native API
NTFS и ReFS
Микроконтроллеры
Справочник NTDLL
Коды NTSTATUS
Разное

Избранное
NTFS Stream Explorer
Native Shell
Тенгвар

Остальное
nvpnhcknn (архив)
English pages
Контакты

Ленты atom
Лента Atom сайта Лента Atom блога



При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.