|
Прием по USART |
|
|
|
Aug 31 2018, 10:17
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Камень STM32F303CB.Принимаю данные Код void USART2_IRQHandler(void) { if ((USART2->ISR & USART_ISR_RXNE) != RESET) { uint8_t chr = USART2->RDR;
if (chr == '\r') { usart2_rx_buf[usart2_rx_idx] = '\0'; usart2_rx_idx = 0; usart2_rx_ready = 1; } else { if(usart2_rx_idx < RX2_BUFFERSIZE) //no overflow { usart2_rx_buf[usart2_rx_idx] = chr; usart2_rx_idx++; } else usart2_rx_overflow = 1; } } } после рисета первый раз я попадаю в условие USART2->ISR & USART_ISR_RXNE - в регистре ISR я вижу RXNE = 1. И все - все последующте разы я не захожу в условие так как RXNE = 0. В документации написано что при приеме данных в USART2->RDR флаг взводиться RXNE = 1 а при чтении из USART2->RDR - флаг очищается RXNE =0. Что я делаю не так? Еще такая проблема - я все время захожу в USART2_IRQHandler - даже когда размыкаю провод RX - хотя у меня включено только одно прерывание - по принятию - Код USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); NVIC_EnableIRQ(USART2_IRQn);
Сообщение отредактировал Jenya7 - Aug 31 2018, 11:58
|
|
|
|
|
 |
Ответов
|
Sep 7 2018, 08:22
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
я отладил прием Код void USART2_IRQHandler(void) { uint8_t chr; uint32_t sr = USART2->ISR; if (sr & USART_ISR_RXNE) { chr = (uint16_t)(USART2->RDR); if (chr == '\r') { usart2_rx_buf[usart2_rx_idx] = '\0'; usart2_rx_idx = 0; usart2_rx_ready = 1; } else { if(usart2_rx_idx < RX2_BUFFERSIZE) //no overflow { usart2_rx_buf[usart2_rx_idx] = chr; usart2_rx_idx++; } else usart2_rx_overflow = 1; } } USART2->ICR = (uint16_t)~USART_FLAG_RXNE; } Проблема такая. Мастер посылает Код USART_SendBuf(USART2, "MBE\r", 4);
Delay_ms(100); И слейв принимает исправно. Но если убираю задержку - Delay_ms(100); слейв принимает как попало "МMBE\r" , "MBЕE\r" , "\0BЕE\r". Как можно улучшить прием? 10 мили - Delay_ms(10) - тоже работает нормально. меньше - ломается. нет Delay_ms(10) - тоже ломается.
Сообщение отредактировал Jenya7 - Sep 7 2018, 08:58
|
|
|
|
|
Sep 9 2018, 06:15
|

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

|
QUOTE (Jenya7 @ Sep 9 2018, 08:04)  если знаете укажите. Указывал уже. Толку-то? QUOTE (Сергей Борщ @ Aug 31 2018, 16:43)  Чудес не бывает. Либо у вас остался взведенным флаг этого события, либо разрешено прерывание по какому-то еще. Чтобы это узнать, достаточно прочитать регистры настройки и описание их содержимого. Попав в прервание сначала читаем SR, чтобы узнать, какие из флагов выставлены и какие биты отвечают за разрешение прерывания по этим флагам. Потом читаем регистры с этими битами разрешения и выясняем, какое именно событие могло вызвать переход в обработчик прерывания.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 9 2018, 07:21
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Sep 9 2018, 12:15)  Указывал уже. Толку-то? У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его. Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу. Вы можете и дальше умничать и говорить тривиальные вещи. Главное чтоб Вам от этого было хорошо. Я для этого открываю темы. Чтоб люди заходили и объясняли мне какое я гавно и какие они умные. А то я ж до сих пор это не понял.
Сообщение отредактировал Jenya7 - Sep 9 2018, 07:42
|
|
|
|
|
Sep 9 2018, 09:59
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(Jenya7 @ Sep 9 2018, 10:21)  У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его. Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу. Я что-то не понимаю: зачем просматривать отладчиком периферийные регистры, чувствительные к чтению? Естественно, нормально ничего работать не будет, потому что на точке останова в начале прерывания отладчик считывает регистры USART-модуля, в том числе RDR. При этом очищается RXNE и поэтому дальше по коду RXNE никогда не будет взведен. 1. В обработчике вставьте такой код Код unsigned int USART_ISRValue; void USART1_IRQHandler(void) { USART_ISRValue = USART1->ISR; if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { unsigned char CurrentSymbol = USART_ReceiveData(USART1); USART_SendData(USART1, CurrentSymbol); USART_ClearITPendingBit(USART1, USART_IT_RXNE); } return; } 2. Зайдите в режим отладки. 3. Сбросьте все точки останова. 4. Закройте окно регистров USART в отладчике. 5. Поставьте точку останова на "return" в обработчике прерывания. 6. Откройте любой терминал, и отправьте 1 символ на плату - у Вас сработает точка останова. 7. Зафиксируйте значение USART_ISRValue - какое оно? 8. Теперь откройте окошки регистров USART. 9. Не убирая точки останова, убедитесь, что все работает также. 10. А вот теперь переместите точку останова на строчку Код USART_ISRValue = USART1->ISR; 11. Отправьте символ на МК, дождитесь срабатывания точки останова. 12. Сделайте 1 шаг (считайте значение USART_ISRValue). Как видно, оно отличается от значения в прошлых пунктах. Выводы: - Нельзя пользоваться бездумно отладчиком при работе с чувствительной к чтению регистровой моделью периферии.
- USART2->ICR = (uint16_t)~USART_FLAG_RXNE; - полная параша, убрать это нужно.
Цитата Проблема такая. Мастер посылает Код USART_SendBuf(USART2, "MBE\r", 4);
Delay_ms(100); И слейв принимает исправно. Но если убираю задержку - Delay_ms(100); слейв принимает как попало "МMBE\r" , "MBЕE\r" , "\0BЕE\r". Как можно улучшить прием? 10 мили - Delay_ms(10) - тоже работает нормально. меньше - ломается. нет Delay_ms(10) - тоже ломается. 4 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце. Устали Вы меня...
|
|
|
|
|
Sep 9 2018, 10:08
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Arlleex @ Sep 9 2018, 15:59)  4 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце. Устали Вы меня... а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному? я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error). вопрос как с этим бороться. если посылать пинг-понг ORE и FE не взводяться. хотя NF иногда проскакивает.
Сообщение отредактировал Jenya7 - Sep 9 2018, 12:28
|
|
|
|
|
Sep 9 2018, 12:27
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(Jenya7 @ Sep 9 2018, 13:08)  а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному? А, не туда посмотрел. Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не Код USART_SendBuf(USART2, "MBE\r"); Цитата(Jenya7 @ Sep 9 2018, 13:08)  я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error). вопрос как с этим бороться. Вам об этом еще выше писали. А Вы все "да у меня только одно прерывание срабатывает"... Я Вас не зря попросил регистр статуса целиком в переменную загнать и под отладчиком глянуть. Процессор на какой частоте работает и на какой скорости UART обмен ведет?
|
|
|
|
Сообщений в этой теме
Jenya7 Прием по USART Aug 31 2018, 10:17 x893 Начните с примеров. Aug 31 2018, 10:31 Jenya7 Цитата(x893 @ Aug 31 2018, 15:31) Начните... Aug 31 2018, 10:33  x893 Цитата(Jenya7 @ Aug 31 2018, 13:33) скача... Aug 31 2018, 11:46   Jenya7 Цитата(x893 @ Aug 31 2018, 16:46) Тогда н... Aug 31 2018, 11:54    mcheb Цитата(Jenya7 @ Aug 31 2018, 15:54) мне и... Sep 1 2018, 04:05     Arlleex Цитата(mcheb @ Sep 1 2018, 08:05) Чтобы н... Sep 1 2018, 12:16 x893 Смысл простой - надо научиться самому искать ответ... Aug 31 2018, 12:19 Сергей Борщ QUOTE (Jenya7 @ Aug 31 2018, 13:17) Еще т... Aug 31 2018, 13:43 HardEgor Цитата(Jenya7 @ Sep 7 2018, 15:22) Delay_... Sep 7 2018, 09:10  Jenya7 Цитата(HardEgor @ Sep 7 2018, 15:10) Так ... Sep 7 2018, 09:22   HardEgor Цитата(Jenya7 @ Sep 7 2018, 16:22) Ставлю... Sep 7 2018, 09:30    Jenya7 Цитата(HardEgor @ Sep 7 2018, 15:30) На к... Sep 7 2018, 09:49     HardEgor Цитата(Jenya7 @ Sep 7 2018, 16:49) переда... Sep 7 2018, 13:14  jcxz Цитата(Сергей Борщ @ Sep 7 2018, 17:39) П... Sep 7 2018, 15:22   Arlleex Цитата(Jenya7 @ Sep 8 2018, 17:48) эта ст... Sep 8 2018, 16:31       Сергей Борщ QUOTE (Jenya7 @ Sep 9 2018, 10:21) У меня... Sep 9 2018, 08:20          Jenya7 Цитата(Arlleex @ Sep 9 2018, 18:27) А, не... Sep 9 2018, 12:49           Arlleex Цитата(Jenya7 @ Sep 9 2018, 15:49) USART_... Sep 9 2018, 12:57            Jenya7 Цитата(Arlleex @ Sep 9 2018, 18:57) Чему ... Sep 9 2018, 13:17 Сергей Борщ QUOTE (Jenya7 @ Sep 9 2018, 15:49) кстати... Sep 9 2018, 14:27
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|