Главная » Статьи » Полезная информация |
Управляем микроконтроллером с ПК по 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! Теперь и я помигал светодиодиком! :D
| |
Просмотров: 41989 | Комментарии: 32
| Теги: |
Всего комментариев: 32 | 1 2 » | ||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
1-30 31-32 | |||||||||||||||||||||||||||||
авторизация
рубрики
Проекты [46] |
Как подключить [32] |
Инструменты [3] |
Полезная информация [18] |
Объявления [3] |
метки