void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* UART IDLE Interrupt */
if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) == SET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
print("time %d",timeCounter");
receivedDataFlag = 1;
}
}
Когда я использую эту функцию, проверьте состояния ожидания линии и определите, получены данные или нет. Но это прерывание срабатывает во время передачи. Как я могу разделить приемную линию данных в режиме ожидания и прием в режиме ожидания?
Я хочу инициировать простое получение линии данных, как я могу это сделать? Какой еще регистр мне посмотреть?
Я получаю очень интересный результат,
Отправитель отправляет каждые 100 мс данные на мое устройство;
Если я использую только функции приема DMA; время возврата 10, 110, 220 330 (состояния простоя работают)
Но если я получил, то после передачи данных с помощью uart эти значения времени возвращают 10,13,15, ... средняя функция передачи изменяет состояние ожидания линии, как это возможно? Связан ли UART_FLAG_IDLE только с rx?
РЕДАКТИРОВАТЬ: Кстати, я использую rs485, поэтому, когда я начинаю передачу, я устанавливаю режим передатчика tranceiver, поэтому режим приемника на стороне отправителя, поэтому мой MCU решает IDLE в этом состоянии? это возможно? Как я могу защитить эту ситуацию?
Когда я запускаю режим передачи после получения данных, то завершается обратный вызов, Когда я вызываю HAL_UART_Receive_DMA(&huart2,(uint8_t*)dma_rx_buf,DMA_BUF_SIZE); прерывание функции IDLE срабатывает каждые 5 мс, но тайм-аут отправки данных 100 мс
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_DMAStop(&huart2);
dmaTransmitCompletedFlag = 1;
RS485_Set_Receive_Mode();
HAL_UART_Receive_DMA(&huart2,(uint8_t*)dma_rx_buf,DMA_BUF_SIZE);
waitForTransmittingData = 0;
}
Это прерывание используется как для передачи, так и для приема.
IDLE относится только к приему, это означает, что обнаружен хотя бы один полный кадр ожидания.
Использование печати в прерывании неразумно, особенно если печать использует тот же UART, для которого предназначено прерывание.
Это IRQ предназначено для USART2, но оно вызывается для каждого разрешенного прерывания , связанного с USART2. Это означает, что обработчик должен проверять и обрабатывать каждый разрешенный сигнал прерывания. Для STM32 USART включает в себя основные сигналы UART, управляемого прерываниями, такие как TXNE и RXNE, а также сигналы ошибок, IDLE и т. д.
Сигнал IDLE предназначен для кадрирования многобайтовых приемов (обычная проблема для USART, особенно в шумной среде). Он активируется, когда линия приема находится в состоянии высокого уровня (или «свободна») в течение некоторого времени устранения дребезга (определяемого настройками скорости передачи/передискретизации), после того как эта линия была активной (во время приема группы из одного или нескольких байтов). . Это полезно, потому что вы можете использовать его для сброса вашего приемного буфера обратно в индекс «0», чтобы следующий кадр был правильно выстроен (даже если в текущем кадре было получено слишком мало или слишком много байтов). Обычно вам приходится реализовывать такую логику с помощью выделенного периферийного устройства таймера, но STM32 удобно упаковывает его в свои периферийные устройства USART (хотя это не поддерживается собственным драйвером HAL).
Если вы действительно хотите, чтобы только сигнал ожидания вызывал прерывание, вам нужно вручную отключить все остальные сигналы прерывания. Если вам нужен полезный приемник UART, управляемый прерываниями, я не советую вам это делать.
Из одного из ваших предыдущих вопросов я дал вам несколько ссылок, где это реализовано.
USART3_IRQHandler(void) {
/* Check for IDLE line interrupt */
if (LL_USART_IsEnabledIT_IDLE(USART3) && LL_USART_IsActiveFlag_IDLE(USART3)) {
LL_USART_ClearFlag_IDLE(USART3); /* Clear IDLE line flag */
usart_rx_check(); /* Check for data to process */
}
/* Implement other events when needed */
}
НержавеющаяСтальКрыса
Только я
НержавеющаяСтальКрыса
Джероен3