|
|
  |
STM32L4 прерывания от UART. Закипел. |
|
|
|
May 11 2016, 08:05
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Пишу код под Nucleo L476. Кубом. И вручную. Результат тот же. Поднял UART1. UART работает. Но прерываний нет. Ни в коде от Куба ни в моем коде. Вручную настраивал так: Код USART1->CR1 = 1<<7 | //Bit 7 TXEIE: interrupt enable 1<<6 | //Bit 6 TCIE: Transmission complete interrupt enable 1<<5 | //Bit 5 RXNEIE: RXNE interrupt enable 1<<3 | //Bit 3 TE: Transmitter enable 1<<2 | //Bit 2 RE: Receiver enable 1<<0; //Bit 0 UE: USART enable USART1->CR2 = 1<<11; //Bit 11 CLKEN: Clock enable USART1->BRR = 0x271; //Tx/Rx baud = f CK / BRR. Oversampling by 16 Если выполнить макрос, разрешающий 37-е прерывание: Код NVIC->ISER[(((uint32_t)(int32_t)37) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)37) & 0x1FUL)); То в моем варианте все виснет. Точно такой же макрос с параметром 37 есть в коде от Куба. Но он не вешает систему. Прерываний просто нет. И да, прерывания от SYSTIC работают в обоих случаях. Мож кто подскажет в чем дело или примерчик рабочий... Хотя под L476 я мало чего нахожу в Сети.
Сообщение отредактировал Димон Безпарольный - May 11 2016, 08:06
|
|
|
|
|
May 11 2016, 09:43
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(Сергей Борщ @ May 11 2016, 12:15)  Тогда что вы вкладываете в понятие "виснет"? Процессор же не может ничего не делать (если не спит). Он должен выполнять какие-то команды. Могу телепатически предположить, что у вас в соответствующий вектор не прописан адрес вашего обработчика и поэтому ядро улетает в общий обработчик, который обычно состоит из пустого цикла. Не улетает. Я по зажиганию светодиода сужу. Виснет это как раз когда не выполняются основной процесс и SysTic. Опять же по светодиоду могу сказать что в исключениях процессор тоже не был. Где он присутствует пока сказать не могу. Вектора все прописаны. Проверял. В ISER[1] ставил пятый бит вручную - не помогло. Меня в меньшей степени интересует собственный код. Т.е. где виснет. Меня интересует код от Куба, где не виснет но и не выполняется код прерывания от UART. Его я ковыряю. Не пойму я состояние. ISER1 - пятый бит установлен(прерывание 37). Он тут же ставится и в ICER1. После загрузки TDR регистра, передача байта идет исправно, но прерывания в Pending регистрах нет. И прерывания нет. Чего ж я все - таки забыл сделать? Чертова документация. PM0214, Generic User Guide, RM0351 аж о 1600 страницах! Ни в одном нет полного описания регистров NVIC. Что ж за регистр ICTR и STIR которые есть в отладчике, но нет ни в одной документации. Код: Код USART1->TDR = 0x65; USART1->TDR = 0x85; Передает только первый байт. ОК. Код: Код USART1->TDR = 0x65; while((USART1->ISR & (1<<6)) == 0) {}; USART1->TDR = 0x85; Передает оба байта. Значит бит TC: Transmission complete (или можно бит 7 Transmit data register empty) работает исправно. Прерывание по нему разрешено. Но нихрена не выполняется. Прочитал регистр USART1->CR1. Окаывается Куб не выставил бит разрешения прерывания (бит 6). Победил и прием. Была проблема при отключении HAL_UART_IRQHandler(&huart1);. Я не понимаю как это возможно, но отключить эту функцию не так просто. Без нее тоже висло намертво. Даже при очистке функции до пустых скобок. И только отключив оптимизатор я смог избавится от этой дряни. Вот код на прием и передачу. Работает. Код void USART1_IRQHandler(void) {
/* USER CODE BEGIN USART1_IRQn 0 */ if(Led) {Led=0; GPIOA->BSRR = 32;} else {Led=1; GPIOA->BSRR = (32<<16);} if (USART1->ISR & (1<<6)) {USART1->ICR |=(1<<6);} if (USART1->ISR & (1<<5)) {USART1->ICR |=(1<<5); USART1->TDR = USART1->RDR;} //USART1->ICR |= (1<<6);
/* USER CODE END USART1_IRQn 0 */ //HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */ } Не понимаю почему я должен читать ISR: USART1->ISR & (1<<6) тогда как по смыслу правильнее было бы читать ICR. И чтение там допускается. Но опять же не работает нихрена - виснет. В коде мало смысла, но для понимания работы пойдет. Оказывается Кубу не досуг ставить биты разрешения прерываний на прием и передачу. Пришлось самому. Ручками: Код USART1->CR1 |= (1<<6); //translate USART1->CR1 |= (1<<5); //recieve Всем спасибо за помощь.
Сообщение отредактировал Димон Безпарольный - May 11 2016, 14:12
|
|
|
|
|
May 11 2016, 20:31
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
А такая команда отправляет буфер? Код HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE); Для этой платы есть несколько примеров c UART(USART) от ST, и с прерыванием, и с DMA, и простой передачей, и с просыпанием от UARTA и не верится что они там ошиблись.
|
|
|
|
|
May 11 2016, 22:09
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(Lagman @ May 11 2016, 23:31)  А такая команда отправляет буфер? Код HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE); Для этой платы есть несколько примеров c UART(USART) от ST, и с прерыванием, и с DMA, и простой передачей, и с просыпанием от UARTA и не верится что они там ошиблись. Они может и не ошиблись, но Куб не ставит 5 и 6 бит на прерывания. Хотя я галочку в Кубе ставил на Global Interrupt Usart1. Да и где ему ставить если: Код huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&huart1);
Сообщение отредактировал Димон Безпарольный - May 11 2016, 22:13
|
|
|
|
|
May 12 2016, 09:35
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Димон Безпарольный @ May 11 2016, 10:43)  Не понимаю почему я должен читать ISR: USART1->ISR & (1<<6) тогда как по смыслу правильнее было бы читать ICR. И чтение там допускается. Но опять же не работает нихрена - виснет. В этой фразе - иллюстрация не полного понимания работы устройства. Это не в упрёк, - все были новичками, - это для анализа ошибок. ISR - регистр СТАТУСА (status), ICR - регистр УПРАВЛЕНИЯ (control). Биты последнего можно читать, да, но они не устанавливаются как результат работы устройства, а потому не отображают его состояния. Для этого есть регистр статуса, и пусть не смущает, что расположение битов в этих регистрах может совпадать и таким образом вводить в заблуждение.
|
|
|
|
|
May 12 2016, 11:18
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(ViKo @ May 12 2016, 12:03)  Забейте на Куб. Он не для работы. А для демонстрации работоспособности. Я запрограммировал регистры USART одной функцией, и все работает, по прерыванию, естественно. Не в данном МК, но разница невелика. Для этого я и ковырял Куб, чтобы понять суть и сделать уже свой проект. Без излишиств и недостатков. В итоге все получилось. Off. Достал меня Эклипс. Не смог прикрутить PrintF. Кейловские технологии не прокатили. Буду переходить на Кейл.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|