Микроконтроллеры фирмы ATMEL - ATMegaXX схемы, программы, исходники |
Страница №2
Создание исполнительных устройств на базе микроконтроллеров ATMegaXX
Ну ежели с пайкой проблем не возникло и платы готовы нужно их оживить при помощи прошивки. Для создания прошивки воспользуемся одной из следующих программ: FastAVR версии не ниже 4 или mikroBasicAVR. И та и другая программа достойны внимания НО! mikroBasicAVR в России не продается, не взламывается и ведет себя откровенно паршиво. Исполняемый код получается в 1,5 раза больше чем у FastAVR. В общем – полное говно.
Сначала о FastAVR. Устанавливаем программу, создаем новый документ и вставляем следующее: '///////////////////////////////////////////////////////// '/// FastAVR Basic Compiler for AVR by MICRODESIGN /// '/// Name of Your project '///////////////////////////////////////////////////////// $Device= m8 ' Используемый девайс в данном случае ATMega8 $Stack = 32 ' Черт его знает что это $Clock = 1.000 ' Частота кварца в МГц (в данном случае 1МГц) ' цельная куча переменных, описываем сразу Dim data0 As String*6,a As String*6 'As String*6 – строка ACSII 6 символов длинной Dim data1 As String*1,data2 As String*1,data3 As String*1 Dim s As String*6, ssm1 As String*6, ssm2 As String*6, ssm3 As String*6 Dim i As Byte,j As Byte,k As Byte,l As Byte,l1 As Byte,l2 As Byte Dim l3 As Byte,ko As Byte, k1 As Byte,k2 As Byte,k3 As Byte Dim bt1 As Byte, bt2 As Byte, bt3 As Byte ' Byte – целочисленная переменная БЕЗ знака Dim d1 As Integer,dd1 As Integer 'Integer – переменная ИМЕЮЩАЯ знак (+ или -) Dim d2 As Integer,dd2 As Integer Dim d3 As Integer,dd3 As Integer Dim p1 As Byte,p2 As Byte,p3 As Byte
Declare Sub Init () ' декларируем, что будет подпрограмма
Open Com=PORTD.0, 4800 For Input As #1 'Открываем Com-порт на порту D на скорости Open Com=PORTD.1, 4800 For Output As #1 ' 4800 Бод. Input-ввод (пин 0), Output-вывод (пин 1),
Do ' place your code in next line DDRC = &hFF ' что-то там с определением вывода порта С PORTC = &h00 ' Выключаем PORTC (приводим пины порта С к состоянию 0В s="000000" i=0 j=0 k=0 l=0 bt1=0 bt2=0 bt3=0 ko=0 k1=0 k2=0 k3=0 d1=0 dd1=0 d2=0 dd2=0 d3=0 dd3=0 l1=0 l2=0 l3=0 ' Блок для проверки состояния микропереключателей While PINB.3 = 0 ' Ждем пока моторы установят механизм в начальное состояние PORTC.0 = 1 ' От начального состояния потом будем вести отсчет Wend PORTC.0 = 0 While PINB.4 = 0 PORTC.1 = 1 Wend PORTC.1 = 0 While PINB.5=0 PORTC.2 = 1 Wend PORTC.2 = 0
Print #1, "System Ready" 'Выводим на Com-порт сообщение, что установка в 0 закончена Print #1, "OK" ' Блок приема в микроконтроллер 6-ти ACSII символов по RS-232 Do ' data0 = InputBin #1,a ' Print #1, data0 Print #1, a data0=Mid(a,2,1) ‘ из 6-ти символов выбираем 2-й по счету, длинной в 1 символ ' Блок формирования массивов по исполнению If data0="1" Then ' если во 2 символе присутствует 1, то формируется ssm1 ssm1=a Print #1,ssm1 k1=1 End If If data0="2" Then ' если во 2 символе присутствует 2, то формируется ssm2 ssm2=a Print #1,"ssm2" k2=1 End If If data0="3" Then ssm3=a Print #1,"ssm3" k3=1 End If
ko=k1+k2+k3 If ko=3 Then Print #1,"All OK" ' если все приняли выводится на Com-порт ,"All OK" ko=0 k1=0 k2=0 k3=0 Init() End If Loop Loop
'///////////А это подпрограмма Sub Init () data1=Mid(ssm1,3,1) ‘ из 6-ти символов выбираем 3-й по счету, длинной в 1 символ data2=Mid(ssm2,3,1) data3=Mid(ssm3,3,1) If data1="m" Then 'Блок проверки в какую сторону крутить мотор d1=-1 Else d1=1 End If If data2="m" Then d2=-1 Else d2=1 End If If data3="m" Then d3=-1 Else d3=1 End If dd1=Mid(ssm1,4,3) 'из 6-ти символов выбираем 4-й по счету, длинной в 3 символа dd2=Mid(ssm2,4,3) dd3=Mid(ssm3,4,3) p1=Val(dd1) 'из 3-х символов формируем целое число p2=Val(dd2) p3=Val(dd3)
'//Блок исполнения ранее вычисленного While bt1<>p1 Or bt2<>p2 Or bt3<>p3 'Работаем пока количество щелчков микропереключателей ‘ меньше заданного If d1=1 And bt1<>p1 Then 'если d1(направление) положительное то: PORTC.0 = 1 ‘ на порт С пин 0 выдаем сигнал +5В (включаем) и… If PINB.0=1 And l1=0 Then l1=1 bt1=bt1+1 'считаем щелчки End If If PINB.0=0 Then l1=0 End If Else PORTC.0 = 0 'когда кол-во щелчков совпало с заданным порт С пин 0 переводим на 0В (выкл) End If ‘ все остальное принципиально подобно If d1=-1 And bt1<>p1 Then PORTC.3 = 1 If PINB.0=1 And l1=0 Then l1=1 bt1=bt1+1 End If If PINB.0=0 Then l1=0 End If Else PORTC.3 = 0 End If If d2=1 And bt2<>p2 Then PORTC.1 = 1 If PINB.1=1 And l2=0 Then l2=1 bt2=bt2+1 End If If PINB.1=0 Then l2=0 End If Else PORTC.1 = 0 End If If d2=-1 And bt2<>p2 Then PORTC.4 = 1 If PINB.1=1 And l2=0 Then l2=1 bt2=bt2+1 End If If PINB.1=0 Then l2=0 End If Else PORTC.4 = 0 End If If d3=1 And bt3<>p3 Then PORTC.2 = 1 If PINB.2=1 And l3=0 Then l3=1 bt3=bt3+1 End If If PINB.2=0 Then l3=0 End If Else PORTC.2 = 0 End If If d3=-1 And bt3<>p3 Then PORTC.5 = 1 If PINB.2=1 And l3=0 Then l3=1 bt3=bt3+1 End If If PINB.2=0 Then l3=0 End If Else PORTC.5 = 0 End If Wend ‘ чтобы в следующий раз не было ошибок все переменные приодим в исходное состояние l1=0 l2=0 l3=0 PORTC.0 = 0 PORTC.3 = 0 PORTC.1 = 0 PORTC.4 = 0 PORTC.2 = 0 PORTC.5 = 0
bt1=0 bt2=0 bt3=0 ssm1="" ssm2="" ssm3="" ‘ и выводим сообщение что система готова к приему следующих команд Print #1,"End Sub" Print #1,"System Ready"
End Sub
Программа для microBasic AVR ' '* Project name: ' USART1 Test '* Author: ' MikroElektronika, July 2006. ' * Description: ' This program demonstrates how to use USART1A library. ' * Test configuration: ' MCU: ATmega8 ' Dev.Board: Easy AVR 3 ' Oscillator: External, 8 MHz ' Ext. Modules: ' SW: mikroBasic for AVR 3.00 ' * NOTES: ' connect RS232 module to MCU ' program usart1_test ‘ обзываем кучу переменных… dim data,data1,data2,data3 as byte dim s as byte[6] ' в данном случае byte[6] – массива из 6 символов dim ssm1 as byte[6] dim ssm2 as byte[6] dim ssm3 as byte[6] dim i,j,k,l as byte dim l1,l2,l3 as byte dim ko,k1,k2,k3 as byte dim bt1,bt2,bt3 as byte dim d1,dd1,dd11,dd111 as short ' short – короткое беззнаковое dim d2,dd2,dd22,dd222 as short dim d3,dd3,dd33,dd333 as short dim p1,p2,p3 as byte
sub procedure Init ' подпрограмма Init data1=ssm1[2] data2=ssm2[2] data3=ssm3[2] if data1="m" then ‘m - направление вращения моторов d1=0-1 else d1=1 end if if data2="m" then d2=0-1 else d2=1 end if if data3="m" then d3=0-1 else d3=1 end if dd1=ssm1[3] dd11=ssm1[4] dd111=ssm1[5] dd2=ssm2[3] dd22=ssm2[4] dd222=ssm2[5] dd3=ssm3[3] dd33=ssm3[4] dd333=ssm3[5] ‘ формируем количество для скавнения с количеством щелчков микропереключателей p1=100*Bcd2Dec16(dd1)+10*Bcd2Dec16(dd11)+Bcd2Dec16(dd111) p2=100*Bcd2Dec16(dd2)+10*Bcd2Dec16(dd22)+Bcd2Dec16(dd222) p3=100*Bcd2Dec16(dd3)+10*Bcd2Dec16(dd33)+Bcd2Dec16(dd333)
‘ работаем пока условия выполняются while (bt1<>p1-2) or (bt2<>p2-2) or (bt3<>p3-2) if (d1>0) and (bt1<>p1-2) then PORTC.0 = 1 ' пока условия выполняются на порту С пин 0 - +5В if Button(PORTB, 0, 1, 1) and (l1=0) then l1=1 bt1=bt1+1 end if if Button(PORTB, 0, 1, 0) then l1=0 end if else PORTC.0 = 0 ' выполнили условия выключаем порт end if if (d1<0) and (bt1<>p1-2) then PORTC.3 = 1 if Button(PORTB, 0, 1, 1) and (l1=0) then l1=1 bt1=bt1+1 end if if Button(PORTB, 0, 1, 0) then l1=0 end if else PORTC.3 = 0 end if if (d2>0) and (bt2<>p2-2) then PORTC.1 = 1 if Button(PORTB, 1, 1, 1) and (l2=0) then l2=1 bt2=bt2+1 end if if Button(PORTB, 1, 1, 0) then l2=0 end if else PORTC.1 = 0 end if if (d2<0) and (bt2<>p2-2) then PORTC.4 = 1 if Button(PORTB, 1, 1, 1) and (l2=0) then l2=1 bt2=bt2+1 end if if Button(PORTB, 1, 1, 0) then l2=0 end if else PORTC.4 = 0 end if if (d3>0) and (bt3<>p3-2) then PORTC.2 = 1 if Button(PORTB, 2, 1, 1) and (l3=0) then l3=1 bt3=bt3+1 end if if Button(PORTB, 2, 1, 0) then l3=0 end if else PORTC.2 = 0 end if if (d3<0) and (bt3<>p3-2) then PORTC.5 = 1 if Button(PORTB, 2, 1, 1) and (l3=0) then l3=1 bt3=bt3+1 end if if Button(PORTB, 2, 1, 0) then l3=0 end if else PORTC.5 = 0 end if wend ‘ переменные и порт приводим в исходное l1=0 l2=0 l3=0 PORTC.0 = 0 PORTC.3 = 0 PORTC.1 = 0 PORTC.4 = 0 PORTC.2 = 0 PORTC.5 = 0
bt1=0 bt2=0 bt3=0 ssm1="" ssm2="" ssm3="" USart1_Write_Char(0x0D) Usart1_Write_Text("OK") ‘ передали по Com-порту что команда выполнена USart1_Write_Char(0x0D) end sub
main: DDRC = $FF ' Порт С будет выходом PORTC = $00 ' Пины порта в состояние 0В s="000000" i=0 j=0 k=0 l=0 bt1=0 bt2=0 bt3=0 ko=0 k1=0 k2=0 k3=0 d1=0 dd1=0 dd11=0 dd111=0 d2=0 dd2=0 dd22=0 dd222=0 d3=0 dd3=0 dd33=0 dd333=0 l1=0 l2=0 l3=0 ' Блок установки системы в начальное состояние (состояние начала отсчета) while Button(PORTB, 3, 1, 0) ' если портB пин 0 подано 5В более чем на 1 милисекунду PORTC.0 = 1 ' then turn on LED on PORTC.0 wend PORTC.0 = 0 while Button(PORTB, 4, 1, 0) PORTC.1 = 1 wend PORTC.1 = 0 while Button(PORTB, 5, 1, 0) PORTC.2 = 1 wend PORTC.2 = 0 USart1_Init(4800) ‘инициализируем Com-порт на 4800 Бод Delay_ms(10) ' wait for module to set Usart1_Write_Text("OK") USart1_Write_Char(0x0D) ' это скан-код клавиши ENTER
while true while USart1_Data_Ready=0
wend data = USart1_Read ' прочитали с Com-порта символ и присвоили его переменной data USart1_Write_Char(data) ' вывели этот символ обратно для контроля ‘ далее формируем массивы и проверяем их на отношение к тому или иному мотору if i<6 then s[i]=data else if s[1]="1" then 'если символ «1» то формируем массиву ssm1 for j=0 to 5 ssm1[j]=s[j] next j if k1=0 then k1=k1+1 end if end if if s[1]="2" then for j=0 to 5 ssm2[j]=s[j] next j if k2=0 then k2=k2+1 end if end if if s[1]="3" then for j=0 to 5 ssm3[j]=s[j] next j if k3=0 then k3=k3+1 end if end if i=-1 ko=k1+k2+k3 end if i=i+1 if data = 0x0D then i=0 s="" end if if ko=3 then 'если ВСЕ массивы сформированы выполняем подпрограмму Init Init ko=0 k1=0 k2=0 k3=0 end if wend end. Далее все это компилируем и на выходе получаем файл с расширением .hex
Опосля всего можно посмотреть как эта прошивка работает в PROTEUSе. Для этого устанавливаем Proteus, открываем его, создаем новый проект в проект вносим из вкладки Microprocerror ICs ATMEGA8, из вкладки VIRTUAL INSTRUMENTs – VIRTUAL TERMINAL, из вкладки Switches & Relays – Button и Switch. Порт B пины 0,1 и 2 занимаем BUTTON, пины 3, 4, 5 Switch, VIRTUAL TERMINAL подключаем RxD на TxD, а TxD на RxD Щелкаем по микроконтроллеру и в Program File указываем путь к скомпилированному в FastAVR или microBasicAVR hex – файлу. Установим Clock Frequency на частоту кристалла (мы же в компиляторе указывали эту частоту – пришло время ее указать и здесь), щелкаем по VIRTUAL TERMINAL – и указываем в свойствах скорость в Бодах (у нас было 4800) (для справки далее 8, NONE,1,No). Стартуем (RUN). Смотрим что получилось…. Если не работает внимательно посмотрите все настройки в протеусе. В общем-то основной принцип работы всех цифровых устройств, основанных на TTL логике, это появление на входах или выходах напряжения +5В или 0В. Собственно именно этим и занимается наша прошивка. А вот мы то и заставляем эти устройства, при помощи различных команд выводить на нужные НАМ ножки то или иное напряжение. Итак на настоящий момент мы имеем: Спаянные схемы, hex-файл прошивки для микроконтроллера и мы посмотрели как этот hex-файл работает, правда в виртуальном устройстве. Нам осталось: залить прошивку в микроконтроллер и сделать программу для управления нашим устройством с компьютера.
|