|
Прием по 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
|
|
|
|
|
Aug 31 2018, 10:33
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(x893 @ Aug 31 2018, 15:31) Начните с примеров. скачал примеры для F3Discovery - для USART примеров нет. Нашел пример для моего камня Код void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // data receive { USART_ClearITPendingBit(USART1, USART_IT_RXNE); rx = (unsigned char) USART_ReceiveData(USART1); rxbuff[e] = rx; e++; } сделал то же самое только для USART2 - та же беда.
Сообщение отредактировал Jenya7 - Aug 31 2018, 11:33
|
|
|
|
|
Aug 31 2018, 13:43
|
Гуру
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095
|
QUOTE (Jenya7 @ Aug 31 2018, 13:17) Еще такая проблема - я все время захожу в USART2_IRQHandler - даже когда размыкаю провод RX - хотя у меня включено только одно прерывание - по принятию - Чудес не бывает. Либо у вас остался взведенным флаг этого события, либо разрешено прерывание по какому-то еще. Чтобы это узнать, достаточно прочитать регистры настройки и описание их содержимого. Попав в прервание сначала читаем SR, чтобы узнать, какие из флагов выставлены и какие биты отвечают за разрешение прерывания по этим флагам. Потом читаем регистры с этими битами разрешения и выясняем, какое именно событие могло вызвать переход в обработчик прерывания. Потом лезем в исходники "библиотеки" и выясняем, кто и зачем прерывания по этому событию разрешил. Неужели так сложно до этого додуматься самому? И да, без чтения документации у вас ничего не получится даже с самыми лучшими библиотеками, не говоря уже о "библиотеках".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 1 2018, 04:05
|
Местный
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602
|
Цитата(Jenya7 @ Aug 31 2018, 15:54) мне интересно какая цель ваших ответов? чтоб количество сообщений было больше? за это что то дают? медаль какую? Чтобы не было лишних вопросов Код void USART2_IRQHandler(void) { if(USART2->ISR & USART_ISR_RXNE) // Данные пришли? { IN_FIFO.buf[IN_FIFO.Put++ % DATABUFSIZE]=USART2->RDR; // кладём в буфер } } // void uart2_putc(unsigned char ch) { USART2->TDR=ch; while(!(USART2->ISR & USART_ISR_TC)); } //
|
|
|
|
|
Sep 1 2018, 12:16
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Цитата(mcheb @ Sep 1 2018, 08:05) Чтобы не было лишних вопросов... Это зря Вы так думаете, что их не будет И, кстати, Ваш пример не совсем корректен. Если данных будет слишком много, Вы будете их постоянно принимать, т.к. никакого события переполнения входного буфера, видимо, не предусмотрено. Но как пример, вполне себе...
Сообщение отредактировал Arlleex - Sep 1 2018, 12:16
|
|
|
|
|
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 7 2018, 09:22
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(HardEgor @ Sep 7 2018, 15:10) Так может у вас мастер(USART_SendBuf) сливает символы? - На последние биты последнего символа накладываются биты следующего символа. Хотя вроде "\r" нормально принимается.... или теряется вся предыдущая строка? А у вас случайно не RS485 полудуплекс? Я для отладки подключил напрямую пины MASTER_USART2_TX - SLAVE_USART2_RX MASTER_USART2_RX - SLAVE_USART2_TX Ставлю точку останова на стороне мастера - вижу четко уходит строка - никаких накладок. а если ставлю точку останова со стороны слейва, на строке usart2_rx_ready = 1; то вижу накладки. поставил скоп на MASTER_USART2_TX - выходящий пакет довольно красивый.
Сообщение отредактировал Jenya7 - Sep 7 2018, 09:32
|
|
|
|
|
Sep 7 2018, 09:49
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(HardEgor @ Sep 7 2018, 15:30) На какое событие в передатчике вы ставите точку останова? Transmit data register empty или Transmission complete? передатчик работает по Transmission complete Код void USART_SendBuf(USART_TypeDef *USARTx, uint8_t *data, uint32_t size) { while (size--) { uint32_t timeout = USART_TIMEOUT; // wait until data register is empty while( !(USARTx->ISR & USART_FLAG_TC) ) {if(!timeout--) break; } USARTx->TDR = *data++; } }
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|