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

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




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

В предыдущей заметке описана функция SPI_ReadByte(), её мы и будем использовать.

Вот в каком формате приходят данные с датчика:


байт 1: P2  EF A12 A11 A10 A09 A08 A07   

байт 2: P1 A06 A05 A04 A03 A02 A01 A00

байт 3: P0 T06 T05 T04 T03 T02 T01 T00

EF - флаг ошибки
P1, P2 - биты нечётности

Error codes:
A[1:0]  Описание                      Угол правильный
00      ошибка                        нет
01      ошибка на стадии ввода        нет
10      превышение температуры        да 
11      (код ошибки не занят)         -

Макросы для выборки датчика:

#define WRITE_0(Port, Pin) Port->ODR &= (u8)(~Pin)
#define WRITE_1(Port, Pin) Port->ODR |= (u8)( Pin)
#define CS_1     WRITE_1(KMA200_PORT, KMA200_SELECT_PIN)
#define CS_0     WRITE_0(KMA200_PORT, KMA200_SELECT_PIN)

Флаги и маски KMA200. А также буфер sensor_data куда складываются приходящие по SPI три байта. А ещё переменные, которые будут содержать температуру и угол.

#define KMA200_EF 0x40
#define KMA200_ERR_MASK 0x03
#define KMA200_DIAGNOSIS_ERROR 0
#define KMA200_DIAGNOSIS_INPUT_STAGE_ERROR 1
#define KMA200_OVER_TEMPERATURE_WARNING 2
#define KMA200_UNSPECIFIED_ERRROR 3

static volatile u8 uTemperature;
static volatile u16 uAngle;
static volatile u8 sensor_data[3] = { 0, 0, 0 };

Функция GetAngleCode() получает код угла с датчика, и определяет, верный ли код получен. Если нужен только угол, то третий байт можно даже не считывать. Если код ошибочный, возвращется -1.

static s16 GetAngleCode(void)
{
  s16 sResult = 0;

  CS_0;
  sensor_data[0] = SPI_ReadByte();
  sensor_data[1] = SPI_ReadByte();
  //sensor_data[2] = SPI_ReadByte(); тут температура, она не нужна
  CS_1;  
  
  sResult = ((sensor_data[0] & 0x3F) << 7);
  sResult |= (sensor_data[1] & 0x7F);  
  
  // флаг ошибки
  
  if (sensor_data[0] & KMA200_EF)
  {
    // угол верный, при этой ошибке, так как она касается температуры
    if (KMA200_OVER_TEMPERATURE_WARNING != (sensor_data[1] & KMA200_ERR_MASK))
    {
       // остальные коды ошибок свидетельствуют о том, что угол неверный
       sResult = -1;
    }
  }
  
  return sResult;
} 

Теперь необработанный код нужно преобразовать в градусы. Функция GetAngle() возвращает угол в диапазоне 0-180°. Для получения кода используется предыдущая функция.

u8 GetAngle(void)
{
  s16 sAngleCode;
  float fAngle;
  
  sAngleCode = GetAngleCode();
  
  if (sAngleCode < 0)
  {
    return 0;
  }
  
  fAngle = (float)sAngleCode;  
  fAngle *= 2.197265625; // в 0,1 градуса
  
  return (u8) ((fAngle + 50) / 100); // в 1 градус
}
Если нужна температура, то код в основном такой же, только температура извлекается таким образом:
  sResult = (sensor_data[2] & 0x7F);  

  // флаг ошибки
  if (sensor_data[0] & KMA200_EF)
  {
    // при этой ошибке температура не верна
    if (KMA200_OVER_TEMPERATURE_WARNING == (sensor_data[1] & KMA200_ERR_MASK))
    {       
       sResult = -1;
    }
    // остальные коды ошибок свидетельствуют о том, что температура верна
  }

Примечание

Датчик угла поворота KMA200 снят с производства. Вместо него используйте KMA210, или, например AS5050.



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


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