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

10 мили - Delay_ms(10) - тоже работает нормально. меньше - ломается.

 

нет Delay_ms(10) - тоже ломается.

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

 

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


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

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

Он в первую очередь приём поломает.

Самое удивительное, что такие горе-пейсатели как будто друг у друга быдлокод передирают. Только что в соседней теме по аналогичному случаю советовал автору подумать, что будет если между чтением регистра приёма UART и последующим принудительным сбросом флага успеет придти символ.

Казалось бы очевидная ситуация - как можно не видеть такого??? :wacko:

Зато "баги" IAR-а находят чуть не каждый день. :biggrin:

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


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

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

 

эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.

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


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

эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.

Очень хреновый подход - тыкать в якобы "черный ящик" разными способами и смотреть, что изменится. Особенно в случае, когда достаточно один раз прочитать документацию. Которая еще и открыта. Которой еще и навалом на русском и ардуиноязыке в интернетах. Нет же, мы полезем сразу на форум и начнем строчить :smile3046:

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


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

эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.
То есть читать документацию вы не хотите принципиально. Тогда я пас.

 

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


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

То есть читать документацию вы не хотите принципиально. Тогда я пас.

 

я не нашел в документации ответа на проблему. если знаете укажите.

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


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

если знаете укажите.
Указывал уже. Толку-то?

Чудес не бывает. Либо у вас остался взведенным флаг этого события, либо разрешено прерывание по какому-то еще. Чтобы это узнать, достаточно прочитать регистры настройки и описание их содержимого. Попав в прервание сначала читаем SR, чтобы узнать, какие из флагов выставлены и какие биты отвечают за разрешение прерывания по этим флагам. Потом читаем регистры с этими битами разрешения и выясняем, какое именно событие могло вызвать переход в обработчик прерывания.

 

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


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

Указывал уже. Толку-то?

 

У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его.

Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу.

Вы можете и дальше умничать и говорить тривиальные вещи. Главное чтоб Вам от этого было хорошо. Я для этого открываю темы. Чтоб люди заходили и объясняли мне какое я гавно и какие они умные. А то я ж до сих пор это не понял.

Изменено пользователем Jenya7

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


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

У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его.
Еще раз повторяю: чудес не бывает. RXNEIE разрешает прерывание не только по RXNE. Читайте документацию внимательно.

Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу.
Какие еще флаги взведены? Вам самому не стало интересно, что же такого магического вы сбрасываете той сторокой, если RNXE уже был сброшен.

 

 

Я для этого открываю темы.
А люди пытаются научить вас учиться и думать самостоятельно. Ибо на каждый вопрос тему не откроешь, а почти на каждый ваш вопрос ответ в документации есть.

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


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

У меня разрешено только одно прерывание 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 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце.

Устали Вы меня...

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


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

4 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце.

Устали Вы меня...

а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному?

 

я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error).

вопрос как с этим бороться.

 

если посылать пинг-понг ORE и FE не взводяться. хотя NF иногда проскакивает.

Изменено пользователем Jenya7

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


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

а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному?

А, не туда посмотрел.

Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не

USART_SendBuf(USART2, "MBE\r");

 

я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error).

вопрос как с этим бороться.

Вам об этом еще выше писали. А Вы все "да у меня только одно прерывание срабатывает"...

Я Вас не зря попросил регистр статуса целиком в переменную загнать и под отладчиком глянуть.

Процессор на какой частоте работает и на какой скорости UART обмен ведет?

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


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

А, не туда посмотрел.

Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не

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

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


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

USART_TIMEOUT

Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху?

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


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

Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху?

 

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

 

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

Изменено пользователем Jenya7

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


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

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

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

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

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

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

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

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

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

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