Нет прерывания от UART.

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

ezlydnev
Сообщения: 10
Зарегистрирован: 11 фев 2021, 11:50
Предприятие: НИИИТ-РК

Нет прерывания от UART.

Сообщение ezlydnev »

Здраствуйте, не могу разобраться с прерыванием от UART. В частности от UART 3.
Программа простая:
1) Проинициализировал UART, и по нажатию кнопки высылаю строку.
2) По приему строки в прерывании мигаю светодиодами.

С отправкой проблем не возникло, так как там реализовал через прерывание порта вх/вых.
С приемом никак не получается, не входит в прерывание UART3. Не входит даже при отправке хотя вроде должен.
Включал/отключал буфер фифо, менял настройки по котором срабатывает прерывание фифо. Это не помогло.

В чем может быть проблема?

Код инициализации ниже.

Код: Выделить всё

void USART_Init(void)
{
	  // Vybor 3 alternativnoy funkcii dlya F12 and F13. Smotri ERRATA    
	  NT_COMMON_REG->GPIOPCTLF_bit.PIN12 = 0x2, /*!< third alternative function for pin */
    NT_COMMON_REG->GPIOPCTLF_bit.PIN13 = 0x2, /*!< third alternative function for pin */

		 // Vybor 2 alternativnoy funkcii dlya D1 and D2. 
     // D1 - RX
	   // D2 - TX  
	  NT_GPIOD -> OUTENSET |= 0x0004; // VKLYCHITb PORT D[2] na VYHOD
	  NT_GPIOD->ALTFUNCSET |= (1 << 2) | (1 << 1); // vkl alternative function
   
    NT_COMMON_REG->GPIOPCTLD_bit.PIN2 |= 0x1, /*!< second alternative function for pin */
    NT_COMMON_REG->GPIOPCTLD_bit.PIN1 |= 0x1, /*!< second alternative function for pin */
    NT_COMMON_REG->GPIODEND |= (1 << 2) | (1 << 1); // vkl D1 i D2
	  
	
	
	
// UART 3 INIT. speed = 115200, sysclock = 75 MGh 
	NT_COMMON_REG -> PER_RST0 |= COMMON_REG_PER_RST0_UARTRST3_Msk; // reset usart
	NT_COMMON_REG -> UART_CLK |=  COMMON_REG_UART_CLK_CLKEN_UART3_Msk | COMMON_REG_UART_CLK_DIVEN_UART3_Msk;
 	NT_COMMON_REG -> UART_SPI_CLK_SEL_bit.SEL_UART3 = 0; // SYS_FREQ taktiryet UART3
	NT_COMMON_REG -> UART_CLK_bit.DIV_UART3 = 5; // delitelb na 10. UART CLK = 75/5 = 15 MGh 
	// on del, on clk 
 
  
	NT_UART3  -> CR_bit.UARTEN = 0;
	NT_UART3 -> IBRD = 3; // chelaya chastb delitelya.
        NT_UART3 -> FBRD = 15;	// drobnaya chastb 
	NT_UART3 -> LCR_H_bit.PEN = 0; // chetnostb off
	NT_UART3 -> LCR_H_bit.STP2 = 0; // 1 stop bit
	NT_UART3 -> LCR_H_bit.FEN = 0; // FIFO OFF
	NT_UART3 -> LCR_H_bit.WLEN = 3; // 8 bit mode 
	NT_UART3  -> CR_bit.TXE = 1;
	NT_UART3  -> CR_bit.RXE = 1;
	NT_UART3  -> CR_bit.UARTEN = 1;
	Энвик_ClearPendingIRQ(UART3_IRQn); // CLEAR IQR AND ON IRQ3 
	Энвик_EnableIRQ(UART3_IRQn);
	 
	 NT_UART3 -> ICR  = 1;
	 
}


Программа Основная

Код: Выделить всё


int main()
{    

	   SystemInit();
	   SystemCoreClockUpdate();
           GPIO_Init();
	  USART_Init(); 
	    while (1) {

	};
    return 0;
}



 void GPIOF_IRQHandler(void)
 {
 NT_GPIOF -> INTSTATUS = 0xFFFF;// sbros IQR
	USART_3_send_string ("0W");
NT_GPIOC ->DATAOUT ^= 0x3E00;
 }


 void UART3_IRQHandler(void)
 {
 	  char uart_data;
	 if (NT_UART3 -> RIS_bit.RXRIS == 1 & NT_UART3 -> RIS_bit.OERIS == 1)
{
	 if (uart_data=='1') 
	  NT_GPIOC ->DATAOUT ^= 0x3D00; // esli nazhali 1

	 NT_UART3 -> ICR_bit.RXIC  = 1;
         NT_UART3 -> ICR_bit.OEIC  = 1;	 
  }
	 NT_UART3 -> ICR  = 1;
}	 

ezlydnev
Сообщения: 10
Зарегистрирован: 11 фев 2021, 11:50
Предприятие: НИИИТ-РК

Re: Нет прерывания от UART.

Сообщение ezlydnev »

Забыл добавить по приходу сообщения меняются биты RXRIS и OERIS. По отправке меняется значение TXRIS. т.е. UART работает. Но в прерывание все равно не хочет идти.
Вложения
фрагмент.PNG
фрагмент.PNG (3.97 КБ) 2096 просмотров
dav
Сообщения: 208
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: Нет прерывания от UART.

Сообщение dav »

Доброго времени суток!
При записи в регистры с окончанием SET и CLEAR не допускается использование операций "чтение-модификация-запись".
Попробуйте изменить код инициализации:

Код: Выделить всё

void USART_Init(void)
{
	  // Vybor 3 alternativnoy funkcii dlya F12 and F13. Smotri ERRATA    
	  NT_COMMON_REG->GPIOPCTLF_bit.PIN12 = 0x2, /*!< third alternative function for pin */
    	  NT_COMMON_REG->GPIOPCTLF_bit.PIN13 = 0x2, /*!< third alternative function for pin */

	 // Vybor 2 alternativnoy funkcii dlya D1 and D2. 
     	   // D1 - RX
	   // D2 - TX  
	  //NT_GPIOD -> OUTENSET = 0x0004; // VKLYCHITb PORT D[2] na VYHOD Не обязательно, т.к. используется альтернативная функция, а не режим порта общего назначения.
	  NT_GPIOD->ALTFUNCSET = (1 << 2) | (1 << 1); // vkl alternative function
   
    NT_COMMON_REG->GPIOPCTLD_bit.PIN2 = 0x1, /*!< second alternative function for pin */
    NT_COMMON_REG->GPIOPCTLD_bit.PIN1 = 0x1, /*!< second alternative function for pin */
    NT_COMMON_REG->GPIODEND |= (1 << 2) | (1 << 1); // vkl D1 i D2
	  
	
	
	
// UART 3 INIT. speed = 115200, sysclock = 75 MGh 
	NT_COMMON_REG -> PER_RST0 |= COMMON_REG_PER_RST0_UARTRST3_Msk; // reset usart
	NT_COMMON_REG -> UART_CLK |=  COMMON_REG_UART_CLK_CLKEN_UART3_Msk | COMMON_REG_UART_CLK_DIVEN_UART3_Msk;
 	NT_COMMON_REG -> UART_SPI_CLK_SEL_bit.SEL_UART3 = 0; // SYS_FREQ taktiryet UART3
	NT_COMMON_REG -> UART_CLK_bit.DIV_UART3 = 5; // delitelb na 10. UART CLK = 75/5 = 15 MGh 
	// on del, on clk 
 
  
	NT_UART3  -> CR_bit.UARTEN = 0;
	NT_UART3 -> IBRD = 3; // chelaya chastb delitelya.
        NT_UART3 -> FBRD = 15;	// drobnaya chastb 
	NT_UART3 -> LCR_H_bit.PEN = 0; // chetnostb off
	NT_UART3 -> LCR_H_bit.STP2 = 0; // 1 stop bit
	NT_UART3 -> LCR_H_bit.FEN = 0; // FIFO OFF
	NT_UART3 -> LCR_H_bit.WLEN = 3; // 8 bit mode 
	NT_UART3  -> CR_bit.TXE = 1;
	NT_UART3  -> CR_bit.RXE = 1;
	NT_UART3  -> CR_bit.UARTEN = 1;
	Энвик_ClearPendingIRQ(UART3_IRQn); // CLEAR IQR AND ON IRQ3 
	Энвик_EnableIRQ(UART3_IRQn);
	 
	 NT_UART3 -> ICR  = 1;
	 
}
ezlydnev
Сообщения: 10
Зарегистрирован: 11 фев 2021, 11:50
Предприятие: НИИИТ-РК

Re: Нет прерывания от UART.

Сообщение ezlydnev »

Здраствуйте. Исправил код по вашему совету. Но к сожалению не помогло.
Данные в DATA поле DR и биты в регистре RIS устанавливаются верно. Поэтому я думаю, что UART работает и инициализация правильная.
Почему может не отработать прерывание? Там же только одна команда Энвик_EnableIRQ(UART3_IRQn)? ФИФО выключено и не должно влиять на прерывание. Настройки НВИКА не трогал. Или еще какие-то нюансы есть? Прочитал весь документ не смог найти каких-то доп. настроек.
К сожалению у меня только одна отладочная плата. Нет возможности проверить на другом контролере. Может быть аппаратная проблема с данным экземпляром?
Вложения
фрагмент 2.PNG
фрагмент 2.PNG (9.44 КБ) 2058 просмотров
Снимок 1.PNG
Снимок 1.PNG (11.8 КБ) 2058 просмотров
Al-x
Сообщения: 29
Зарегистрирован: 02 фев 2021, 19:22
Предприятие: АО "НТЦ "РИФ"

Re: Нет прерывания от UART.

Сообщение Al-x »

Речь о 1921ВК01Т?

А в MIS регистре так же всё верно? Не пробовали IMSC менять?
ezlydnev
Сообщения: 10
Зарегистрирован: 11 фев 2021, 11:50
Предприятие: НИИИТ-РК

Re: Нет прерывания от UART.

Сообщение ezlydnev »

Здраствуйте!
Да, про 1921ВК01Т.

Спасибо за совет. Поменял маску регистра IMSC. Получается так:
1) при сбросе IMSC нулевой.
2) Регистр MIS не меняется при событиях оправки/передачи в отличии от RIS.
3) Когда в IMSC установил все единицы, начал меняться MIS.
4) Только после этого начало входить в прерывание

Я планировал маскировать RIS в самом коде и там уже решить что за прерывание конкретно случилось.
В итоге как я понял уставка маски обязательна, иначе в прерывание не идет. Я изначально думал что это как доп. опция для регистрации конкретного прерывания. А это необходимая настройка даже если не собираешься использовать это аппаратно-маскированное значение MIS.
Al-x
Сообщения: 29
Зарегистрирован: 02 фев 2021, 19:22
Предприятие: АО "НТЦ "РИФ"

Re: Нет прерывания от UART.

Сообщение Al-x »

ezlydnev писал(а): 10 сен 2021, 13:15 В итоге как я понял уставка маски обязательна, иначе в прерывание не идет. Я изначально думал что это как доп. опция для регистрации конкретного прерывания. А это необходимая настройка даже если не собираешься использовать это аппаратно-маскированное значение MIS.
Как правило, у всех импортных есть регистр, которой определяет какое из событий вызывает прерывание и его инициализация обязательна. У НИИЭТа кривое описание: "Каждый из сигналов может быть маскирован путем сброса соответствующего бита в регистре маски SPI_IMSC." вместо прямого указания, что биты необходимо установить.
ezlydnev
Сообщения: 10
Зарегистрирован: 11 фев 2021, 11:50
Предприятие: НИИИТ-РК

Re: Нет прерывания от UART.

Сообщение ezlydnev »

В stm32 вызывается прерывание на любое событие связанное с UART. Потом уже в прерывании смотришь какой бит в регистре в сост. лог 1, и в зависимости от этого действуешь. Так же я думал и здесь поступить.

Но действительно того, что маску надо накладывать в обязательном порядке нет. Это конечно смутило меня.
Paul125
Сообщения: 15
Зарегистрирован: 11 май 2022, 17:02
Предприятие: ООО НПП ЭКРА

Re: Нет прерывания от UART.

Сообщение Paul125 »

Добрый день!
Хочу поинтересоваться у знающих людей, кто смог победить UART.
В описании вижу прерывание UART_RT, которое срабатывает:
- при выдержке времени в 32 бита на входящей линии + обязательно в принимающем регистре были данные.
Вот дословно выдержка из описания.
UART_RT
Прерывание возникает в случае, если буфер приемника не пуст, и на вход приемника не поступало новых данных в течение периода времени, необходимого для передачи 32 бит. Прерывание сбрасывается после считывания данных из буфера приемника до его опустошения или программно.

Но я не могу обеспечить данные условия, в каком бы режиме работал (с FIFO или в однобайтном режиме), я всегда вычитываю принимающий регистр (или FIFO и регистр копирует данные в FIFO и снова пуст) и данное прерывание не срабатывает.
Может быть можно как то читать данные но сбрасывать пустоту принимающего регистра (или взводить его переполнение после чтения)?
Возможно в моей логике приема ошибка и как то хитро надо читать данные с принимающего регистра... или это баг данного UARTа.
Прошу помощи, весь мозг уже сломал.

Прерывание и маску включил.

Код: Выделить всё

Энвик_EnableIRQ(UART3_RT_IRQn);
UART_ITCmd(NT_UART3, UART_ITSource_RecieveTimeout, ENABLE);
dav
Сообщения: 208
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: Нет прерывания от UART.

Сообщение dav »

Paul125 писал(а): 04 июл 2022, 14:21 В описании вижу прерывание UART_RT, которое срабатывает:
UART_RT
Прерывание возникает в случае, если буфер приемника не пуст, и на вход приемника не поступало новых данных в течение периода времени, необходимого для передачи 32 бит. Прерывание сбрасывается после считывания данных из буфера приемника до его опустошения или программно.

Но я не могу обеспечить данные условия, в каком бы режиме работал (с FIFO или в однобайтном режиме), я всегда вычитываю принимающий регистр (или FIFO и регистр копирует данные в FIFO и снова пуст) и данное прерывание не срабатывает.

Доброго времени суток!
Данное прерывание можно использовать, например, при использовании в проекте более высокоприоритетных прерываний от другой периферии, и если не успели прочитать данные из входного буфера в течение периода времени, необходимого для передачи 32 бит, только тогда и переходить к обработке приема байта полученного по UART. Если необходимо отслеживать таймаут между принимаемыми байтами, то необходимо задействовать один из аппаратных таймеров.

1. Для каких целей предполагаете использовать прерывание по таймауту?
2. Принимающий регистр вычитываете в другом прерывании UART?
Ответить

Вернуться в «32-разрядные микроконтроллеры»