|
Теряются данные при считывании по UART, STM32F103RD |
|
|
|
Oct 23 2015, 10:37
|
Местный
  
Группа: Свой
Сообщений: 237
Регистрация: 14-08-07
Из: Москва
Пользователь №: 29 791

|
Цитата(Atlantis- @ Oct 23 2015, 13:02)  ... с частотой 500 Гц я опрашиваю датчики. ... Каждую 1 мс по UART присылаю команду "передать данные"... "С частотой 500 Гц" - это каждые 2 мс... Где наврали? И очень подозрительно реализован опрос: может, после посылки команды "передать данные" надо дожидаться ответа на неё, а не посылать следующую команду? В приёмнике ведь наверняка есть приёмный буфер?
|
|
|
|
|
Oct 23 2015, 11:32
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(=GM= @ Oct 23 2015, 13:17)  Вообще-то, уарт предназначен для работы один-на-один. Поподробнее расскажите, как вы переключаете датчики, какая скорость передачи етц... переключаю микросхемой 74HC126D, скорость 350 000 бит/с но какая разница? в варианте, когда я считывал данные по USB ничего не терялось, иначе на ПК все бы полетело.
|
|
|
|
|
Oct 23 2015, 11:52
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(r_dot @ Oct 23 2015, 13:37)  "С частотой 500 Гц" - это каждые 2 мс... Где наврали?
И очень подозрительно реализован опрос: может, после посылки команды "передать данные" надо дожидаться ответа на неё, а не посылать следующую команду? В приёмнике ведь наверняка есть приёмный буфер? там устроено так:посылается первый запрос данных, запускается таймер, после приема данных линии UART переключаются на второй датчик, через 1 мс срабатывает прерывание таймера - считываем данные от второго датчика, переключаем UART на первый датчик, через 2 мс (от старта) считываем данные с первого датчика и т.д. То есть датчик опрашивается каждые 2 мс. Далее, чтобы отправить то что пришло с датчиков по RS-485, я опрашиваю МК каждые 1 мс, есть ли данные Цитата(uriy @ Oct 23 2015, 14:47)  А вы уверены что микросхему 74HC126D переключаете когда передача данных уже завершена? переключение происходит в прерывании от DMA - то есть при условии, когда нужное кол-во данных пришло
|
|
|
|
|
Oct 24 2015, 13:34
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Сделал на стороне STM32 постоянный массив, который считываю каждые 1 мс - все равно через некоторое время байт пропадает. Получается ошибка происходит в момент передачи по USB. Посмотрел - там какие то диковинные процессы происходят. У меня там два массива и бит, который их переключает. Алгоритм такой: каждые 1 мс инвертирую этот бит и посылаю запрос данных. если бит =1, то из UART данные приходят в массив 1, а в USB передаются данные из массива 2, если бит =0, то наоборот. По UART всегда передается 19 байт за 1 мс. Я поставил точку остановки в момент передачи по USB - в обоих массивах как то оказалось больше 19 байт. Не понимаю, как это вообще возможно. Вроде бы все просто: пока один буфер заполняется, другой вычитывается, потом наоборот, как они могут переполниться?
|
|
|
|
|
Oct 26 2015, 10:14
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Atlantis- @ Oct 24 2015, 13:34)  По UART всегда передается 19 байт за 1 мс 1000/19/10 = 5.26 мкс,что соответствует 190 кбит/с. Это что ж у вас за скорость такая нестандартная? Цитата(Atlantis- @ Oct 24 2015, 13:34)  пока один буфер заполняется, другой вычитывается, потом наоборот, как они могут переполниться? Что ж, пора взглянуть на вашу программу. Интересно, как вы буфера переполняете.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 26 2015, 20:07
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(=GM= @ Oct 26 2015, 13:14)  1000/19/10 = 5.26 мкс,что соответствует 190 кбит/с. Это что ж у вас за скорость такая нестандартная?
Что ж, пора взглянуть на вашу программу. Интересно, как вы буфера переполняете. скорость 1 Мбит/с, а что какие то проблемы с нестандартными скоростями? программа осталась на работе, но напишу все, что вспомню, там несложно итак, у меня есть два буфера, два индекса элементов и бит - переключатель буферов Код BYTE Buff0[76]; BYTE Buff1[76]; BYTE InPtr0 =0; BYTE InPtr1 =0; bit ToggleBuff =0; переключение буферов происходит в прерывании USB Start of Frame при условии, что передача данных запущена. Что-то типа такого Код void USB_Isr {
if (пришел Start of Frame) { if(transmit !=0)//бит, устанавливается командой USB {
ToggleBuff = ~ToggleBuff; SBUF =0x38;//посылаем запрос данных по UART }
}
if(Endpoint свободна) { DataOut =1;//разрешили передачу данных }
} в main опрашиваю флаги, передаю данные Код if ((transmit ==1) && (DataOut ==1)) { DataOut =0;
if (ToggleBuff) { //передаю данные из Buff0, сбрасываю InPtr0 =0 } else { //передаю данные из Buff1, сбрасываю InPtr1 =0 }
} в прерывании UART пишу в буфер, в зависимости от флага Код void UART_Isr { //сбрасываю флаг прерывания if (ToggleBuff) { //пишу данные в Buff1, инкрементирую InPtr1++ } else { //пишу данные в Buff0, инкрементирую InPtr0++ }
}
}
|
|
|
|
|
Oct 27 2015, 10:56
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(esaulenka @ Oct 27 2015, 12:06)  Первый признак любимых граблей эмбеддера: слово "прерывание" есть, а слова "волатайл" - нету. тогда бы сбои были систематическими, а у меня они в разное время происходят, порой после 20-30 секунд, а это уже тысячи переданных пакетов. Походу я ошибся в определении источника ошибок...установил в одном из буферов приемника условие, что принято меньше 19 байт и точку остановки там - в процессе передачи улетел в эту точку, посмотрел приемный буфер - не хватает второго байта. Значит дело все таки в STM32. Но там вообще мистика, я не понимаю как так может быть. Вот мой обработчик прерываний UART CODE void UART5_IRQHandler(void) { uint8_t Data; uint16_t Length; if ((UART5->SR & USART_SR_TC) != 0) { UART5->SR &= ~USART_SR_TC;//очистить флаг окончания передачи по UART
if(OUT_buf < IN_buf) { USART_SendData(UART5, BuffUART[OUT_buf]); OUT_buf++; }
} else if ((UART5->SR & USART_SR_RXNE) != 0) {
switch (USART_ReceiveData(UART5)) {
case 0x38: //передать данные
if (Transfer != 0) {
BuffUART[0] = 19; BuffUART[1] = 16; BuffUART[2] = 1; BuffUART[3] = 0x55; BuffUART[4] = 0xCC; BuffUART[5] = 0; BuffUART[6] = counter1; BuffUART[7] = 0; BuffUART[8] = counter1; BuffUART[9] = 0; BuffUART[10] = counter1; counter1++; BuffUART[11] = 0; BuffUART[12] = counter1; BuffUART[13] = 0; BuffUART[14] = counter1; BuffUART[15] = 0; BuffUART[16] = counter1; BuffUART[17] = 0x0D; BuffUART[18] = 0xAA;
if (ToggleFlag ==1) { BuffUART[2] = 1; ToggleFlag =0; } else { BuffUART[2] = 1;//если тут 2, то происходят сбои! если 1, то сбоев нет ToggleFlag++; } OUT_buf=0; IN_buf = 19; USART_SendData(UART5, BuffUART[OUT_buf]); OUT_buf++; } break; } UART5->SR &= ~USART_SR_RXNE;//очистить флаг приема данных по UART
} }
изменение значения BuffUART[2] почему то приводит к сбоям
|
|
|
|
|
Oct 27 2015, 13:28
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(esaulenka @ Oct 27 2015, 15:28)  Ничего не понял. Данные из датчиков попадают в два разных массива, переключение между массивами - по команде с ПК. Два этих процесса не синхронизированы. Так почему же оно почти всегда работает? :-)
Кто такой BuffUART[2] вообще неясно. Если он нигде не анализируется, на выполнение программы влиять он не должен никак. Даа не так. Данные приходят с датчиков на STM32, он по UART передает на C8051F320, а тот передает по USB. Чтобы вычленить проблему, я данные с датчиков вообще не трогаю. А по запросу от C8051F320 передаю ему фиксированный массив из 19 байт. И если меняю значение BuffUART[2], то получаю сбои. Цитата(esaulenka @ Oct 27 2015, 15:28)  Если он нигде не анализируется, на выполнение программы влиять он не должен никак. вот именно!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|