Перейти к содержанию
    

STM32L4 прерывания от UART. Закипел.

Пишу код под 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 я мало чего нахожу в Сети.

 

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То в моем варианте все виснет
Вот просто напрочь виснет? И даже отладчик перестает отзываться?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот просто напрочь виснет? И даже отладчик перестает отзываться?

Нет, отладчик работает. Я сейчас в нем ковыряюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, отладчик работает. Я сейчас в нем ковыряюсь.

Отладчик позволяет увидеть всё: UART, NVIC, процессор. Соответственно, без особого труда можно пройтись по всей цепочке и установить, что именно сработало не так.

Поэтому да, лучше ковыряйтесь в отладчике, чем в форуме :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда что вы вкладываете в понятие "виснет"? Процессор же не может ничего не делать (если не спит). Он должен выполнять какие-то команды. Могу телепатически предположить, что у вас в соответствующий вектор не прописан адрес вашего обработчика и поэтому ядро улетает в общий обработчик, который обычно состоит из пустого цикла.

Не улетает. Я по зажиганию светодиода сужу. Виснет это как раз когда не выполняются основной процесс и 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:

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А такая команда отправляет буфер?

HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE);

Для этой платы есть несколько примеров c UART(USART) от ST, и с прерыванием, и с DMA, и простой передачей, и с просыпанием от UARTA и не верится что они там ошиблись.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А такая команда отправляет буфер?

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);

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть они весь мир обманули с примером UART_TwoBoards_ComIT ?

Срочно напишите им - пусть исправят немедленно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забейте на Куб. Он не для работы. А для демонстрации работоспособности.

Я запрограммировал регистры USART одной функцией, и все работает, по прерыванию, естественно. Не в данном МК, но разница невелика.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не понимаю почему я должен читать ISR: USART1->ISR & (1<<6) тогда как по смыслу правильнее было бы читать ICR. И чтение там допускается. Но опять же не работает нихрена - виснет.

В этой фразе - иллюстрация не полного понимания работы устройства. Это не в упрёк, - все были новичками, - это для анализа ошибок.

ISR - регистр СТАТУСА (status), ICR - регистр УПРАВЛЕНИЯ (control). Биты последнего можно читать, да, но они не устанавливаются как результат работы устройства, а потому не отображают его состояния. Для этого есть регистр статуса, и пусть не смущает, что расположение битов в этих регистрах может совпадать и таким образом вводить в заблуждение.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забейте на Куб. Он не для работы. А для демонстрации работоспособности.

Я запрограммировал регистры USART одной функцией, и все работает, по прерыванию, естественно. Не в данном МК, но разница невелика.

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

 

Off. Достал меня Эклипс. Не смог прикрутить PrintF. Кейловские технологии не прокатили. Буду переходить на Кейл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Работает Куб. У меня. Читать нужно внимательно. Переписывать или свое прерывание писать там не предполагается. А писать нужно в callback-функцию. Там их, кажется мне, две - половинное и полное завершение. И, соответственно, два раза прерывание вызывается. И эти функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Работает Куб. У меня. Читать нужно внимательно. Переписывать или свое прерывание писать там не предполагается. А писать нужно в callback-функцию. Там их, кажется мне, две - половинное и полное завершение. И, соответственно, два раза прерывание вызывается. И эти функции.

В посте 8 я привел настройки uart1. Про 5 и 6 бит там не упоминается. Соответственно без них прерывания на прием и передачу работать не будут. Приведите свой код если Вы утверждаете что эти биты устанавливаются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Off. Достал меня Эклипс. Не смог прикрутить PrintF. Кейловские технологии не прокатили. Буду переходить на Кейл.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...