Светодиодное сердце на микроконтроллере 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-й вывод//порта Bincl(PortB,1);//Подтянуть к нулю 0-й вывод//порта Bexcl(PortB,0);end SysLED_Red;
//Индикация зеленымprocedure SysLED_Green;begin//Подтянуть к единице 0-й вывод//порта Bincl(PortB,0);//Подтянуть к нулю 1-й вывод//порта Bexcl(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 of0: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)thenPortD := $00;ShiftCounter := 0;PortDataA := $01;PortA := PortDataA;inc(ShiftCounter);
elsif (ShiftCounter < 8) and (ShiftCounter > 0)thenPortDataA := PortDataA rol 1;PortA := PortDataA;inc(ShiftCounter);
elsif (ShiftCounter = 8)thenPortA := $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)thenPortC := $00;PortDataD := $01;PortD := PortDataD;inc(ShiftCounter);
elsif (ShiftCounter > 16) and (ShiftCounter < 18)thenPortDataD := PortDataD rol 1;PortD := PortDataD;inc(ShiftCounter);endif;
|3:inc(TimerTickCounter);
if ( ( TimerTickCounter mod TimeCount ) = 0 )then
inc(St_Level);
if ( St_Level >= 16)thenSt_Level := 1;endif;
endif;
case St_Level of0: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 >= 8thenOutBitsIndex := 0;endif;|endcase;
end;{--------------------------------------------------------------}{ Main Program }{$IDATA}//Код выполняемый сразу после Reset'abegin//Инициализировать порты ввода/вывода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.
