А вот сейчас SPI-ем считал. Сейчас буду подпорки одну за другой убирать. Если удастся на DMA все это дело вывести, будет круто.
Добавлено спустя 1 минуту 56 секунд:Блина, точность-то у него какая зверская... 512 честных отсчетов без дребезга практически....
Добавлено спустя 3 минуты 19 секунд:SPI работает оно только в режиме FullDuplex. В RX-Only отмораживается и не хочет воспринимать данные.
Добавлено спустя 1 час 8 минут 28 секунд:Так, вот рабочий код для чтения показаний с STM32 через SPI:
Дефайны для удобства:
- Код: Выделить всё • Развернуть
#define AS5043_Val AS5043_Out.Value
#define AS5043_Pos AS5043_Out.Merged.Position
#define AS5043_OCF AS5043_Out.Merged.OCF
#define AS5043_COF AS5043_Out.Merged.COF
#define AS5043_LIN AS5043_Out.Merged.LIN
#define AS5043_MAGDEC AS5043_Out.Merged.MAGDEC
#define AS5043_MAGENC AS5043_Out.Merged.MAGINC
Структура для показаний датчика
- Код: Выделить всё • Развернуть
typedef union {
uint16_t Value;
struct {
uint8_t :1;
uint8_t MAGDEC :1;
uint8_t MAGINC :1;
uint8_t LIN :1;
uint8_t COF :1;
uint8_t OCF :1;
uint16_t Position :10;
} Merged;
} AS5043_Type;
AS5043_Type AS5043_Out;
Сетап SPI:
- Код: Выделить всё • Развернуть
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx ;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_SSOutputCmd(SPI1, ENABLE);
Клоки:
- Код: Выделить всё • Развернуть
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, ENABLE);
GPIO:
- Код: Выделить всё • Развернуть
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 /*| GPIO_Pin_6*/ | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Ну и само чтение:
- Код: Выделить всё • Развернуть
SPI_Cmd(SPI1, ENABLE);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_Cmd(SPI1, DISABLE);
AS5043_Val = SPI_I2S_ReceiveData(SPI1);
Грабли, по которым я ходил два дня: несмотря на любую логику при использовании unidirection RX-only линии, вход от датчика подключается не к MISO, а к MOSI. Вот так вот...
Добавлено спустя 1 час 45 минут 38 секунд:Грязный хак - за счет потери 1-го бита разрешения можно полностью автоматизировать сбор данных с датчика на STM32 (при желании - с двух датчиков). Конфигурируем USART2 (и USART3 если надо) на 9ть бит, flow control rts, врубаем клок... Максимальный клок, с которым заработало - 500кГц, около 10мкс на пакет.
Но есть большая ложка дегтя, которую я не знаю как обойти. AS5043 выкидывает данные MSB first, сериал принимает LSB first
Я вот конечно вот такое сделал, но это ж ужос, весь смысл теряется:
- Код: Выделить всё • Развернуть
val1 = 0;
for (k = 0; k<9; k++)
{
val1 = (val1<<1) | (val&1);
val = val>>1;
}