AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
02.09.2012, 15:42
|
#1
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
AT89C5131 прием и передача данных по USB
Начал осваивать МК AT89C5131 и пытаюсь работать с USB , теперь у меня уже есть все книги П.В.Агурова (первая и вторая книга по USB и «Последовательные интерфейсы ПК») но все равно кое в чем не могу разобраться, да и код прикладных программ у Агурова на паскале написан, пришлось писать свой код под C++Builder 6.
Сейчас разбираюсь с USB HID устройством, немного изменив код для МК из книги П.В.Агурова пытаюсь принять данные на ПК, пока что просто при нажатии кнопки на устройстве пытаюсь отправить 1 а при отпущенной кнопке 0, в коде из книги, в МК функция записи данных в буфер конечной точки вызывается постоянно в бесконечном цикле, у меня она вызывается один раз при нажатии кнопки и отправляет 1 и когда отпускаем кнопку тоже вызывается и отправляет 0, но когда начинаю периодически нажимать-отпускать происходит какой то сбой в МК и он теряет связь с ПК, подскажите в чем причина и как нужно правильно организовать такой код для МК AT89C5131 ?
Вопрос 2.
Если хост является инициатором всех запросов по приему и передаче данных, получается что хост должен переключать конечные точки? И если мы переключили устройство на какую то конечную точку (не нулевую) то как долго можно находиться в этом состоянии, или все таки нужно периодически при работе с конечной точкой (не нулевой) в ходе работы опрашивать и нулевую?
Вопрос 3.
Как зафиксировать в коде МК в моем случае AT89C5131 факт того что произошел сбой связи с ПК по USB (не физическое отключение а просто сбой связи) и дать сигнал хотя бы светодиодом?
Код:
|
/* ================================================== = */
void main()
{
Set_x2_mode();
LEDCON = 0x0F;
P3_2 = 1;
P3_3 = 1;
/*P3_4 = 1;*/
P3_5 = 1;
usb_init();
usb_connected = FALSE;
while(1)
{
/*Fill_EP1_FIFO();*/
if(!usb_connected)
{
if(Usb_resume())
{
usb_connected = TRUE;
/* RESET SUSPEND */
Usb_clear_suspend_clock();
Usb_clear_suspend();
Usb_clear_resume();
Usb_clear_sof();
}
}
else
{
if(Usb_suspend())
{
usb_connected = FALSE;
Usb_clear_suspend();
Usb_set_suspend_clock();
}
if(Usb_reset())
{
Usb_clear_reset();
}
if(Usb_sof())
{
Usb_clear_sof();
}
/*------------------------------------*/
if(Usb_endpoint_interrupt())
{
Usb_select_ep(0);
if(Usb_setup_received())
{
usb_enumeration_process();
}
Usb_select_ep(1);
if(Usb_tx_complete())
{
Usb_clear_tx_complete();
P3_3 = ~P3_3;
end_point1_ready = FALSE;
}
}
/*------------------------------------*/
} /* end else */
/*--------------------------------------------------*/
if(P3_2 == 0 && LockOn1 == 1)/*Кнопка 1 нажата*/
{
P3_5 = 0;
point1_state = 0x01;
Fill_EP1_FIFO();
LockOff1 = 1;
LockOn1 = 0;
}
if(P3_2 == 1 && LockOff1 == 1)/*Кнопка 1 отпущена*/
{
P3_5 = 1;
point1_state = 0x00;
Fill_EP1_FIFO();
LockOn1 = 1;
LockOff1 = 0;
}
/*--------------------------------------------------*/
} /* end for */
} /* end main */
/* ================================================== = */
void Fill_EP1_FIFO()
{
if((usb_configuration_nb == 0) || (Usb_suspend()))
{
return;
}
if(!end_point1_ready) /* */
{
Usb_select_ep(1);
Usb_write_byte(point1_state);
Usb_write_byte(0x02);
Usb_write_byte(0x03);
Usb_write_byte(0x04);
Usb_write_byte(0x05);
Usb_write_byte(0x06);
Usb_write_byte(0x07);
Usb_set_tx_ready();
end_point1_ready = TRUE;
return;
}
}
/* ================================================== = */ |
Последний раз редактировалось rihkov; 02.09.2012 в 23:08.
|
|
|
|
06.09.2012, 00:23
|
#2
|
Гражданин KAZUS.RU
Регистрация: 24.11.2006
Адрес: ДНР
Сообщений: 612
Сказал спасибо: 553
Сказали Спасибо 314 раз(а) в 142 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Сообщение от rihkov
|
...немного изменив код для МК из книги П.В.Агурова
|
А до внесения изменений работало без сбоев?
Как отлаживаете устройство?
Не самый удачный камушек для изучения USB...
|
|
|
|
06.09.2012, 20:10
|
#3
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Еще раз перечитываю Агурова и похоже я понял в чем тут проблема, а проблема тут в том что HID драйвер постоянно читает данные из устройства даже если я их не принимаю функцией ReadFile, получается что нужно постоянно что то передавать, проверил HID джойстик, он постоянно передает данные если даже не нажимаешь кнопки.
__________________
Николай
|
|
|
|
06.09.2012, 20:22
|
#4
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,833
Сказал спасибо: 919
Сказали Спасибо 4,303 раз(а) в 2,572 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
rihkov, вы не правы. Можете не передавать, если не надо.
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
22.09.2012, 21:12
|
#5
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Я понял в чем проблема, нужно чтобы весь код из цикла обрабатывался по прерыванию 13 USB.
__________________
Николай
|
|
|
|
04.11.2012, 13:58
|
#6
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Подскажите пожалуйста когда запускать при инициализации в МК процесс нумерации, если после того когда МК получает от хоста пакет SETUP, то по какому событию (по какому флагу)?
Собрал следующий код который показан ниже, в начале запускается функция инициализации, потом по USB прерыванию 13 происходит обработка следующих флагов:
Код:
|
/*================================================= ====*/
void usb_int(void) interrupt 13
{
if(usb_connected == TRUE)/*ЕСЛИ УСТРОЙСТВО ПОДКЛЮЧЕНО К ШИНЕ*/
{
/*usb_endpoint();/**/
/*=============================*/
if(Usb_reset())/*ЕСЛИ ПОЛУЧЕН СИГНАЛ СБРОСА (ФЛАГ ПРЕРЫВАНИЯ ОКОНЧАНИЯ СБРОСА)*/
{
/*P3_5 = 0;/*ЛАМПА ЗЕЛЕНАЯ*/
Usb_clear_reset();/*СБРОС (ФЛАГ ПРЕРЫВАНИЯ ОКОНЧАНИЯ СБРОСА)*/
/*Usb_enable_suspend_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ ПРИОСТАНОВКИ)*/
/*Usb_enable_sof_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ НАЧАЛА КАДРА)*/
/*usb_connected = TRUE;/*УСТАНОВИТЬ ФЛАГ АКТИВНОСТИ USB ШИНЫ*/
}
/*=============================*/
if(Usb_sof())/*ФЛАГ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ НАЧАЛА КАДРА*/
{
P3_6 = 0;/*ЛАМПА ЖЕЛТАЯ*/
Usb_clear_sof();/*СБРОС (ФЛАГ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ НАЧАЛА КАДРА)*/
}
/*=============================*/
if(Usb_suspend())/*ЕСЛИ ПОЛУЧЕН СИГНАЛ "ЗАСЫПАНИЯ"*/
{
/*P3_3 = 0;/*ЛАМПА КРАСНАЯ*/
Usb_clear_suspend();/*СБРОС ФЛАГА ПРЕРЫВАНИЯ ПРИ ПРИОСТАНОВКЕ*/
/*Usb_set_suspend_clock();/*УСТАНОВКА (БИТ ПРИОСТАНОВКИ СИНХРОНИЗАЦИИ USB)*/
/*usb_connected = FALSE;/*СБРОСИТЬ ФЛАГ АКТИВНОСТИ USB ШИНЫ*/
}
/*=============================*/
}
else/*ЕСЛИ УСТРОЙСТВО ОТКЛЮЧЕНО ОТ ШИНЫ*/
{
if(Usb_resume())/*ЕСЛИ ПОЛУЧЕН СИГНАЛ ПОБУДКИ*/
{
usb_connected = TRUE;/*УСТАНОВИТЬ ФЛАГ АКТИВНОСТИ USB ШИНЫ*/
/*Usb_clear_suspend_clock();/*СБРОС (БИТ ПРИОСТАНОВКИ СИНХРОНИЗАЦИИ USB)*/
Usb_clear_suspend();/*СБРОС ФЛАГА ПРЕРЫВАНИЯ ПРИ ПРИОСТАНОВКЕ*/
Usb_clear_resume();
Usb_clear_sof();/*СБРОС (ФЛАГ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ НАЧАЛА КАДРА)*/
}
}
}
/* ================================================== = */ |
далее если я вызываю функцию, где происходит нумерация, в основном цикле программы, то тогда все нормально все флаги в этой функции выставляются и происходит нумерация, но если я эту функцию пытаюсь вызвать по прерыванию USB 13 то не выставляется даже флаг о наличии прерывания от нулевой конечной точки, и следовательно не вызывается функция нумерации, подскажите в чем тут проблема?
Код:
|
/*================================================= ==*/
void usb_endpoint()
{
/*=====================================*/
if(Usb_endpoint_interrupt0())/*ФЛАГ НАЛИЧИЯ ПРЕРЫВАНИЯ ОТ 0 КОНЕЧНОЙ ТОЧКИ*/
{
P3_3 = 0;/*ЛАМПА КРАСНАЯ*/
/*P3_5 = ~P3_5;/*ДЛЯ ОТЛАДКИ*/
Usb_clear_endpoint_interrupt0();/*СБРОС (ФЛАГ НАЛИЧИЯ ПРЕРЫВАНИЯ ОТ 0 КОНЕЧНОЙ ТОЧКИ)*/
Usb_select_ep(0);
if(Usb_setup_received())/*ФЛАГ ПРЕРЫВАНИЯ ПРИ ПОЛУЧЕНИИ ПАКЕТА SETUP*/
{
P3_5 = 0;/*ЛАМПА ЗЕЛЕНАЯ*/
usb_read_request();/*НАЧАТЬ ПРОЦЕСС НУМЕРАЦИИ*/
}
}
/*=====================================*/
if(Usb_endpoint_interrupt1())/*ФЛАГ НАЛИЧИЯ ПРЕРЫВАНИЯ ОТ 1 КОНЕЧНОЙ ТОЧКИ*/
{
Usb_clear_endpoint_interrupt1();/*СБРОС (ФЛАГ НАЛИЧИЯ ПРЕРЫВАНИЯ ОТ 1 КОНЕЧНОЙ ТОЧКИ)*/
Usb_select_ep(1);
if(Usb_tx_complete())/*ФЛАГ ПРЕРЫВАНИЯ ПО ОКАНЧАНИИ ПЕРЕДАЧИ ВХОДЯЩИХ ДАННЫХ*/
{
Usb_clear_tx_complete();/*СБРОС ФЛАГА*/
end_point1_ready = FALSE;/*ГОТОВНОСТЬ К ПЕРЕДАЧЕ ДАННЫХ*/
}
}
/*=====================================*/
}
/*================================================= ==*/ |
ФУНКЦИЯ ИНИЦИАЛИЗАЦИИ:
Код:
|
/* ================================================== = */
void usb_init()
{
usb_configuration_nb = 0x00;/**/
usb_connected = FALSE;/*СБРОСИТЬ ФЛАГ АКТИВНОСТИ USB ШИНЫ*/
end_point1_ready = FALSE;/*ФЛАГ РАЗРЕШИТЬ ЗАПИСЬ В ЕР1*/
Pll_set_div(PLL_24MHz);/*УСТАНОВИТЬ ЧАСТОТУ КВАРЦА*/
Pll_enable();/*ВКЛЮЧИТЬ ГЕНЕРАТОР*/
Usb_enable();/*ВКЛЮЧИТЬ МОДУЛЬ USB*/
/*=============================*/
/*Usb_clear_suspend_clock();/*СБРОС БИТА ПРИОСТАНОВКИ СИНХРОНИЗАЦИИ USB*/
/*Usb_clear_suspend();/*СБРОС ФЛАГА ПРЕРЫВАНИЯ ПРИ ПРИОСТАНОВКЕ*/
/*=============================*/
/*ОТКЛЮЧИТСЯ ОТ ШИНЫ И СНОВА ПОДКЛЮЧИТСЯ*/
Usb_detach();
delay5();
Usb_attach();
delay5();
/*РАЗРЕШАЕМ ОСНОВНЫЕ USB ПРЕРЫВАНИЯ*/
/*=============================*/
Usb_enable_suspend_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ ПРИОСТАНОВКИ В РЕГИСТРЕ USBIEN)*/
/*Usb_enable_resume_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПРИ ПРОБУЖДЕНИИ ЦП В РЕГИСТРЕ USBIEN)*/
Usb_enable_reset_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПО ОКАНЧАНИИ СБРОСА В РЕГИСТРЕ USBIEN)*/
Usb_enable_sof_interrupt();/*УСТАНОВКА (БИТ РАЗРЕШЕНИЯ ПРЕРЫВАНИЯ ПРИ ОБНАРУЖЕНИИ НАЧАЛА КАДРА В РЕГИСТРЕ USBIEN)*/
/*=============================*/
Enable_usb_interrupt();/*01000000 БИТ ВКЛЮЧЕНИЯ ПРЕРЫВАНИЯ USB В РЕГИСТРЕ IEN1*/
Enable_interrupt();/*10000000 БИТ ВКЛЮЧЕНИЯ ВСЕХ ПРЕРЫВАНИЙ В РЕГИСТРЕ IEN0*/
usb_configure_endpoint(0, CONTROL|MSK_EPEN);/**/
usb_reset_endpoint(0);/**/
Usb_enable_ep_int(0);/*РАЗРЕШЕНИЕ ПРЕРЫВАНИЯ ОТ КОНЕЧНОЙ ТОЧКИ*/
/*Usb_attach();/**/
/*Enable_interrupt();/*10000000 БИТ ВКЛЮЧЕНИЯ ВСЕХ ПРЕРЫВАНИЙ В РЕГИСТРЕ IEN0*/
usb_connected = TRUE;/*УСТАНОВИТЬ ФЛАГ АКТИВНОСТИ USB ШИНЫ*/
}
/* ================================================== = */ |
|
|
|
|
12.11.2012, 00:17
|
#7
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Уже надоело экспериментировать с этим HID, вот опять столкнулся с очередной проблемой, не получается передать данные от ХОСТА в УСТРОЙСТВО, проблема в написании дескриптора OUT РЕПОРТА, подскажите как написать входные и выходные дескрипторы репортов, нужно писать два отдельных дескриптора и потом при инициализации передавать их ХОСТУ сначала один (INPUT) потом второй (OUTPUT), или нужен один дескриптор репорта в котором описаны и (INPUT) данные и (OUTPUT) данные?
|
|
|
|
12.11.2012, 07:46
|
#8
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
можно и так и так. но для начала делайте один единый.
|
|
|
Эти 2 пользователя(ей) сказали Спасибо Hives за это сообщение:
|
|
|
12.11.2012, 08:44
|
#9
|
Временная регистрация
Регистрация: 29.03.2005
Сообщений: 86
Сказал спасибо: 6
Сказали Спасибо 45 раз(а) в 21 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Забудьте про Агурова, как про страшный сон. В ней ни полслова не говорится от том, что нужно использовать готовые библиотеки для работы с USB HID, как на стороне устройства USB (Ваш микроконтроллер), так и на стороне ПО хоста (программы для компьютера). Это книга только для затуманивания мозгов, от неё мало пользы. Гораздо лучше книжка " USB in the nutshell" [2], её можно найти и на русском языке.
Первое, что Вам нужно сделать, это взять пример USB HID с сайта Atmel для микроконтроллера AT89C5131 [1]. Тупо возьмите готовый код для микроконтроллера, скомпилируйте, прошейте. Убедитесь, что устройство USB HID работает. Далее возьмите готовый пример ПО хоста, работающее с этим USB HID, на том же сайте Atmel (оно сделано на основе DLL AtUsbHid.dll), скомпилируйте его, и попробуйте связаться с Вашим USB HID устройством. После того, как это все у Вас заработает, посмотрите, как работает код, почитайте апноуты, которые его описывают, и все Ваши вопросы отпадут сами собой. Далее можете приступать к модификации кода AT89C5131 и ПО хоста, чтобы они выполняли именно Ваши прикладные функции (передавали нажатия на кнопку и т. п.).
[ Ссылки]
1. AT89C5131 - апноуты.
2. USB in the nutshell.
Последний раз редактировалось microsin; 12.11.2012 в 08:48.
|
|
|
Эти 5 пользователя(ей) сказали Спасибо microsin за это сообщение:
|
|
|
13.11.2012, 00:59
|
#10
|
Прописка
Регистрация: 15.06.2006
Адрес: РФ г.Тюмень
Сообщений: 205
Сказал спасибо: 3
Сказали Спасибо 19 раз(а) в 19 сообщении(ях)
|
Re: AT89C5131 прием и передача данных по USB
Дело в том что уже все перепробовал и не как не могу послать данные на устройство, склоняюсь к тому что пишу не правильный дескриптор OUT РЕПОРТА, от устройства в ПК все передается нормально, все существующие примеры и все документации уже изучил, но ни где нет примера как передавать данные по отдельной конечной точке типа EP OUT INTERRUPT, хотя в спецификации написано что это доступно и работает начиная с Win2000 вроде.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 08:32.
|
|