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

 
 
> Прием по USART
Jenya7
сообщение Aug 31 2018, 10:17
Сообщение #1


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Jenya7
сообщение Sep 7 2018, 08:22
Сообщение #2


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 7 2018, 14:39
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 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
Jenya7
сообщение Sep 8 2018, 14:48
Сообщение #4


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

Группа: Участник
Сообщений: 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
Сергей Борщ
сообщение Sep 8 2018, 18:32
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #6


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

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


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #8


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

Группа: Участник
Сообщений: 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
Arlleex
сообщение Sep 9 2018, 09:59
Сообщение #9


Местный
***

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


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

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


Местный
***

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


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

 


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


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