реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> STM32L4 прерывания от UART. Закипел.
Димон Безпарольн...
сообщение May 11 2016, 08:05
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 11 2016, 08:28
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Димон Безпарольный @ May 11 2016, 11:05) *
То в моем варианте все виснет
Вот просто напрочь виснет? И даже отладчик перестает отзываться?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение May 11 2016, 08:57
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(Сергей Борщ @ May 11 2016, 11:28) *
Вот просто напрочь виснет? И даже отладчик перестает отзываться?

Нет, отладчик работает. Я сейчас в нем ковыряюсь.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 11 2016, 09:15
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Димон Безпарольный @ May 11 2016, 11:57) *
Нет, отладчик работает.
Тогда что вы вкладываете в понятие "виснет"? Процессор же не может ничего не делать (если не спит). Он должен выполнять какие-то команды. Могу телепатически предположить, что у вас в соответствующий вектор не прописан адрес вашего обработчика и поэтому ядро улетает в общий обработчик, который обычно состоит из пустого цикла.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
scifi
сообщение May 11 2016, 09:38
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Димон Безпарольный @ May 11 2016, 11:57) *
Нет, отладчик работает. Я сейчас в нем ковыряюсь.

Отладчик позволяет увидеть всё: UART, NVIC, процессор. Соответственно, без особого труда можно пройтись по всей цепочке и установить, что именно сработало не так.
Поэтому да, лучше ковыряйтесь в отладчике, чем в форуме laughing.gif
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение May 11 2016, 09:43
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 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


Всем спасибо за помощь. rolleyes.gif

Сообщение отредактировал Димон Безпарольный - May 11 2016, 14:12
Go to the top of the page
 
+Quote Post
Lagman
сообщение May 11 2016, 20:31
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



А такая команда отправляет буфер?
Код
HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE);

Для этой платы есть несколько примеров c UART(USART) от ST, и с прерыванием, и с DMA, и простой передачей, и с просыпанием от UARTA и не верится что они там ошиблись.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение May 11 2016, 22:09
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
x893
сообщение May 12 2016, 06:42
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



То есть они весь мир обманули с примером UART_TwoBoards_ComIT ?
Срочно напишите им - пусть исправят немедленно.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 12 2016, 09:03
Сообщение #10


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Забейте на Куб. Он не для работы. А для демонстрации работоспособности.
Я запрограммировал регистры USART одной функцией, и все работает, по прерыванию, естественно. Не в данном МК, но разница невелика.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение May 12 2016, 09:35
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Димон Безпарольный @ May 11 2016, 10:43) *
Не понимаю почему я должен читать ISR: USART1->ISR & (1<<6) тогда как по смыслу правильнее было бы читать ICR. И чтение там допускается. Но опять же не работает нихрена - виснет.

В этой фразе - иллюстрация не полного понимания работы устройства. Это не в упрёк, - все были новичками, - это для анализа ошибок.
ISR - регистр СТАТУСА (status), ICR - регистр УПРАВЛЕНИЯ (control). Биты последнего можно читать, да, но они не устанавливаются как результат работы устройства, а потому не отображают его состояния. Для этого есть регистр статуса, и пусть не смущает, что расположение битов в этих регистрах может совпадать и таким образом вводить в заблуждение.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение May 12 2016, 11:18
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(ViKo @ May 12 2016, 12:03) *
Забейте на Куб. Он не для работы. А для демонстрации работоспособности.
Я запрограммировал регистры USART одной функцией, и все работает, по прерыванию, естественно. Не в данном МК, но разница невелика.

Для этого я и ковырял Куб, чтобы понять суть и сделать уже свой проект. Без излишиств и недостатков. В итоге все получилось.

Off. Достал меня Эклипс. Не смог прикрутить PrintF. Кейловские технологии не прокатили. Буду переходить на Кейл.
Go to the top of the page
 
+Quote Post
Tanya
сообщение May 12 2016, 13:50
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(Димон Безпарольный @ May 12 2016, 14:18) *
Для этого я и ковырял Куб, чтобы понять суть и сделать уже свой проект.

Работает Куб. У меня. Читать нужно внимательно. Переписывать или свое прерывание писать там не предполагается. А писать нужно в callback-функцию. Там их, кажется мне, две - половинное и полное завершение. И, соответственно, два раза прерывание вызывается. И эти функции.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение May 12 2016, 14:41
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(Tanya @ May 12 2016, 16:50) *
Работает Куб. У меня. Читать нужно внимательно. Переписывать или свое прерывание писать там не предполагается. А писать нужно в callback-функцию. Там их, кажется мне, две - половинное и полное завершение. И, соответственно, два раза прерывание вызывается. И эти функции.

В посте 8 я привел настройки uart1. Про 5 и 6 бит там не упоминается. Соответственно без них прерывания на прием и передачу работать не будут. Приведите свой код если Вы утверждаете что эти биты устанавливаются.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 12 2016, 15:48
Сообщение #15


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Димон Безпарольный @ May 12 2016, 14:18) *
Off. Достал меня Эклипс. Не смог прикрутить PrintF. Кейловские технологии не прокатили. Буду переходить на Кейл.

Вот интересно, какая связь между эклипсом и printf()


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 21:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.0153 секунд с 7
ELECTRONIX ©2004-2016