Сергей Борщ 119 7 сентября, 2018 Опубликовано 7 сентября, 2018 · Жалоба 10 мили - Delay_ms(10) - тоже работает нормально. меньше - ломается. нет Delay_ms(10) - тоже ломается. Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 сентября, 2018 Опубликовано 7 сентября, 2018 · Жалоба Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает. Он в первую очередь приём поломает. Самое удивительное, что такие горе-пейсатели как будто друг у друга быдлокод передирают. Только что в соседней теме по аналогичному случаю советовал автору подумать, что будет если между чтением регистра приёма UART и последующим принудительным сбросом флага успеет придти символ. Казалось бы очевидная ситуация - как можно не видеть такого??? :wacko: Зато "баги" IAR-а находят чуть не каждый день. :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 8 сентября, 2018 Опубликовано 8 сентября, 2018 · Жалоба Помедитируйте над строчкой "USART2->ICR = (uint16_t)~USART_FLAG_RXNE;" Если вы хотите сбросить флпг приема, то, во-первых не нужен "~", а во-вторых этот флаг уже сбросился, когда вы читали RDR. Если же вы хотели сбросить все остальные флаги - то как-то то странно делать это без проверки, да и передачу такой сброс наверняка поломает. эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 8 сентября, 2018 Опубликовано 8 сентября, 2018 · Жалоба эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел. Очень хреновый подход - тыкать в якобы "черный ящик" разными способами и смотреть, что изменится. Особенно в случае, когда достаточно один раз прочитать документацию. Которая еще и открыта. Которой еще и навалом на русском и ардуиноязыке в интернетах. Нет же, мы полезем сразу на форум и начнем строчить :smile3046: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 8 сентября, 2018 Опубликовано 8 сентября, 2018 · Жалоба эта строчка появилась после многих часов отладки. без нее я все время захожу в прерывание. даже если новый чар не пришел.То есть читать документацию вы не хотите принципиально. Тогда я пас. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба То есть читать документацию вы не хотите принципиально. Тогда я пас. я не нашел в документации ответа на проблему. если знаете укажите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба если знаете укажите.Указывал уже. Толку-то? Чудес не бывает. Либо у вас остался взведенным флаг этого события, либо разрешено прерывание по какому-то еще. Чтобы это узнать, достаточно прочитать регистры настройки и описание их содержимого. Попав в прервание сначала читаем SR, чтобы узнать, какие из флагов выставлены и какие биты отвечают за разрешение прерывания по этим флагам. Потом читаем регистры с этими битами разрешения и выясняем, какое именно событие могло вызвать переход в обработчик прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 9 сентября, 2018 Опубликовано 9 сентября, 2018 (изменено) · Жалоба Указывал уже. Толку-то? У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его. Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу. Вы можете и дальше умничать и говорить тривиальные вещи. Главное чтоб Вам от этого было хорошо. Я для этого открываю темы. Чтоб люди заходили и объясняли мне какое я гавно и какие они умные. А то я ж до сих пор это не понял. Изменено 9 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба У меня разрешено только одно прерывание RXNEIE = 1 - только оно. И в регистрах при отладке я вижу только его.Еще раз повторяю: чудес не бывает. RXNEIE разрешает прерывание не только по RXNE. Читайте документацию внимательно. Флаг RXNE при чтении регистра USART2->RDR очищается. В регистрах при отладке я это вижу.Какие еще флаги взведены? Вам самому не стало интересно, что же такого магического вы сбрасываете той сторокой, если RNXE уже был сброшен. Я для этого открываю темы.А люди пытаются научить вас учиться и думать самостоятельно. Ибо на каждый вопрос тему не откроешь, а почти на каждый ваш вопрос ответ в документации есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба У меня разрешено только одно прерывание 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 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце. Устали Вы меня... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 9 сентября, 2018 Опубликовано 9 сентября, 2018 (изменено) · Жалоба 4 - это количество символов? Ну если это так - то, во-первых, понятно, почему принимается всегда по-разному, а во-вторых, такой код никуда не годится - Вам, как пользователю этой функции нафиг знать не нужно, сколько символов в ней. Она должна отправить строку. А строка в Си уже имеет искусственный ограничитель в конце. Устали Вы меня... а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному? я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error). вопрос как с этим бороться. если посылать пинг-понг ORE и FE не взводяться. хотя NF иногда проскакивает. Изменено 9 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба а что плохого в USART_SendBuf(USART2, "MBE\r", 4)? я посылаю 4 символа и почему они должны приниматься по разному? А, не туда посмотрел. Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не USART_SendBuf(USART2, "MBE\r"); я посмотрел регистры поглубже и выявил проблему. при быстрой посылке взводится флаг ORE (overrun error), NF (noise flag) и иногда FE (framing error). вопрос как с этим бороться. Вам об этом еще выше писали. А Вы все "да у меня только одно прерывание срабатывает"... Я Вас не зря попросил регистр статуса целиком в переменную загнать и под отладчиком глянуть. Процессор на какой частоте работает и на какой скорости UART обмен ведет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 9 сентября, 2018 Опубликовано 9 сентября, 2018 (изменено) · Жалоба А, не туда посмотрел. Работать будет, но все равно не ясен смысл еще одного аргумента (количества передаваемых символов). Почему не 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 генерируется прерывание. Изменено 9 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 9 сентября, 2018 Опубликовано 9 сентября, 2018 · Жалоба USART_TIMEOUT Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 9 сентября, 2018 Опубликовано 9 сентября, 2018 (изменено) · Жалоба Чему равен? Есть уверенность, что отправляющий UART не напихивает в регистр без продыху? USART_TIMEOUT = 100000. я стал точкой останова на timeout-- максимум 10 - 20 итераций происходит. убрал { if(!timeout--) break; } вроде нормально флаг отрабатывает. символ ушел флаг взвелся. Изменено 9 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться