...

суббота, 26 апреля 2014 г.

Светодиодное сердце на микроконтроллере Atmega16, или программирование AVR на языке Pascal

program Love_Machine;

{$NOSHADOW}

{ $WG} {global Warnings off}


//Контроллер ATmega16

//Напряжения питания 3.3 В

Device = mega16, VCC=3.3;

{ $BOOTRST $01C00} {Reset Jump to $01C00}


Import SysTick, TickTimer;


From System Import LongWord;


Define

//Рабочая частота 1 MГц (Внутренняя RC-цепочка)

ProcClock = 1000000; {Hertz}

SysTick = 10; {msec}

StackSize = $0032, iData;

FrameSize = $0032, iData;


TickTimer = Timer1;

//Задержка переключения системного

//в милисекундах

Define_USR SysLED_Delay = 500;


Implementation


{$IDATA}


{--------------------------------------------------------------}

{ Type Declarations }


type


{--------------------------------------------------------------}

{ Const Declarations }


const


TimeCount: Byte = 70;


MOutBits_L1:array[0..7] of Byte = (


$00,

$00,

$00,

$00,


$00,

$00,

$00,

$ff

);


MOutBits_L2:array[0..7] of Byte = (


$00,

$00,

$00,

$00,


$00,

$00,

$ff,

$ff

);


MOutBits_L3:array[0..7] of Byte = (

$00,

$00,

$00,

$00,


$00,

$ff,

$ff,

$ff

);


MOutBits_L4:array[0..7] of Byte = (


$00,

$00,

$00,

$00,


$ff,

$ff,

$ff,

$ff

);


MOutBits_L5:array[0..7] of Byte = (


$00,

$00,

$00,

$ff,


$ff,

$ff,

$ff,

$ff

);


MOutBits_L6:array[0..7] of Byte = (


$00,

$00,

$ff,

$ff,


$ff,

$ff,

$ff,

$ff

);


MOutBits_L7:array[0..7] of Byte = (


$00,

$ff,

$ff,

$ff,


$ff,

$ff,

$ff,

$ff

);


{*

MOutBits: array[0..24] of LongWord =(

%010000000000000101,

%010000000000000101,

%010000000000000101,

%010000000000000101,

%010000000000000101,


%010000000000000001,

%010000000000000001,

%010000000000000001,

%010000000000000001,

%010000000000000001,


%010000000000000001,

%010000000000000001,

%010000000000000001,

%010000000000000001,

%010000000000000001,


%000000000000000101,

%000000000000000101,

%000000000000000101,

%000000000000000101,

%000000000000000101,


%000000000000000001,

%000000000000000001,

%000000000000000001,

%000000000000000001,

%000000000000000001


);

*}


{--------------------------------------------------------------}

{ Var Declarations }

{$IDATA}

var


OutBitsIndex: Byte;


St_Level: Byte;

St_Timer: Byte;


PortDataA: Byte;

PortDataC: Byte;

PortDataD: Byte;

ShiftCounter: Byte;


TimerTickCounter: LongWord;


{--------------------------------------------------------------}

{ functions }


//Функци инициализации

//портов ввода-вывода

procedure InitPorts;

begin

//Первый сегмент сердца ( 8 светодиодов)

//Порт на вывод

DDRA:= %11111111;

//Записать нули

PortA:= %00000000;


//Второй сегмент сердца

//Порт на вывод

DDRC:= %11111111;

//Записать нули

PortC:= %00000000;


//Третий сегмент сердца ()

//Два вывода порта на вывод

DDRD:= %00000011;

//Записать нули

PortD:= %00000000;


//системный двухцветный светодиод (2 ножки)

//Порт на вывод

DDRB:= %00000011;


end InitPorts;


//Индикация красным

procedure SysLED_Red;

begin

//Подтянуть к единице 1-й вывод

//порта B

incl(PortB,1);

//Подтянуть к нулю 0-й вывод

//порта B

excl(PortB,0);

end SysLED_Red;


//Индикация зеленым

procedure SysLED_Green;

begin

//Подтянуть к единице 0-й вывод

//порта B

incl(PortB,0);

//Подтянуть к нулю 1-й вывод

//порта B

excl(PortB,1);

end SysLED_Green;


//Переключение индикации

//зеленный-красный

procedure SysLED_SwColor;

begin

//Зажечь красный

SysLED_Red;

//Задержка

mDelay(Word(SysLED_Delay));

//Зажечь зеленый

SysLED_Green;

//Задержка

mDelay(Word(SysLED_Delay));

end SysLED_SwColor;


//Обработчик прерывания программного таймера

procedure onTickTimer; //(SaveAllRegs);

begin

//SysLED_SwColor;

case St_Timer of

0:

toggle(PortA,0);

toggle(PortA,1);

toggle(PortA,2);

toggle(PortA,3);

toggle(PortA,4);

toggle(PortA,5);

toggle(PortA,6);

toggle(PortA,7);


toggle(PortC,0);

toggle(PortC,1);

toggle(PortC,2);

toggle(PortC,3);

toggle(PortC,4);

toggle(PortC,5);

toggle(PortC,6);

toggle(PortC,7);


toggle(PortD,0);

toggle(PortD,1);

|

1:

PortDataA := PortDataA ror 1;

PortA := PortDataA;

PortDataC := PortDataC ror 1;

PortC := PortDataC;

PortDataD := PortDataD ror 1;

PortD := PortDataD;

|

2:


// PortDataC := PortDataC ror 1;

// PortC := PortDataC;

// PortDataD := PortDataD ror 1;

// PortD := PortDataD;


if (ShiftCounter = 0) or (ShiftCounter = 18)

then

PortD := $00;

ShiftCounter := 0;

PortDataA := $01;

PortA := PortDataA;

inc(ShiftCounter);


elsif (ShiftCounter < 8) and (ShiftCounter > 0)

then

PortDataA := PortDataA rol 1;

PortA := PortDataA;

inc(ShiftCounter);


elsif (ShiftCounter = 8)

then

PortA := $00;

PortDataC := $01;

PortC := PortDataC;

inc(ShiftCounter);


elsif (ShiftCounter > 8) and (ShiftCounter < 16)

then


PortDataC := PortDataC rol 1;

PortC := PortDataC;

inc(ShiftCounter);


elsif (ShiftCounter = 16)

then

PortC := $00;

PortDataD := $01;

PortD := PortDataD;

inc(ShiftCounter);


elsif (ShiftCounter > 16) and (ShiftCounter < 18)

then

PortDataD := PortDataD rol 1;

PortD := PortDataD;

inc(ShiftCounter);

endif;


|

3:

inc(TimerTickCounter);


if ( ( TimerTickCounter mod TimeCount ) = 0 )

then


inc(St_Level);


if ( St_Level >= 16)

then

St_Level := 1;

endif;


endif;


case St_Level of

0:

PortA := $00;

PortC := $00;

PortD := $00;

|

1:

PortA := MOutBits_L1[OutBitsIndex];

PortC := MOutBits_L1[OutBitsIndex];

PortD := MOutBits_L1[OutBitsIndex];

|

2:

PortA := MOutBits_L2[OutBitsIndex];

PortC := MOutBits_L2[OutBitsIndex];

PortD := MOutBits_L2[OutBitsIndex];

|

3:

PortA := MOutBits_L3[OutBitsIndex];

PortC := MOutBits_L3[OutBitsIndex];

PortD := MOutBits_L3[OutBitsIndex];

|

4:

PortA := MOutBits_L4[OutBitsIndex];

PortC := MOutBits_L4[OutBitsIndex];

PortD := MOutBits_L4[OutBitsIndex];

|

5:

PortA := MOutBits_L5[OutBitsIndex];

PortC := MOutBits_L5[OutBitsIndex];

PortD := MOutBits_L5[OutBitsIndex];

|

6:

PortA := MOutBits_L6[OutBitsIndex];

PortC := MOutBits_L6[OutBitsIndex];

PortD := MOutBits_L6[OutBitsIndex];

|

7:

PortA := MOutBits_L7[OutBitsIndex];

PortC := MOutBits_L7[OutBitsIndex];

PortD := MOutBits_L7[OutBitsIndex];

|

8:

PortA := $FF;

PortC := $FF;

PortD := $FF;

|

9:

PortA := MOutBits_L7[OutBitsIndex];

PortC := MOutBits_L7[OutBitsIndex];

PortD := MOutBits_L7[OutBitsIndex];

|

10:

PortA := MOutBits_L6[OutBitsIndex];

PortC := MOutBits_L6[OutBitsIndex];

PortD := MOutBits_L6[OutBitsIndex];

|

11:

PortA := MOutBits_L5[OutBitsIndex];

PortC := MOutBits_L5[OutBitsIndex];

PortD := MOutBits_L5[OutBitsIndex];

|

12:

PortA := MOutBits_L4[OutBitsIndex];

PortC := MOutBits_L4[OutBitsIndex];

PortD := MOutBits_L4[OutBitsIndex];

|

13:

PortA := MOutBits_L3[OutBitsIndex];

PortC := MOutBits_L3[OutBitsIndex];

PortD := MOutBits_L3[OutBitsIndex];

|

14:

PortA := MOutBits_L2[OutBitsIndex];

PortC := MOutBits_L2[OutBitsIndex];

PortD := MOutBits_L2[OutBitsIndex];

|

15:

PortA := MOutBits_L1[OutBitsIndex];

PortC := MOutBits_L1[OutBitsIndex];

PortD := MOutBits_L1[OutBitsIndex];

|

endcase;


inc( OutBitsIndex );


if OutBitsIndex >= 8

then

OutBitsIndex := 0;

endif;

|

endcase;


end;

{--------------------------------------------------------------}

{ Main Program }

{$IDATA}

//Код выполняемый сразу после Reset'a

begin

//Инициализировать порты ввода/вывода

InitPorts;

//Настроить программный таймер

// Период = 1 мс

// Частота = 1 кГц

TickTimerTime(1000);

// Запустить таймер

TickTimerStart;


// Остановить таймер

TickTimerStop;


//Разрешить прерывания

EnableInts;


{

//Последовательное включение

//светодиодов c секундным интервалом

incl(PortA,0);

mDelay(1000);

incl(PortA,1);

mDelay(1000);

incl(PortA,2);

mDelay(1000);

incl(PortA,3);

mDelay(1000);

incl(PortA,4);

mDelay(1000);

incl(PortA,5);

mDelay(1000);

incl(PortA,6);

mDelay(1000);

incl(PortA,7);

mDelay(1000);

incl(PortC,0);

mDelay(1000);

incl(PortC,1);

mDelay(1000);

incl(PortC,2);

mDelay(1000);

incl(PortC,3);

mDelay(1000);

incl(PortC,4);

mDelay(1000);

incl(PortC,5);

mDelay(1000);

incl(PortC,6);

mDelay(1000);

incl(PortC,7);

mDelay(1000);

incl(PortD,0);

mDelay(1000);

incl(PortD,1);

mDelay(1000);


//Переход в первый режим таймера (Toggle)

St_Timer := 0;


//Период 200 мс

TickTimerTime(200000);

// Запустить таймер

TickTimerStart;

//Задержка 2 секунды

mDelay(2000);


//Период 150 мс

TickTimerTime(150000);

// Запустить таймер

TickTimerStart;

mDelay(2000);


// Остановить таймер

TickTimerStop;

//Период 100 мс

TickTimerTime(100000);

// Запустить таймер

TickTimerStart;

//Задержка 2 секунды

mDelay(2000);


// Остановить таймер

TickTimerStop;

//Период 50 мс

TickTimerTime(50000);

// Запустить таймер

TickTimerStart;

//Задержка 2 секунды

mDelay(2000);


// Остановить таймер

TickTimerStop;

//Период 25 мс

TickTimerTime(25000);

// Запустить таймер

TickTimerStart;

//Задержка 2 секунды

mDelay(2000);


}

// Остановить таймер

TickTimerStop;


PortDataA := $AA;

PortDataC := $AA;

PortDataD := $AA;


//Переход во второй режим (Shift Inv)

St_Timer := 1;


//Период 200 мс

TickTimerTime(200000);

// Запустить таймер

TickTimerStart;


//Задержка 5 секунд

mDelay(2000);


// Остановить таймер

TickTimerStop;


PortA := $00;

PortC := $00;

PortD := $00;


PortDataA := $00;

PortDataC := $00;

PortDataD := $00;


ShiftCounter := 0;


//Переход во второй режим (Shift One)

St_Timer := 2;


//Период 200 мс

TickTimerTime(200000);

// Запустить таймер

TickTimerStart;


//Задержка 5 секунд

mDelay(5000);


// Остановить таймер

TickTimerStop;

//Переход в третий режим таймера (PWM)

St_Timer := 3;

// Частота = 1 кГц

TickTimerTime(1000);

// Запустить таймер

TickTimerStart;


//Основной цикл

loop


//inc(St_Level);

//if ( St_Level >= 9)

//then

// St_Level := 0;

//endif;

//mDelay(200);


//SysLED_SwColor;


// incl(PortC,1);

// mDelay(1);

endloop;

end Love_Machine.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий