Управляем микроконтроллером с ПК по UART

ЗадачаЕсть схема со светодиодом и подключением к компьютеру по 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 Исходники тестовой программы для ПК Скомпилированная программа


Взято с: avrproject.ru


Категория: AVR
Метки:

Написать коментарий

*
= 3 + 4

Добавить изображение

Последние статьи