Уважаемый Пётр использовал библиотеку программного обеспечения USB господина Ollopa. Господин Ollopa был так добр, что опубликовал версию LBX своей библиотеки. Хотя библиотека и работает, она не протестирована на все 100% и пока не поддерживается. Со временем появится коммерческая версия (LIB), которая будет поддерживаться. Эта библиотека программного обеспечения USB и образцы кода, можно использовать в USB устройствах для большинства AVR чипов -
Спасибо Петр, за этот замечательный материал!
Программная реализация USB в AVR.
USB драйвер (файл swusb.LBX ) нужно скопировать в папку LIB программы BASCOM-AVR. Пример HID джойстика был переделан в демонстрационное устройство и USB термометр.
Demo - device.
Демонстрационное устройство, позволяет производить двухсторонний обмен произвольной информацией с компьютером. Его схема показана на рисунке.
Программа имеет довольно большой размер (почти 1000 строк), поэтому будут рассмотрены лишь фрагменты, отвечающие за конфигурацию USB драйвера и обмен информацией. В оригинальной программе был заменён HID дескриптор устройства, типа джойстик, на HID дескриптор нестандартного устройства, позволяющий производить обмен произвольной информацией. Также была активирована вторая конечная точка и настроена на приём информации от компьютера. Именно HID дескриптор определяет тип устройства. От него зависит, будет ли устройство, клавиатурой, мышкой, джойстиком и т. д. В рассматриваемом демонстрационном устройстве, HID дескриптор имеет вид:
Data 33 ' Length = 33 bytes
Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1)
Data &H09 , &H01 ' Usage(vendor Usage 1)
Data &HA1 , &H02 ' Collection(logical)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H25 , &HFF ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H81 , &H02 ' Input(data , Var , Abs)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H26 , &HFF , 0 ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H91 , &H02 ' Output(data , Var , Abs)
Data &HC0 ' End_collection
В первой строке, указанно число байт дескриптора. Вторая и третья строка, описывает тип устройства. В нашем случае, это нестандартное HID устройство. Далее следует описание входной и выходной конечных точек. Параметры Logical_minimum и Logical_maximum определяют допустимый интервал значений, хранящийся в буфере конечной точки. Параметр Report_count определяет число байт, передаваемых или принимаемых за одну посылку. Допустимое значение 1…8. В демонстрационном устройстве, передаётся и принимается, только по один байт за посылку.
Конфигурация конечных точек производится с помощью этого кода.
' Address of optional endpoints (Must be > 0. comment-out to not use)
Const _usb_endp2addr = 1
Const _usb_endp3addr = 2
' Valid types are 0 for control or 3 for interrupt
Const _usb_endp2type = 3
Const _usb_endp3type = 3
' Directions are: 0=Out, 1=In. Ignored by control endpoints
Const _usb_endp2direction = 1
Const _usb_endp3direction = 0
' Polling interval (ms) for interrupt endpoints. Ignored by control endpoints
' (Must be at least 10)
Const _usb_endp2interval = 200
Const _usb_endp3interval = 100
Уникальные идентификаторы устройства - Vendor ID and Product ID, задают в строках:
Const _usb_vid = &HAAAA
Const _usb_pid = &HEF22
Приём и передача данных, выполняются в главном цикле программы.
Do
Resetcounter = 0
' Check for reset here
While _usb_pin._usb_dminus = 0
Incr Resetcounter
If Resetcounter = 1000 Then
Call Usb_reset()
End If
Wend
' Check for received data
If _usb_status._usb_rxc = 1 Then
If _usb_status._usb_setup = 1 Then
' Process a setup packet/Control message
Call Usb_processsetup(_usb_tx_status)
Elseif _usb_status._usb_endp1 = 1 Then
' Input data endpoints
Portb = _usb_rx_buffer(2) ' Copy USB data in Portb
End If
' Reset the RXC bit and set the RTR bit (ready to receive a new packet)
_usb_status._usb_rtr = 1
_usb_status._usb_rxc = 0
End If
Buttons_current = Pinc
Buttons_current = Buttons_current And 3
If Buttons_current <> Buttons_last Then
' Queue data to be sent on endpoint 2 (HID report)
If _usb_tx_status2._usb_txc = 1 Then
Buttons_last = Buttons_current
_usb_tx_buffer2(2) = Buttons_current
Call Usb_send(_usb_tx_status2 , 1) ' Send data in PC
End If
End If
Loop
End При поступлении новых данных от компьютера, будет установлен флаг _usb_endp1 в переменной _usb_status. Поступившие данные хранятся в массиве _usb_rx_buffer. В демонстрационной программе, за одну посылку, принимается только один байт данных, что описано в HID репорте. Этот байт копируется в Portb микроконтроллера. Для передачи данных из микроконтроллера в компьютер, данные записываются в массив _usb_tx_buffer2. После этого вызывается функция Usb_send. Её второй аргумент – число передаваемых байт. Но перед этим, проверяется готовность USB драйвера к передаче данных, путём проверки флага _usb_txc, переменной _usb_tx_status2. Для работы с демонстрационным устройством, была разработана компьютерная программа HID_Example_IO.exe
USB thermometer.
USB термометр создан на основе кода демонстрационного устройства. Основные изменения были внесены в главный цикл программы.
Config 1wire = Portc.5
Dim 1wire_array(9) As Byte
Dim W_1wire As Word
Dim Dsid1(8) As Byte
Dim Flaginputtermo As Byte
Dim Resetcounter As Word
Dim Idlemode As Byte
Enable Interrupts
W_1wire = 1wirecount()
Dsid1(1) = 1wsearchfirst()
1wreset ' reset the bus
1wwrite &HCC' skip rom
1wwrite &H44 ' Convert T
Timer1= 0
Flaginputtermo = 0
Do
Resetcounter = 0
'Check for reset here
While _usb_pin._usb_dminus= 0
Incr Resetcounter
If Resetcounter = 1000 Then
Call Usb_reset()
End If
Wend
'Check for received data
If _usb_status._usb_rxc = 1 Then
If _usb_status._usb_setup = 1 Then
'Process a setup packet/Control message
Call Usb_processsetup(_usb_tx_status)
Elseif _usb_status._usb_endp1 = 1 Then
' Input data endpoints
End If
'Reset the RXC bit and set the RTR bit (ready to receive a new packet)
_usb_status._usb_rtr = 1
_usb_status._usb_rxc = 0
End If
If Flaginputtermo = 1 Then
Flaginputtermo = 0
1wverify Dsid1(1)
1wwrite &HBE
1wire_array(1) = 1wread(9)
1wreset ' reset the bus
1wwrite &HCC ' skip rom
1wwrite &H44 ' Convert T
'Queue data to be sent on endpoint 2 (HID report)
If _usb_tx_status2._usb_txc = 1 Then
_usb_tx_buffer2(2) = 1wire_array(1)
_usb_tx_buffer2(3) = 1wire_Array(2)
Call Usb_send(_usb_tx_status2 , 2) ' Send data (2 bytes) in PC
End If
End If
Loop
End
Из главного цикла удалён код, принимающий данные от компьютера и добавлен код, опроса датчика DS18B20. Данные из датчика нужно считывать не чаще одного раза за 750 миллисекунд. Чтобы не задерживать работу главного цикла на такой относительно большой промежуток времени, была использована переменная Flaginputtermo как флаг. В прерывании от таймера Timer1, происходящем примерно один раз в секунду, в переменную записывается число 1, что служит признаком необходимости чтения данных из датчика. По окончанию чтения, данные копируются из массива 1wire_array в массив _usb_tx_buffer2 и вызывается функция Usb_send, передающая данные (2 байта) через шину USB в компьютер. В HID репорт было внесено небольшое изменение (выделено зелёным цветом), связанное с необходимостью передачи 2 байт за посылку.
Data 33 ' Length = 33 bytes
Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1)
Data &H09 , &H01 ' Usage(vendor Usage 1)
Data &HA1 , &H02 ' Collection(logical)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H25 , &HFF ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H02 ' Report_count(2)
Data &H81 , &H02 ' Input(data , Var , Abs)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H26 , &HFF , 0 ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H91 , &H02 ' Output(data , Var , Abs)
Data &HC0 ' End_collection
Для отображения температуры на экране компьютера, была разработана программа USB_thermometer.exe
Для их компиляции, нужен PureBasic, версии 4.40 или 4.41.
Для безошибочной компиляции, нужно установить библиотеку HID_Lib (файл "HID_Lib for PureBasic 4.41.exe" в архиве).
Подборка статей по виртуальному USB Oloppa:
- USB барометр
- USB термометр на ATmega8 и PIC18F4550
- USB часы
- USB джойстик на ATmega8
- Простое USB HID устройство на ATmega8
- СТРЕЛОЧНЫЙ ИНДИКАТОР ЗАГРУЗКИ ЦП И ОПЕРАТИВНОЙ ПАМЯТИ ПК
- ОРГАНИЗУЕМ ПРОГРАММНЫЙ USB В BASCOM-AVR НА ПРИМЕРЕ USB-ВОЛЬТМЕТРА. ЧАСТЬ 1-3
- AVR-Software-USB mit Bascom
Удачного вам ЮСБ-ирования!!!
|