А вот сейчас 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;
 }