Files
oberon-07-compiler/samples/MSP430/Example3.ob07
T

148 lines
3.3 KiB
Plaintext

(*
Пример для LaunchPad MSP-EXP430G2 Rev1.5
Зеленый светодиод мигает по сигналам от таймера A,
красный - по сигналам от сторожевого таймера в интервальном режиме
*)
MODULE Example3;
IMPORT SYSTEM, RTL;
CONST
REDLED = 0;
GREENLED = 6;
P1OUT = 21H;
P1DIR = 22H;
(* регистры сторожевого таймера *)
WDTCTL = 0120H;
IE1 = 0000H;
IFG1 = 0002H;
(* биты регистра WDTCTL *)
WDTIS0 = 0;
WDTIS1 = 1;
WDTSSEL = 2;
WDTCNTCL = 3;
WDTTMSEL = 4;
WDTNMI = 5;
WDTNMIES = 6;
WDTHOLD = 7;
(* биты регистра IE1 *)
WDTIE = 0;
NMIIE = 4;
(* биты регистра IFG1 *)
WDTIFG = 0;
NMIIFG = 4;
(* ключ защиты сторожевого таймера *)
WDTPW = 5A00H;
(* регистры таймера A *)
TACTL = 0160H;
TAR = 0170H;
TACCTL0 = 0162H;
TACCR0 = 0172H;
(* биты регистра TACTL *)
TAIFG = 0;
TAIE = 1;
TACLR = 2;
MC0 = 4;
MC1 = 5;
ID0 = 6;
ID1 = 7;
TASSEL0 = 8;
TASSEL1 = 9;
(* биты регистра TACCTL0 *)
CCIE = 4;
CAP = 8;
PROCEDURE set_bit (mem, bit: INTEGER);
VAR
b: BYTE;
BEGIN
SYSTEM.GET(mem, b);
SYSTEM.PUT8(mem, BITS(b) + {bit})
END set_bit;
PROCEDURE inv_bit (mem, bit: INTEGER);
VAR
b: BYTE;
BEGIN
SYSTEM.GET(mem, b);
SYSTEM.PUT8(mem, BITS(b) / {bit})
END inv_bit;
(*
обработчик прерываний
n - номер прерывания в векторе прерываний:
адрес номер
0FFFEH 0
0FFFCH 1
0FFFAH 2
...
0FFC0H 31
sr, pc - значение регистров SR и PC в момент прерывания
*)
PROCEDURE int (n, sr, pc: INTEGER);
VAR
x: SET;
BEGIN
IF n = 7 THEN (* прерывание от таймера A - #7 *)
SYSTEM.GET(TACTL, x);
IF TAIFG IN x THEN (* прерывание было *)
inv_bit(P1OUT, GREENLED);
(* сбросить флаг прерывания и обновить регистр TACTL *)
SYSTEM.PUT(TACTL, x - {TAIFG})
END
ELSIF n = 5 THEN (* прерывание от сторожевого таймера - #5 *)
inv_bit(P1OUT, REDLED)
END
END int;
PROCEDURE main;
BEGIN
(* инициализация регистра P1DIR *)
SYSTEM.PUT8(P1DIR, {REDLED, GREENLED});
(* начальное состояние светодиодов - включены *)
set_bit(P1OUT, GREENLED);
set_bit(P1OUT, REDLED);
RTL.SetInt(int); (* назначить обработчик прерываний *)
SYSTEM.CODE(0D232H); (* BIS #8, SR; EINT; разрешить прерывания *)
(* инициализация регистров таймера A *)
SYSTEM.PUT(TAR, 0);
SYSTEM.PUT(TACCTL0, {CCIE, CAP});
SYSTEM.PUT(TACCR0, 1500);
SYSTEM.PUT(TACTL, {TAIE, MC0, TASSEL0});
(* инициализация регистров сторожевого таймера *)
set_bit(IE1, WDTIE);
SYSTEM.PUT(WDTCTL, WDTPW + ORD({WDTIS1, WDTSSEL, WDTCNTCL, WDTTMSEL}))
END main;
BEGIN
main
END Example3.