#include // Заголовочный файл для микроконтроллера
#include // для прерывания по таймеру
#include // для _delay_ms()
#include // требуется для usbdrv.h
#include "usbdrv.h" // загружает параметры и библиотеки v-usb
//описание пакета данных для обмена между устройством и компьютером.
PROGMEM char usbHidReportDescriptor[22] = {
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x00, // USAGE (Undefined)
0xB2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};
//Таймер включающий заново светодиод VD3
ISR(TIMER0_OVF_vect) {PORTC=0x01;}
//Функция вызываемая при запросе данных компьютером.
uchar usbFunctionRead(uchar *data, uchar len) {
while (ADCSRA==0xC3){}; // Ждем пока оцифровка завершиться
data[0] = ADCL; // копируем младший байт регистра оцифровки в пакет ответа
data[1] = ADCH; // копируем старший байт регистра оцифровки в пакет ответа
return len; // возвращаем длину пакета ответа
}
//функция вызываемая при получении устройством данных
uchar usbFunctionWrite(uchar *data, uchar len) {
ADMUX =data[0]; //устанавливаем канал для оцифровки
return 1; //сообщаем вызвавшей процедуре об успехе операции
}
uchar usbFunctionSetup(uchar data[8]) {
usbRequest_t *rq = (void *) data;
//определяем класс пришедшего запроса
if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
if (rq->bRequest == USBRQ_HID_GET_REPORT) { //Если компьютер запросил данные
PORTC=0x00; // выключаем светодиод
ADCSRA=0xC3; // Запускаем оцифровку
return USB_NO_MSG; // вызываем usbFunctionRead()
} else if (rq->bRequest == USBRQ_HID_SET_REPORT) { //Если компьютер прислал данные
PORTC=0x00; // выключаем светодиод
return USB_NO_MSG; // вызываем usbFunctionWrite()
}
return 0;
} return 0;
}
int main(void) {
// Инициализируем таймер для мигания светодиодом
TCCR0=0x05; // делитель таймера – 1024, 12МГц/1024=11718,75... ~12КГц
TCNT0=0x00; // Начальное значение - 0
TIMSK=0x01; // Таймер срабатывает по достижению 256: 12КГц/256~46Гц
TIFR=0; // Сбрасываем все флаги прерываний
ADCSRA=0x83; // Инициализируем АЦП
DDRC=0xFF; // Порт С – на вывод
PORTC=0x01; // Включаем светодиод
usbInit(); // запускаем инициализацию usb
usbDeviceDisconnect() // отключаем устройство
delay_ms(250); // ждем 250мс
usbDeviceConnect(); // подключаем устройство
sei(); //Разрешаем прерывания
for(;;){usbPoll();} //бесконечный цикл с функцией проверки пришедших данных
return 0;
}
|