ЗадачаЕсть схема со светодиодом и подключением к компьютеру по UART. На компьютере должна быть программа позволяющая зажигать и гасить светодиод на плате с микроконтроллером. Также неплохо было бы если в компьютерной программе имелась возможность принимать сообщения от микроконтроллера.
РеализацияПрограмма для микроконтроллера как и всегда будет написана в Bascom-AVR. А вот для ПК я никогда не программировал, поэтому решил пойти по пути наименьшего сопротивления и выбрал компилятор Basic-подобного языка – PureBasic. После вводной статьи от товарища Aleks8383 про его USB-вольтметр, PureBasic показался мне не сложным. Поэтому решил остановится на нем.
Тестовая схема собрана на микроконтроллере ATMega8. Можно обойтись без кварца, просто на макетке он у меня стоит, поэтому задействовал. С компьютером схема соединяется через любой имеющийся преобразователь, я использую USB-UART на микросхеме FT232RL.
Программа для микроконтроллера в Bascom-AVR.
$regfile = “m8def.dat”
$crystal = 12000000
$baud = 19200
Config Portb.0 = Output ‘подключаем светодиод
Led Alias Portb.0
‘объявляем подпрограммы
Declare Sub Getline(s As String) ‘чтение данных из буфера
Declare Sub Del_buffer() ‘очистка буфера
Dim R As Byte
Dim S As String * 1
Dim B As Byte
Do
R = Ischarwaiting() ‘проверка наличия команды в буфере UART
If R = 1 Then ‘если в буфере что-то есть переменной R присвоится значение 1
Getline S ‘вытаскиваем содержимое буфера в переменную S
If S = “A” Then ‘если там символ “А”
Print “Led ON” ‘отошлем сообщение
Led = 1 ‘и включим светодиод
Elseif S = “B” Then ‘если там символ “В”
Print “Led OFF” ‘сообщим о выключении
Led = 0 ‘выключаем светодиод
End If
Del_buffer ‘если в буфере что-то другое очищаем его
End If
Loop
End
‘подпрограмма для разбора сообщения c UART
‘=========================================
Sub Getline(s As String)
S = “”
Do
B = Inkey() ‘берем символ из буфера в формате ASCII
Select Case B
Case 0 : Exit Do ‘если дальше буфер пуст – выходим из цикла
Case 10 : If S <> “” Then Exit Do ‘конец строки, значит выходим из цикла
Case Else : If B > 31 Then S = S + Chr(b) ‘составляем строку
End Select
Loop
End Sub
‘очистка буфера UART
‘===================
Sub Del_buffer()
Do
B = Inkey() ‘кладем в переменную “В” данные из буфера
Loop Until B = 0 ‘выходим из цикла когда в переменную попадет 0 (буфер пуст)
End Sub
Немного поясню программу. Функция Ischarwaiting() возвратит переменной R единицу если в буфере присутствуют какие-либо данные. Если функция вернула единицу идем в подпрограмму Getline и кладем в переменную S все что прочитали из буфера. В этой самой подпрограмме Sub Getline в цикле Do…Loop по одному достаются значения символов согласно таблице ASCII с помощью функции Inkey()Тут надо остановится и сказать что по таблице ASCII до 31 значения идут управляющие символы. Так цифра 10 означает завершение строки (Line Feed), это то чем завершается строка и обнаружив ее мы завершаем извлекать данные из буфера и уходим из цикла. А все печатаемые символы (буквы и цифры) имеют значения больше 31. Поэтому если в переменную В попадает значение больше 31 значит этот символ добавляем в основную строку S = S + Chr(b)Если все данные из буфера мы достали, а символа 10 так и не дождались (если программа или устройство по какой-то причине автоматически не завершает строку) то из цикла нам поможет выйти свойство функции Inkey() , она в случае пустого буфера возвращает 0. По этому условию у нас тоже организован выход из цикла.
Так как из-за помех в буфер может попасть какой-нибудь мусор, аналогичным образом организована подпрограмма очистки буфера Sub Del_buffer(). К ней мы можем обращаться каждый раз после чтения, чтобы исключить порчу строк ненужными данными.
А дальше, получив строку S, в зависимости от ее содержимого, выполняем определенное действие. К примеру если пришел символ “А” – включим светодиод, если “В” – выключим.
Теперь перейдем на приложение со стороны компьютера. Программа для ПК написанная в PureBasic:
#COM_Port = 2 ;Идентификатор COM порта. ;Процедура открытия порта. выбранного из списка Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ;С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ;Закрываем его. EndIf Port = GetGadgetText(3) ;Тут открываем порт с необходимыми настройками If OpenSerialPort(#COM_Port,Port,19200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,255,255) Text=”Порт “+Port+” открыт” : Color=RGB(46, 137, 36) Else Text=”Не удалось открыть порт “+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
;Процедура приема данных Procedure InData() Protected InBytes If IsSerialPort(#COM_Port) ;С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ;Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), InBytes) If RealInBytes>0 AddGadgetItem(4, -1, PeekS(@InBuffer(), RealInBytes, #PB_Ascii)) EndIf EndIf EndIf EndProcedure ;Процедура передачи данных Procedure ComOut(Send_data.s) If IsSerialPort(#COM_Port) ;если порт открыт ComWrite(SerialPortID(#COM_Port),@send_data,1) ;Шлем данные из переменной Send_data Else ;Выводим сообщение об ошибке. MessageRequester(“Ошибка”,”Текущий порт не доступен!”,16) EndIf EndProcedure If OpenWindow(0, 300, 100, 320, 370, “Тестовая программа”) ;Создаем окно программы ButtonGadget(1, 90, 310, 100, 35, “Зажечь”, #PB_Button_Default) ;Кнопка “Зажечь” TextGadget(2,10,310,25,15,”Порт”) ;Выводим в окно надпись “Порт”. ComboBoxGadget(3, 10, 325, 70, 21, #PB_ComboBox_Editable) ;гаджет выпадающего списка For i=1 To 99 ;создаем список от 1 до 99 с возможными портами для открытия AddGadgetItem(3,-1,”COM”+Str(i)) Next i SetGadgetState(3,0) ;Делаем активным нулевой пункт выпадающего списка. EditorGadget(4, 8, 10, 305, 280,#PB_String_ReadOnly) TextGadget(5,10,350,200,15,””) ;Здесь будет отображаться результат открытия порта. ButtonGadget(6, 200, 310, 100, 35, “Погасить”, #PB_Button_Default) ;Кнопка “Погасить” Select_ComPort() Repeat Event = WaitWindowEvent() InData() ;принимаем данные из UART все время пока работает программа If Event=#PB_Event_Gadget ;если произошло срабатывание гаджета Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка “Зажечь” ComOut(“A”) ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ;Считываем текст из текущего пункта выпадающего списка. ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() ElseIf Gadget=6 ;нажата кнопка “Погасить” ComOut(“B”) ;Переходим на процедуру передачи байта. InData() EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf End
В начале программы присутствуют три процедуры: Procedure Select_ComPort() – процедура открытия выбранного из списка COM-порта. При срабатывании гаджета ComboBoxGadget произойдет выбор номера порта и этот номер будет открыт (если доступен) в данной процедуре. Здесь же прописываются необходимые настройки порта (скорость, размер буфера и пр.) так же нужно не забывать что микроконтроллер и программа должны общаться на одной скорости. В данном примере использую скорость 19200 бод. Procedure InData() – процедура чтения данных из ком-порта. Этой процедурой пользуемся когда нужно узнать что пришло от микроконтроллера. Прочитанные данные помещаются в гаджет под номером 4 (у нас это EditorGadget) Procedure ComOut(Send_data.s) – процедура отправки данных в ком-порт. Отправляться будет содержимое переменной Send_data.
А дальше в программе идут стандартные функции создания окна и необходимых гаджетовOpenWindow(0, 300, 100, 320, 370, “Тестовая программа”) ;Создаем окно программы
и обработка их действийEvent = WaitWindowEvent()
В результате программа обзаведется двумя кнопками (“Зажечь” и “Погасить”), выпадающим списком, в котором можно выбрать необходимый СОМ порт, гаджетом в который будет выводится сообщения присланные микроконтроллером (по типу терминала) и еще несколькими текстовыми гаджетами для информационных целей. Выбрав нужный порт и подключив тестовую схему к компьютеру через преобразователь, жмем кнопку “Зажечь”. При этом в окне приема сообщений появится текст “Led ON”, присланный микроконтроллером
В общем все наглядно продемонстрировано на видео
Отдельное спасибо пользователю с именем Пётр, за помощь в написании программы на PureBasic! Теперь и я помигал светодиодиком! 😀
Исходники и прошивка для ATMega8 Исходники тестовой программы для ПК Скомпилированная программа
Последние статьи
- Лучшая практика проектирования при размещении компонентов печатной платы
- Android 6.0 на lancer X
- Простой усилитель мощности класса АВ своими руками.
- Двухтактный ультралинейный ламповый УНЧ на EL84 (6П14П).
- Люксметр на ATmega8 и цифровом датчике BH1750
- Контроллер для светодиодной ленты с ИК управлением
- Самодельный LED светильник на основе ИК датчика HC-SR501
- Простой усилитель низкой частоты на TDA7377 и NE5532
- Простейший звонок с двумя мелодиями
- LED Cube 8x8x8 на Arduino с RTC