Hi
For example, my last project led rgb 32x16 panel + ATMega64.
When I push r0 and r1 registers on stack in interrupt handling everything is ok.
Code: Select all
program panel32x16rgb;
{ Declarations section }
var
R1_pin: sbit at portc5_bit;
G1_pin: sbit at portc6_bit;
B1_pin: sbit at portc7_bit;
R2_pin: sbit at portg2_bit;
G2_pin: sbit at porta7_bit;
B2_pin: sbit at porta6_bit;
A_pin : sbit at porta5_bit;
B_pin : sbit at porta4_bit;
C_pin : sbit at porta3_bit;
D_pin : sbit at portc4_bit;
CLK_pin: sbit at porta2_bit;
LAT_pin: sbit at porta1_bit;
OE_pin : sbit at porta0_bit;
R1_pin_direction: sbit at ddc5_bit;
G1_pin_direction: sbit at ddc6_bit;
B1_pin_direction: sbit at ddc7_bit;
R2_pin_direction: sbit at ddg2_bit;
G2_pin_direction: sbit at dda7_bit;
B2_pin_direction: sbit at dda6_bit;
A_pin_direction : sbit at dda5_bit;
B_pin_direction : sbit at dda4_bit;
C_pin_direction : sbit at dda3_bit;
D_pin_direction : sbit at ddc4_bit;
CLK_pin_direction: sbit at dda2_bit;
LAT_pin_direction: sbit at dda1_bit;
OE_pin_direction : sbit at dda0_bit;
scan: byte;
screen: array [0..191] of byte;
Procedure Reset();
begin
R1_pin_direction:=1;
G1_pin_direction:=1;
B1_pin_direction:=1;
R2_pin_direction:=1;
G2_pin_direction:=1;
B2_pin_direction:=1;
A_pin_direction :=1;
B_pin_direction :=1;
C_pin_direction :=1;
D_pin_direction :=1;
CLK_pin_direction:=1;
LAT_pin_direction:=1;
OE_pin_direction :=1;
R1_pin:=0;
G1_pin:=0;
B1_pin:=0;
R2_pin:=0;
G2_pin:=0;
B2_pin:=0;
A_pin :=0;
B_pin :=0;
C_pin :=0;
D_pin :=0;
CLK_pin:=0;
LAT_pin:=0;
OE_pin :=1;
tccr0:= %00000101; //clk/8//32/64/128/256/1024
tcnt0:=0;
toie0_bit:=1;
sreg_i_bit:=1;
end;
procedure T0_Int(); iv IVT_ADDR_TIMER0_OVF; ics ICS_AUTO;
var _n,_i,tmp_scan,tmp_n: byte;
begin
asm
push r0;
push r1;
end;
if scan<1 then /// 1/2
begin
inc (scan);
tmp_scan:=3;
end
else
begin
scan:=0;
tmp_scan:=0;
end;
for _n:=0 to 7 do //3
begin
tmp_n:=(_n*12)+tmp_scan;
for _i:=0 to 7 do
begin
B1_pin:= (screen[tmp_n +0] shr _i) and 1;
G1_pin:= (screen[tmp_n +1] shr _i) and 1;
R1_pin:= (screen[tmp_n +2] shr _i) and 1;
B2_pin:= (screen[tmp_n +96] shr _i) and 1;
G2_pin:= (screen[tmp_n +97] shr _i) and 1;
R2_pin:= (screen[tmp_n +98] shr _i) and 1;
CLK_pin:=1;
CLK_pin:=0;
end;
for _i:=7 downto 0 do
begin
B1_pin:= (screen[tmp_n +6] shr _i) and 1;
G1_pin:= (screen[tmp_n +7] shr _i) and 1;
R1_pin:= (screen[tmp_n +8] shr _i) and 1;
B2_pin:= (screen[tmp_n +102] shr _i) and 1;
G2_pin:= (screen[tmp_n+103] shr _i) and 1;
R2_pin:= (screen[tmp_n+104] shr _i) and 1;
CLK_pin:=1;
CLK_pin:=0;
end;
end;
OE_pin:=1;
A_pin:=1;
B_pin:=1;
C_pin:=1;
D_pin:=1;
case scan of
0:A_pin:=0;
1:B_pin:=0;
2:C_pin:=0;
3:D_pin:=0;
end;
LAT_pin:=1;
LAT_pin:=0;
OE_pin:=0;
asm
pop r1;
pop r0;
end;
end;
Procedure set_pix(x_pos,y_pos,_red,_green,_blue:byte);
var _bit_nr:byte;
_byte_nr:byte;
begin
_bit_nr:= 7- (x_pos mod 8);
if y_pos >=8 then
begin
y_pos:=y_pos-8;
_byte_nr:=((x_pos div 8) *24) + (y_pos*3)+96;
end
else
_byte_nr:=((x_pos div 8) *24) + (y_pos*3);
if _red=0 then
clearbit(screen[_byte_nr+0],_bit_nr)
else
setbit(screen[_byte_nr+0],_bit_nr);
if _green=0 then
clearbit(screen[_byte_nr+1],_bit_nr)
else
setbit(screen[_byte_nr+1],_bit_nr);
if _blue=0 then
clearbit(screen[_byte_nr+2],_bit_nr)
else
setbit(screen[_byte_nr+2],_bit_nr);
end;
Procedure set_screen(_red: byte;_green:byte;_blue:byte);
var
_n,tmp_r,tmp_g,tmp_b: byte;
begin
tmp_r:=0;
tmp_g:=0;
tmp_b:=0;
if _red=1 then
tmp_r:=0xff;
if _green=1 then
tmp_g:=0xff;
if _blue=1 then
tmp_b:=0xff;
for _n:=0 to 63 do
begin
screen[(_n*3)+0]:=tmp_r;
screen[(_n*3)+1]:=tmp_g;
screen[(_n*3)+2]:=tmp_b;
end;
end;
begin
{ Main program }
Reset;
set_screen(0,0,0);
while true do
begin
set_pix(5,5,1,1,1);
set_pix(6,6,1,0,0);
set_pix(7,7,0,1,0);
set_pix(8,8,0,0,1);
set_pix(9,9,1,1,0);
set_pix(10,10,1,0,1);
set_pix(11,11,0,1,1);
end;
end.
ASM FILE
Code: Select all
_T0_Int:
PUSH R30
PUSH R31
PUSH R27
IN R27, SREG+0
PUSH R27
PUSH R28
PUSH R29
IN R28, SPL+0
IN R29, SPL+1
SBIW R28, 2
OUT SPL+0, R28
OUT SPL+1, R29
ADIW R28, 1
;panel32x16rgb.mpas,84 :: begin
;panel32x16rgb.mpas,86 :: push r0;
PUSH R0
;panel32x16rgb.mpas,87 :: push r1;
PUSH R1
;panel32x16rgb.mpas,91 :: if scan<1 then /// 1/2
LDS R16, _scan+0
CPI R16, 1
BRLO L__T0_Int72
JMP L__T0_Int3
L__T0_Int72:
;panel32x16rgb.mpas,93 :: inc (scan);
LDS R16, _scan+0
SUBI R16, 255
STS _scan+0, R16
;panel32x16rgb.mpas,94 :: tmp_scan:=3;
; tmp_scan start address is: 20 (R20)
LDI R20, 3
;panel32x16rgb.mpas,95 :: end
; tmp_scan end address is: 20 (R20)
JMP L__T0_Int4
;panel32x16rgb.mpas,96 :: else
L__T0_Int3:
;panel32x16rgb.mpas,98 :: scan:=0;
LDI R27, 0
STS _scan+0, R27
;panel32x16rgb.mpas,99 :: tmp_scan:=0;
; tmp_scan start address is: 20 (R20)
LDI R20, 0
; tmp_scan end address is: 20 (R20)
;panel32x16rgb.mpas,100 :: end;
L__T0_Int4:
;panel32x16rgb.mpas,103 :: for _n:=0 to 7 do //3
; tmp_scan start address is: 20 (R20)
; _n start address is: 21 (R21)
LDI R21, 0
; tmp_scan end address is: 20 (R20)
; _n end address is: 21 (R21)
L__T0_Int6:
;panel32x16rgb.mpas,105 :: tmp_n:=(_n*12)+tmp_scan;
; _n start address is: 21 (R21)
; tmp_scan start address is: 20 (R20)
LDI R16, 12
MUL R21, R16
MOV R16, R0
ADD R16, R20
STD Y+1, R16
;panel32x16rgb.mpas,106 :: for _i:=0 to 7 do
LDI R27, 0
STD Y+0, R27
Best regards
G.B.