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

 
 
 
Reply to this topicStart new topic
> как организовать передачу данных по USB из прерывания
NikP
сообщение Sep 18 2014, 13:01
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Есть устройство на STM32F207, которое периодически вводит данные с датчика (внешний АЦП) и передаёт во внешний ПК по виртуальному COM порту , фирмвара - на базе примера для STM322хG-EVAL. Когда передача идёт из главного модуля программы - всё работает, но передача происходит через разные интервалы времени - видно зависит от занятости шины USB.

Программа примерно такая:
CODE

app.c
{
....
int main(void)
{
while (1) {..DataIN_OUT_toUSB(...) }
}
....
}

usbd_cdc_vcp.c
{
....
DataIN_OUT_toUSB(...){...}
....
}



Чтобы опрос АЦП и передача шли через равные интервалы, я решил сделать прерывание от таймера ( с интервалом ~ 2 мс - времени должно с запасом хватить на преобразование ) и из него вызывать функцию передачи :

CODE

app.c
{
....
int main(void)
{
while (1) {}
}
....
}

usbd_cdc_vcp.c
{
....
DataIN_OUT_toUSB(...){...}
....

void TIM7_IRQHandler(void)
{
TIM7->SR &= ~TIM_SR_UIF; // reset interrupt flag

DataIN_OUT_toUSB(...)

TIM_Cmd(TIM7, ENABLE); // start TIM7
}
}


В результате передача по USB вообще прекратилась. По осциллографу вижу синхроимпульсы, т.е. прерывания происходят, по отладчику вижу, что программа заходит в функцию DataIN_OUT_toUSB. А вот передачи по шине просто нет. В чём может быть дело? Ведь таймер на время выполнения функции остановлен.






Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Sep 18 2014, 13:15
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Не понятно как в деталях все это сделано и насколько автор знает работу USB.
Дивайс сам по себе не может ничего инициировать, он может приготовить данные и высылать по запросу от хоста.
Если Вы без запроса от хоста пытаетесь послать, ничего не получится


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
NikP
сообщение Sep 18 2014, 17:43
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Согласен, что вопрос сформулирован достаточно косноязычно, но подробно расписывать (мне кажется) нет смысла - только место занимать.
Суть в следующем.
Написана фирмвара на основе примера STM. В программе есть функция DataIN_OUT_toUSB, которая опрашивает АЦП , пихает данные в массив на передачу по USB. Функция вызывается в модуле app.c ( обычно именуется main.с, но так сделано в примере - менять не стал), определена в модуле usbd_cdc_vcp.c. При этом всё работает - АЦП опрашивается, данные пихаются в буфер и идут наружу в ПК.
Изменил фирмвару - в модуле app.c оставил пустой цикл, а функцию стал вызывать из прерывания по таймеру из модуля usbd_cdc_vcp.c . Таймер сработал - вызвал функцию опроса АЦП, функция отработала, данные в буфере, снова запускается таймер. Всё прекрасно крутится - АЦП опрашивается, в буфер данные идут, а вот из буфера в USB не уходят. В чём может быть причина? Изменилось только то, что функция стала вызываться из другого места, сама она не изменилась.
Go to the top of the page
 
+Quote Post
WitFed
сообщение Sep 19 2014, 11:00
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 271
Регистрация: 6-12-11
Из: Taganrog
Пользователь №: 68 701



Очень вероятно, что прерывание от таймера имеет приоритет выше, чем от USB -- в ОС время очень важно.
Поэтому второе не происходит внутри первого, фунция DataIN_OUT_toUSB() ничего не видит и т.д...
Я бы лично в обработчике прерывания просто устанавливал флаг, в основном цикле его ждал и вызывал DataIN_OUT_toUSB().
Хотя если в последней есть просто поллинг запроса от хоста на заполнение ответной фифошки USB, то она (очень!) не всегда сможет попасть на него и вернуть нужные данные. Тогда живым будет только оригинальный непрерывный вариант.
USB -- вещь очень громоздкая, без изучения хотя бы основ и даташита на контроллер в этой части обычные понятия fread/fwrite будут работать редко. Возможно, если просто так данных напихать "впрок" в фифошку после их насчитывания, то они сотрутся прерыванием от USB при запросе хоста, именно в котором и должны быть напиханы only.
Я бы лично без отладчика эти вещи и не трогал -- там хоть можно поставить точку останова на любой стадии и пару операций ухватить замедленно в понимательный орган, потом всё порушится, начать сначала, переставить ТО чуть далее... Составить общую картину потом.
Go to the top of the page
 
+Quote Post
billidean
сообщение Sep 24 2014, 10:28
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 247
Регистрация: 4-10-10
Из: г. Екатеринбург
Пользователь №: 59 925



Так-то автор пишет, что
Цитата
АЦП опрашивается, в буфер данные идут
. Правда, он не сказал, как он это выяснил, методом медитации или отладчиком. То, что осциллографом видны тики таймера еще не говорит, что "АЦП опрашивается, в буфер данные идут".
Я не знаю наполнение функции DataIN_OUT_toUSB, но не может ли получиться так, что 2мс не хватает (или хватает, но впритык) для полного выполнения этой ф-ции, и МК почти все время висит в обработчике таймера?
Раньше все работало, потому что не было жесткой привязки к запуску этой ф-ции, т.е. когда закончила (может это занимало и более 2мс), тогда и опять начала выполняться, но при этом она могла быть прервана контроллером USB.
Go to the top of the page
 
+Quote Post
NikP
сообщение Sep 26 2014, 10:49
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Спасибо за замечание A. Fig Lee - до меня дошло, что мой подход идеологически неправильный, мою задачу надо решать по-другому.

Поэтому вопрос по теме представляет уже чисто спортивный интерес.
Значит что касается DataIN_OUT_toUSB :
CODE
void DataIN_OUT_toUSB (void)
{
...
Capture_and_convert(..)//опрос датчиков, преобразование и заполнение массива Data[i] данными с АЦП
...
VCP_DataTx ((uint8_t*)&Data, 4096);
...

}



После прошивки МК запускал программу под отладчиком ( оба варианта!!! - с вызовом DataIN_OUT_toUSB из модуля арр.с и из прерывания по таймеру) - отладчик показал, что в обоих вариантах программа заходит в VCP_DataTx, но в первом случае данные в шину передаются, во втором - нет . Контроль данных в шине USB проводил USB-монитором. Приоритет прерывания для таймера поставил самый низший (точнее - перебирал методом тыка от 5 до 85), интервал перезагрузки таймера отрабатывал разный - от 2 мс до 10 мс. Неужто за 10 мс USВ данные не передаст?


Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 22:58
Рейтинг@Mail.ru


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