AS5045 и STM32
И снова здравствуйте. Хотел бы продолжить тему про магнитный энкодер AS5045, начатую в моей прошлой статье(https://pikabu.ru/story/as5045_i_arduino_6724136). Но на этот раз датчик подключается не к ардуино, а к STM32F103C8T6. Так как ардуино оказалась слишком медленной для одновременного считывания двух датчиков, выполнение вычислений и многого другого не относящегося к теме. Писался код в System Workbench for STM32 (SW4STM32), но образцы представленного кода должны работать в любой другой среде. Кстати, большей частью эти функции практически полностью перекопированы из библиотеки для ардуино но с оглядкой на частоту STM.
И так начнем с выставления портов ввода-вывода в нужные состояния: CS,CLK - OUTPUT; DO - INPUT. Названия пинов отражают к какому выводу подключаться на плате датчика.
Теперь тактирование. Оно максимально насколько это возможно и где это возможно:
Вначале нужно объявить следующие дефайны:
#define AS5045_STATUS_OCF 0x10
#define AS5045_STATUS_COF 0x08
#define AS5045_STATUS_LIN 0x04
#define AS5045_STATUS_MAGINC 0x02
#define AS5045_STATUS_MAGDEC 0x01
Встречайте, функция инициализации датчика!
_Bool AS5045_Init()
{
uint8_t count = 0;
while (AS5045_Read(), (_status & AS5045_STATUS_OCF) == 0)
{
if (count > 30)
{
return 0 ; //ошибка инициализации
}
HAL_Delay(5);
count++;
}
return 1;
}
А вот и само считывание статуса датчика и его положения:
uint16_t AS5045_Read()
{
HAL_GPIO_WritePin(GPIOB,CS_PIN_Pin,0);
uint16_t value = 0;
uint8_t i = 0;
status = 0;
for (i = 0; i <12; i++)
{
HAL_GPIO_WritePin(GPIOB,CLK_PIN_Pin,0);
for(uint8_t i = 0; i < 4; i++){} //без подобных циклов датчик не
HAL_GPIO_WritePin(GPIOB,CLK_PIN_Pin,1); //успевает передать данные и на выходе
for(uint8_t i = 0; i < 2; i++) {} //рандомные числа
value = (value << 1) | HAL_GPIO_ReadPin(DO_PIN_GPIO_Port,DO_PIN_Pin);
}
for ( i = 0 ; i < 6 ; i++)
{
HAL_GPIO_WritePin(GPIOB,CLK_PIN_Pin,0);
for(uint8_t i = 0; i < 4; i++){}
HAL_GPIO_WritePin(GPIOB,CLK_PIN_Pin,1);
for(uint8_t i = 0; i < 2; i++){}
status = (status << 1) | HAL_GPIO_ReadPin(DO_PIN_GPIO_Port,DO_PIN_Pin);
}
HAL_GPIO_WritePin(GPIOB,CS_PIN_Pin,1);
_status = status >> 1 ;
return value ;
}
В принципе это все что я хотел показать сегодня. Тут нет программирования нулевого положения и, возможно, она не самая оптимальная по производительности, но эти функции делают все что мне нужно. Спасибо за внимание!