Используются технологии uCoz

Часть2
Home Up

Микроконтроллеры фирмы ATMEL - ATMegaXX

схемы, программы, исходники

Часть 3

Исходники:
Для FastAVR:

image004.gif (498 bytes)

Для MicroBasicAVR:

image005.gif (551 bytes)

Для Proteus:

image004.gif (498 bytes)

Страница №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). Смотрим что получилось…. Если не работает внимательно посмотрите все настройки в протеусе.

Файл для теста в Proteus - image004.gif (498 bytes)

В общем-то основной принцип работы всех цифровых устройств, основанных на TTL логике, это появление на входах или выходах напряжения +5В или 0В. Собственно именно этим и занимается наша прошивка. А вот мы то и заставляем эти устройства, при помощи различных команд выводить на нужные НАМ ножки то или иное напряжение.

Итак на настоящий момент мы имеем: Спаянные схемы, hex-файл прошивки для микроконтроллера и мы посмотрели как этот hex-файл работает, правда в виртуальном устройстве.

Нам осталось: залить прошивку в микроконтроллер и сделать программу для управления нашим устройством с компьютера.

 

ДАЛЕЕ



Используются технологии uCoz