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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Прием по USART
Сергей Борщ
сообщение Sep 7 2018, 14:39
Сообщение #16


Гуру
******

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



QUOTE (Jenya7 @ Sep 7 2018, 11:22) *
10 мили - Delay_ms(10) - тоже работает нормально. меньше - ломается.

нет Delay_ms(10) - тоже ломается.
Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает.


--------------------
На любой вопрос даю любой ответ
"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
jcxz
сообщение Sep 7 2018, 15:22
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Sep 7 2018, 17:39) *
Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает.

Он в первую очередь приём поломает.
Самое удивительное, что такие горе-пейсатели как будто друг у друга быдлокод передирают. Только что в соседней теме по аналогичному случаю советовал автору подумать, что будет если между чтением регистра приёма UART и последующим принудительным сбросом флага успеет придти символ.
Казалось бы очевидная ситуация - как можно не видеть такого??? wacko.gif
Зато "баги" IAR-а находят чуть не каждый день. biggrin.gif
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 8 2018, 14:48
Сообщение #18


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Sep 7 2018, 20:39) *
Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает.


эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 8 2018, 16:31
Сообщение #19


Местный
***

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



Цитата(Jenya7 @ Sep 8 2018, 17:48) *
эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.

Очень хреновый подход - тыкать в якобы "черный ящик" разными способами и смотреть, что изменится. Особенно в случае, когда достаточно один раз прочитать документацию. Которая еще и открыта. Которой еще и навалом на русском и ардуиноязыке в интернетах. Нет же, мы полезем сразу на форум и начнем строчить smile3046.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 8 2018, 18:32
Сообщение #20


Гуру
******

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



QUOTE (Jenya7 @ Sep 8 2018, 17:48) *
эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.
То есть читать документацию вы не хотите принципиально. Тогда я пас.


--------------------
На любой вопрос даю любой ответ
"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
Jenya7
сообщение Sep 9 2018, 05:04
Сообщение #21


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Sep 9 2018, 00:32) *
То есть читать документацию вы не хотите принципиально. Тогда я пас.


я не нашел в документации ответа на проблему. если знаете укажите.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 9 2018, 06:15
Сообщение #22


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 9 2018, 07:21
Сообщение #23


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Sep 9 2018, 12:15) *
Указывал уже. Толку-то?


У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его.
Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу.
Вы можете и дальше умничать и говорить тривиальные вещи. Главное чтоб Вам от этого было хорошо. Я для этого открываю темы. Чтоб люди заходили и объясняли мне какое я гавно и какие они умные. А то я ж до сих пор это не понял.

Сообщение отредактировал Jenya7 - Sep 9 2018, 07:42
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 9 2018, 08:20
Сообщение #24


Гуру
******

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



QUOTE (Jenya7 @ Sep 9 2018, 10:21) *
У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его.
Еще раз повторяю: чудес не бывает. RXNEIE разрешает прерывание не только по RXNE. Читайте документацию внимательно.
QUOTE (Jenya7 @ Sep 9 2018, 10:21) *
Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу.
Какие еще флаги взведены? Вам самому не стало интересно, что же такого магического вы сбрасываете той сторокой, если RNXE уже был сброшен.


QUOTE (Jenya7 @ Sep 9 2018, 10:21) *
Я для этого открываю темы.
А люди пытаются научить вас учиться и думать самостоятельно. Ибо на каждый вопрос тему не откроешь, а почти на каждый ваш вопрос ответ в документации есть.


--------------------
На любой вопрос даю любой ответ
"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
Arlleex
сообщение Sep 9 2018, 09:59
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 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). Как видно, оно отличается от значения в прошлых пунктах.

Выводы:
  1. Нельзя пользоваться бездумно отладчиком при работе с чувствительной к чтению регистровой моделью периферии.
  2. 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 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце.
Устали Вы меня...
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 9 2018, 10:08
Сообщение #26


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 9 2018, 12:27
Сообщение #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 обмен ведет?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 9 2018, 12:49
Сообщение #28


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Arlleex @ Sep 9 2018, 18:27) *
А, не туда посмотрел.
Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не
Код
USART_SendBuf(USART2, "MBE\r");



Вам об этом еще выше писали. А Вы все "да у меня только одно прерывание срабатывает"...
Я Вас не зря попросил регистр статуса целиком в переменную загнать и под отладчиком глянуть.
Процессор на какой частоте работает и на какой скорости UART обмен ведет?

у меня есть посылка строки
Код
void USART_SendString(USART_TypeDef *USARTx, const char *string)
{
  while(*string)
  {
    uint32_t timeout = USART_TIMEOUT;
    // wait until data register is empty
    while( !(USARTx->ISR & USART_FLAG_TC) ) {  if(!timeout--) break; }
    USARTx->TDR = *string++; //
  }
}

это я для отладки строку посылаю. но реально я буду посылать не ASCII символы а uint8_t.

частота кора 72 Мега. скорость UART 115200.

кстати мне не понятно почему по флагам ORE и FE генерируется прерывание.

Сообщение отредактировал Jenya7 - Sep 9 2018, 12:55
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 9 2018, 12:57
Сообщение #29


Местный
***

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



Цитата(Jenya7 @ Sep 9 2018, 15:49) *
USART_TIMEOUT

Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 9 2018, 13:17
Сообщение #30


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Arlleex @ Sep 9 2018, 18:57) *
Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху?


USART_TIMEOUT = 100000. я стал точкой останова на timeout-- максимум 10 - 20 итераций происходит.

убрал { if(!timeout--) break; } вроде нормально флаг отрабатывает. символ ушел флаг взвелся.

Сообщение отредактировал Jenya7 - Sep 9 2018, 13:34
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th April 2024 - 03:53
Рейтинг@Mail.ru


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