STM32F767ZI Обработка внешних прерываний

Я пытаюсь создать правильный интерфейс ведомого SPI для ADC AD7768-4. АЦП имеет интерфейс SPI, но не выводит преобразования через SPI. Вместо этого есть выходные данные, которые синхронизируются на отдельных выводах GPIO. Таким образом, мне в основном нужно разбивать данные на биты и выводить их в SPI, чтобы получить надлежащий интерфейс ведомого SPI. Пожалуйста, не спрашивайте, почему я так делаю, это было поручено мне.

У меня проблема с прерываниями. Я использую процессор STM32F767ZI — он работает на частоте 216 МГц, и мои данные АЦП ДОЛЖНЫ БЫТЬ синхронизированы на частоте 20 МГц. Я настроил свои NMI, но я не вижу, когда система вызывает или указывает на обработчик прерываний.

Я использовал программное обеспечение STMCubeMX, чтобы назначать контакты и генерировать код настройки, и в stm32F7xx.c файл, он показывает NMI_Handler() функция, но я не вижу указатель на него в системных файлах. Я также нашел пустым HAL_GPIO_EXTI_IRQHandler() функция в STM32F7xx_hal_gpio.c, который, кажется, проверяет, подтвержден ли вывод, и очищает все ожидающие биты, но не сбрасывает флаг прерывания и не проверяет его, и опять же, я не вижу указателя на эту функцию.

Чтобы более тщательно все усложнить, у меня есть 10 тактов, чтобы определить, какой флаг установлен (1 из двух за раз), сбросить его, задать переменную и переместить данные из регистров GPIO. Я считаю, что это возможно, но опять же, я не уверен в том, что делает система, как только прерывание отключается.

Есть ли у кого-нибудь опыт работы с внешними прерываниями на этом процессоре, который мог бы пролить свет на то, как эта конкретная система обрабатывает вещи? Опять же — 10 тактов, чтобы сделать то, что мне нужно … перемещение данных займет у меня всего 1-2 такта, а у меня 8 для обработки прерываний …

РЕДАКТИРОВАТЬ:

Мы изменили частоту DCLK на 5,12 МГц (20,48 МГц MCLK / 4), потому что на 2,56 МГц у нас было ровно 12,5 микросекунд для передачи данных и настройки для следующего импульса DRDY, а скорость 80 кГц дает нам ровно нулевой запас. На частоте 5,12 МГц у меня есть 41 такт для запуска процедуры прерывания, которую я могу немного уменьшить, если пропущу проверку второго флага и просто обработаю входящие данные. Но я чувствую, что должен хотя бы использовать проверку флага DRDY и использовать процедуру для включения второго прерывания, иначе я буду постоянно прерывать, потому что DCLK на АЦП всегда работает. Это позволяет мне считать данные 6,12 микросекунды и 6,25 микросекунды, чтобы вытаскивать их до следующего импульса DRDY. Я должен быть в состоянии сделать это на частоте SPI 32 МГц (ведомый), но, скорее всего, это будет делать на частоте 50 МГц. Это мой текущий код прерывания:

void NMI_Handler(void)
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)
{
count = 0;
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
HAL_GPIO_EXTI_Callback(GPIO_PIN_0);
//     __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);

HAL_NVIC_EnableIRQ(GPIO_PIN_1);
}
else
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1) != RESET)
{
data_pad[count] = GPIOF->IDR;
count++;
if (count == 31)
{
data_send = !data_send;
HAL_NVIC_DisableIRQ(GPIO_PIN_1);
}
__  HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
HAL_GPIO_EXTI_Callback(GPIO_PIN_1);
//      __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);
}
}
}

Я по-прежнему обеспокоен тактовыми циклами, и я полагаю, что смогу обойтись только проверкой флага DRDY, если я оперирую предположением, что единственный другой флаг EXTI, который сработает, — это тактовый вывод. Хотя я спрашиваю, как это будет работать, если SYS_TICK работает в фоновом режиме … Я должен выяснить.

Мы исследуем более быстрый процессор для обработки битов, но сейчас похоже, что PI3 не сможет справиться с этим, если он работает под управлением Linux, и я не знаю слишком много более быстрых процессоров, которые работают либо очень маленькая надежная ОСРВ, или может быть просто запрограммирована в крайнем случае …

0

Решение

10 тактов, чтобы сделать то, что мне нужно … перемещение данных займет у меня всего 1-2 такта, а у меня останется 8 для обработки прерываний …

Ни за что. Ввод прерывания (проталкивание регистров, выборка вектора и заполнение конвейера) занимает 10-12 циклов даже на Cortex-M7. Затем рассмотрим очень простой обработчик прерываний, просто переместив биты входных данных в буфер и очистив флаг прерывания:

uint32_t *p;
void handler(void) {
*p++ = GPIOA->IDR;
EXTI->PR = 0x10;
}

это переводится на что-то вроде этого

handler:
ldr     r0, .addr_of_idr // load &GPIOA->IDR
ldr     r1, [r0]         // load GPIOA->IDR
ldr     r2, .addr_ofr_p  // load &p
ldr     r3, [r2]         // load p
str     r1, [r3]         // store the value from IDR to *p
adds    r3, r3, #4       // increment p
str     r3, [r2]         // store p
ldr     r0, .addr_of_pr  // load &EXTI->PR
movs    r1, #0x10
str     r1, [r0]         // store 0x10 to EXTI->PR
bx      lr
.addr_of_p:
.word   p
.addr_of_idr
.word   0x40020010
.addr_of_pr
.word   0x40013C14

Так что это 11 инструкций, каждая из которых занимает хотя бы один цикл, после запись прерывания. Это при условии, что код, векторная таблица и стек находятся в самой быстрой области ОЗУ. Я не уверен, работают ли литералы литералов в ITCM вообще, использование непосредственных литералов добавило бы еще 3 цикла. Забудь это.

Это должно быть решено с помощью оборудования.

Контроллер имеет 6 интерфейсов SPI, выберите 4 из них. соединять DRDY всем четырем NSS булавки, DCLK все SCK булавки, и каждый DOUT прикрепить к одному MISO штырь. Теперь каждый интерфейс SPI обрабатывает один канал и может собирать до 32 бит в своем внутреннем FIFO.

Тогда я бы установил прерывание на переднем крае на одном из NSS булавки (EXTI по-прежнему работает, даже если контакт находится в режиме альтернативной функции), и считывает все данные одновременно.

РЕДАКТИРОВАТЬ

Оказывается, что SPM STM32 требует чрезмерной задержки между NSS падение и SCK повышение, которое AD7768 не обеспечивает, поэтому не будет работать.

STM32F767 имеет периферийное устройство DFSDM, предназначенное для приема данных от внешних АЦП. Он может принимать до 8 каналов последовательных данных с частотой 20 МГц и даже выполнять некоторую предварительную обработку, которая может понадобиться вашему приложению.

Проблема в том, что DFSDM не имеет DRDY На входе я точно не знаю, как можно синхронизировать передачу данных. Это может работать, утверждая START# Singal для сброса связи.

Если это не сработает, вы можете попробовать запустить каналы DFSDM, используя таймер и DMA. соединять DRDY к внешнему триггеру TIM1 или же TIM8 (другие таймеры не будут работать, потому что они подключены к более медленной шине APB1 и другому контроллеру DMA), запустите его на переднем фронте ETRи пусть он генерирует запрос DMA через ~ 20 нс. Затем позвольте DMA записать значение, необходимое для запуска канала, в регистр конфигурации канала DFSDM. Повторите для трех других каналов.

3

Другие решения

Есть файл запуска, сгенерированный перед компиляцией: startup_stm32f767xx.s — который содержит все указатели на функции.

Под маркером g_pfnVectors: является .word NMI_Handler указывая на функцию для обработки немаскированных прерываний и двух других указателей, .word EXTI0_IRQHandler а также .word EXTI1_IRQHandler как векторы для внешних обработчиков прерываний. Далее в том же файле находятся следующие директивы компилятора:

.weak      NMI_Handler
.thumb_set NMI_Handler,Default_Handler

.weak      EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler

.weak      EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler

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

0

Я внимательно прочитал AD7768 DS и обнаружил, что он может передавать данные четырех каналов на один вывод DOUT. Итак, я снова говорю о последовательном аудио интерфейсе (SAI).

Если вы можете снизить DCLK Частота до 2,5 МГц, чем вы можете понизить частоту с соотношением 1: 8 (как отношение от 2,5 МГц до 20 МГц) с частотой дискретизации при полной тактовой частоте АЦП.

Если вы направите все 4 канала на один выход DOUT0, вы уменьшите частоту дискретизации только в соотношении 1: 4.

AD7768-4 DS

страница 53

На AD7768 интерфейс может быть настроен для вывода преобразования
данные на одном, двух или восьми выводах DOUTx. Конфигурация DOUTx
для AD7768 выбирается с помощью выводов FORMATx (см. таблицу 33).

стр. 66 таблица 34: (для AD7768-4)
стр. 67, рисунок 98:

FORMAT0 = 1 Все каналы выводятся на вывод DOUT0, на выходе TDM. Используется только DOUT0.

Ты можешь использовать SAI с FS знак равно DRDY и четыре слота, 32 бита / слот

0
По вопросам рекламы [email protected]