Часть 2.
Рабочая программа и ее пояснение.
Рабочая программа и ее пояснение.
Пришло время ознакомиться с рабочей программой. Загрузите по ссылкам исходник программы для контроллера и файлы для ее отладки в Протеусе:
Распакуйте их. Откройте Bascom и загрузите в нем файл noname4.bas. Так-же откройте в Протеусе файл rob_demo.dsn. В Протеусе переопределите в настройках контроллере файл прошивки.
Запустите в Протеусе симуляцию. В окне терминала введите команду qqa1 и нажмите <Enter>, это заставит "крутиться" один из двигателей.
Дополнительно: В Протеусе двигатели объединены парами (один "наезжает" на другой"), одна такая спарка - это один "реальный" двигатель, верхний - направление вращения в одну сторону, нижний - в другую, так я сделал чтобы не рисовать мостовую схему.
Команды для контроллера:
qqa1 - вращение двигателя камеры вверх
qqb1 - вращение двигателя камеры вниз
qqr1 - поворот робота налево
qqs1 - поворот робота направо
qql1 - движение робота вперед
qqk1 - движение робота назад
qqt1 - останов всех двигателей
qqo1 - включение фонаря-фары
qqp1 - выключение фонаря фары
qqf1 - включение дополнительного устройства (сигнал)
qqg1 - выключение дополнительного устройства (сигнал)
Пояснение: цифра 1 в конце команды обозначает скорость вращения мотора. Скорость задается в интервале от 0 до 9, чем число выше - тем скорость ниже. То есть: qqa0 - двигатель камеры будет вращаться очень быстро, qqa9 - двигатель камеры будет вращаться с самой медленной скоростью. На дополнительных устройствах - фонарь и сигнал, скорость не распространяется, но программа ожидает введения четырех знаков, то этому в этих командах цивра просто забивает пустующее место.
Не следует забивать вместо цифр символы букв, хотя попробовать можете.
Приведу код программы:
$regfile = "m16def.dat"
$crystal = 4000000
$baud = 19200
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40
'///////////* определяем состояние портов - на ввод или на вывод *//////
Ddra = $00
Ddrb = $ff
Ddrc = $ff
Ddrd = $00
'//////////////////* описываем переменные */////////////////////////////
Dim I As Byte , J As Byte , Res As Byte
Dim Pos As Byte , Pos1 As Byte , Pos2 As Byte
Dim Msgr As String * 20
Dim Msga As String * 1
Dim Msga1 As String * 1 , Z As String * 2
Dim Ad As Word
Dim Cam As Byte , Prt As Byte
Dim O As Byte , F As Byte , Of As Byte
'/////////////////* присваиваем переменным значения *///////////////////
J = 0
Z = "qq"
Cam = 0
O = 0
F = 0
Of = 0
'//////* включаем АЦП (аналого-цифровое преобразование) *///////////////////
Start Adc
'/////* устанавливаем и включаем прерывание (как подпрограмму) *////////////
On Urxc Rec_isr
Enable Urxc
Enable Interrupts
'/////////////* НАЧИНАЕМ ОСНОВНУЮ ПРОГРАММУ */////////////////////////////////
Do
'//////////////////* начало оператора Select *////////////////////////////////
Select Case Msga
Select Case Msga
'///////////////////* камера вверх с проверкой предела поворота */////////////
Case "a"
Ad = Getadc(0)
If Ad > 50 Then
Portb.1 = 0
Portb.0 = 1
Cam = 5
End If
Msga = "e"
'///////////////////* камера вниз с проверкой предела поворота *//////////////
Case "b"
Ad = Getadc(0)
If Ad < 1000 Then
Portb.0 = 0
Portb.1 = 1
Cam = 7
End If
Msga = "e"
'///////////////////* вперед непрерывно *////////////////////////////////////
Case "k"
Portb.0 = 0
Portb.1 = 0
Portb.3 = 0
Portb.5 = 0
Portb.2 = 1
Portb.4 = 1
Msga = "e"
'////////////////////* назад непрерывно *////////////////////////////////////
Case "l"
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.4 = 0
Portb.3 = 1
Portb.5 = 1
Msga = "e"
'////////////////////* влево непрерывно *///////////////////////////////////
Case "r"
Portb.0 = 0
Portb.1 = 0
Portb.4 = 0
Portb.3 = 0
Portb.2 = 1
Portb.5 = 1
Msga = "e"
'////////////////////* вправо непрерывно *//////////////////////////////////
Case "s"
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.5 = 0
Portb.4 = 1
Portb.3 = 1
Msga = "e"
'//////////////////* полный стоп только двигателей *///////////////////////
Case "t"
Portb.0 = 0
Portb.1 = 0
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.3 = 0
Portb.4 = 0
Portb.5 = 0
'//////////////////* пустой оператор*//////////////////////////////////////
Case "e"
'//////////////////* фара вкл *///////////////////////////////////////////
Case "o"
Portb.6 = 1
O = 1
Msga = "e"
'//////////////////* фара выкл *///////////////////////////////////////////
Case "p"
Portb.6 = 0
O = 0
Of = 0
Msga = "e"
'//////////////////* сигнал вкл *//////////////////////////////////////////
Case "f"
Portb.7 = 1
F = 1
Msga = "e"
'//////////////////* сигнал выкл *//////////////////////////////////////////
Case "g"
Portb.7 = 0
F = 0
Of = 0
Msga = "e"
'//////////////////* конец оператора Select *////////////////////////////////
End Select
'/////////////////////*проверка включения фары или сигнала*//////////////
If O = 1 Then
Of = 1
If F = 1 Then
Of = 3
End If
End If
If F = 1 Then
Of = 2
If O = 1 Then
Of = 3
End If
End If
'/////////////////*проверка - не достигнут ли предел поворота камеры *///////
Ad = Getadc(0)
If Cam = 5 Then
If Ad < 50 Then
Portb.0 = 0
Portb.1 = 0
End If
End If
If Cam = 7 Then
If Ad > 1000 Then
Portb.0 = 0
Portb.1 = 0
End If
End If
'///////////////* регулирование скорости с проверкой *///////////
'///////////////* не включены ли камера и/или фонарь *///////////
Prt = Portb
'Prt = Pinb
If Res = 0 Then
For I = 0 To J Step 1
Waitms 3
'*******************************'
If Prt < 64 Then
Portb = 0
End If
If Of = 1 Then
Portb = 64
End If
If Of = 2 Then
Portb = 128
End If
If Of = 3 Then
Portb = 192
End If
'*********************************'
Next I
End If
Portb = Prt
'///////////////////*обработка команды с СОМ-порта */////////////////////////
If Res = 1 Then
Pos1 = Pos + 2
Pos2 = Pos + 3
Msga = Mid(msgr , Pos1 , 1)
Msga1 = Mid(msgr , Pos2 , 1)
J = Val(msga1)
'J = J + J
Res = 0
End If
'//////////* возвращаемся к оператору Do *///////////////////////////////
Loop
'/////**** подпрограмма-прерывания, она ждет входящей команды****///////
Rec_isr:
If Prt < 64 Then
Portb = 0
End If
If Of = 1 Then
Portb = 64
End If
If Of = 2 Then
Portb = 128
End If
If Of = 3 Then
Portb = 192
End If
'///////////* получаем данные на СОМ-порт *//////////////////////////////
Input Msgr
Pos = Instr(msgr , Z)
If Pos > 0 Then
Res = 1
Msga = "t"
End If
'/////////* возвращаемся в основную проргамму *//////////////////////////
Case "a"
Ad = Getadc(0)
If Ad > 50 Then
Portb.1 = 0
Portb.0 = 1
Cam = 5
End If
Msga = "e"
'///////////////////* камера вниз с проверкой предела поворота *//////////////
Case "b"
Ad = Getadc(0)
If Ad < 1000 Then
Portb.0 = 0
Portb.1 = 1
Cam = 7
End If
Msga = "e"
'///////////////////* вперед непрерывно *////////////////////////////////////
Case "k"
Portb.0 = 0
Portb.1 = 0
Portb.3 = 0
Portb.5 = 0
Portb.2 = 1
Portb.4 = 1
Msga = "e"
'////////////////////* назад непрерывно *////////////////////////////////////
Case "l"
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.4 = 0
Portb.3 = 1
Portb.5 = 1
Msga = "e"
'////////////////////* влево непрерывно *///////////////////////////////////
Case "r"
Portb.0 = 0
Portb.1 = 0
Portb.4 = 0
Portb.3 = 0
Portb.2 = 1
Portb.5 = 1
Msga = "e"
'////////////////////* вправо непрерывно *//////////////////////////////////
Case "s"
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.5 = 0
Portb.4 = 1
Portb.3 = 1
Msga = "e"
'//////////////////* полный стоп только двигателей *///////////////////////
Case "t"
Portb.0 = 0
Portb.1 = 0
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.3 = 0
Portb.4 = 0
Portb.5 = 0
'//////////////////* пустой оператор*//////////////////////////////////////
Case "e"
'//////////////////* фара вкл *///////////////////////////////////////////
Case "o"
Portb.6 = 1
O = 1
Msga = "e"
'//////////////////* фара выкл *///////////////////////////////////////////
Case "p"
Portb.6 = 0
O = 0
Of = 0
Msga = "e"
'//////////////////* сигнал вкл *//////////////////////////////////////////
Case "f"
Portb.7 = 1
F = 1
Msga = "e"
'//////////////////* сигнал выкл *//////////////////////////////////////////
Case "g"
Portb.7 = 0
F = 0
Of = 0
Msga = "e"
'//////////////////* конец оператора Select *////////////////////////////////
End Select
'/////////////////////*проверка включения фары или сигнала*//////////////
If O = 1 Then
Of = 1
If F = 1 Then
Of = 3
End If
End If
If F = 1 Then
Of = 2
If O = 1 Then
Of = 3
End If
End If
'/////////////////*проверка - не достигнут ли предел поворота камеры *///////
Ad = Getadc(0)
If Cam = 5 Then
If Ad < 50 Then
Portb.0 = 0
Portb.1 = 0
End If
End If
If Cam = 7 Then
If Ad > 1000 Then
Portb.0 = 0
Portb.1 = 0
End If
End If
'///////////////* регулирование скорости с проверкой *///////////
'///////////////* не включены ли камера и/или фонарь *///////////
Prt = Portb
'Prt = Pinb
If Res = 0 Then
For I = 0 To J Step 1
Waitms 3
'*******************************'
If Prt < 64 Then
Portb = 0
End If
If Of = 1 Then
Portb = 64
End If
If Of = 2 Then
Portb = 128
End If
If Of = 3 Then
Portb = 192
End If
'*********************************'
Next I
End If
Portb = Prt
'///////////////////*обработка команды с СОМ-порта */////////////////////////
If Res = 1 Then
Pos1 = Pos + 2
Pos2 = Pos + 3
Msga = Mid(msgr , Pos1 , 1)
Msga1 = Mid(msgr , Pos2 , 1)
J = Val(msga1)
'J = J + J
Res = 0
End If
'//////////* возвращаемся к оператору Do *///////////////////////////////
Loop
'/////**** подпрограмма-прерывания, она ждет входящей команды****///////
Rec_isr:
If Prt < 64 Then
Portb = 0
End If
If Of = 1 Then
Portb = 64
End If
If Of = 2 Then
Portb = 128
End If
If Of = 3 Then
Portb = 192
End If
'///////////* получаем данные на СОМ-порт *//////////////////////////////
Input Msgr
Pos = Instr(msgr , Z)
If Pos > 0 Then
Res = 1
Msga = "t"
End If
'/////////* возвращаемся в основную проргамму *//////////////////////////
Return
Дополнительно по некоторым операторам:
1) Обозначене переменных Dim - переменные имеют числовую форму: Bit, Byte, Integer,Word (размер числа в порядке увеличения) и строковую: String*2 где 2 это количество символов в строке("ab"). String*5 имеет 5 символов ("abcde"), String*20 - 20 символов ("abcdefgh123456789prs");
2) Все действие программы заключается в выполнении основного кода, помещенного между операторами Do и Loop.
3) Input - ждем данных по СОМ-порту, а получив их присваиваем в переменную Msgr. Название переменной может быть любой (саму переменную мы обозначаем в начале программы Dim XX As String*Y, где XX - имя переменной, а Y - количество символов в строке);
4) Start Adc
On Urxc Rec_isr
Enable Urxc
Enable Interrupts - это команды компилятора, мы их пишем если хотим запустить функции на контроллере или убираем, если эти функции не нужны. Сами команды неизменяемы, переносятся как есть из программы в программу;
5) Select Case Msga
Case "a"
Case "a"
Case "k"
End Select - операторы команды Select. Будет выполняться только тот блок Case, значение в котором ("a" или "k" в этом примере) будет равно переменной Msgr. То есть если Msgr равно a то выполнится блок под строчкой Case "a", если k - то под Case "k", если t - то под Case "t";
6) Getadc(0) - получаем значение напряжения на вводе контроллера ADC0 (порт a пин 0 ножка контроллера 40). Если надо снять значение напряжения с ADC3 (порт a пин 3 ножка контроллера 37), то вводим Getadc(3). Чтобы понять куда смотреть и что ставить посмотрите на рисунок:
Красным овалом обозначены ножки контроллера и порт "a", зеленым - назначенный этой ножке номер АЦП (аналого-цифрового преобразователя), синим - ножка контроллера, на которую надо будет обязательно подать +5В, это "опорное" напряжение, относительно которого будет рассчитываться значение АЦП (+5В это питание контроллера, надо будет при монтаже просто не забыть подвести к ней +5В), если это забыть сделать, то контроллер значение выдавать не будет;
7) Pos = Instr(msgr , Z) - поиск в строке msgr символов которые присвоены строковой переменной Z, если совпадение найдено, то переменная Pos - получает порядковый номер этого совпадения, если совпадений не найдено, то Pos получает значение ноля;
8) Оператор условия:
If Of = 2 Then
Portb = 128
End If
Portb = 128
End If
Синим показаны операторы Bascom-а, они обязательны. Желтым обозначено условие, которое ЕСЛИ СОБЛЮДАЕТСЯ, то выполняется код, который окрашет красным. Если условие не выполняется, то и "красный" код - пропускается;
9) Оператор цикла:
For I = 0 To J Step 1
Waitms 3
Waitms 3
Next I
Синим показаны операторы Bascom-а, они обязательны. Желтым обозначено условие такое: "красный" код будет выполняться до тех пор, пока значения I и J не станут равными. Вначале I равно нолю, а J - допустим 5, I меньше J "красный" код выполняется, но после его выполнения I увеличивается на значение указанное после Step (на 1). Т.е. после выполнения "красного" кода к I приплюсовывается число, стоящее после Step. Красный код будет выполняться столько раз, сколько раз надо будет прибавить значение Step к нолю, после чего основная программа продолжится.
10) Msga = Mid(msgr , Pos1 , 1) : команда находит в строке msgr символы, которые находятся после порядкового номера Pos1 и присваивает их строковой переменной Msga в количестве 1 символа. Если будет так написано: Msga = Mid(msgr , Pos1 , 5) то Msga присвоится значение пяти символов стоящих на и после позиции Pos1 в строке msgr;
11) J = Val(msga1) Этот оператор преобразует строковые символы из msga1 в число и присваевает его переменной J.
Больше в программе ничего нет, остались только математические операторы.