发表于:2009/1/17 12:09:13
#0楼
这是本人做的一个机箱温控的一段程序。是plm51的代码,主频12mhz。
$db pw(94) rom(large) co ot(3) sb
mcs51os: do;
$nolist
$include(\plm51\reg51.dcl)
$include(\plm51\lit.dcl)
$include(ds18b20.dcl)
$list
dcl system$err literally 0;
dcl hard$err literally 1;
dcl command$err literally 2;
dcl time$err literally 3;
dcl date$err literally 4;
dcl temperaturelimit literally 40;
/*=========================================================================*/
dcl copyright(*) byte con
(
copyright(c) 2003 by lidongfa.all right reserved
);
dcl version byte con(00h);
/*=========================================================================*/
/* */
/* system clock interrupt serve program. */
/* use the 1# timer and 1# register. */
/* */
/*=========================================================================*/
dcl timer0cnt word con(1000);
dcl char$img(31) byte con
(
/* edga fbcp */
/* 0 */ 0010$0001b, /* 0 */
/* 1 */ 1111$1001b, /* 1 */
/* 2 */ 0000$1011b, /* 2 */
/* 3 */ 1000$1001b, /* 3 */
/* 4 */ 1101$0001b, /* 4 */
/* 5 */ 1000$0101b, /* 5 */
/* 6 */ 0000$0101b, /* 6 */
/* 7 */ 1110$1001b, /* 7 */
/* 8 */ 0000$0001b, /* 8 */
/* 9 */ 1000$0001b, /* 9 */
/* */ 1111$1111b /* 10 */
);
dcl disp$buf(2) byte;
dcl (disp$buf$ptr) byte;
dcl led1 literally p32;
dcl led2 literally p33;
dcl tmdat literally p35;
dcl fanout literally p37;
dcl fanouttmp bit;
dcl firstread bit;
dcl fanoutdelay byte;
dcl temperature word; /* 读取后温度值存于temperature中 */
dcl temp word;
dcl second word;
dcl msecond$cnt word;
display$temp:procedure pub;
temp = temperature / 16;
disp$buf(0) = char$img(temp mod 10);
disp$buf(1) = char$img((temp / 10) mod 10);
end display$temp;
system$clock:procedure using 1;
msecond$cnt = msecond$cnt + 1;
if msecond$cnt mod 4 = 0 then
do;
led1 = 1;
led2 = 1;
p1 = disp$buf(disp$buf$ptr);
if disp$buf$ptr = 0 then
led1 = 0;
else if disp$buf$ptr = 1 then
led2 = 0;
disp$buf$ptr = disp$buf$ptr + 1;
if disp$buf$ptr >= 2 then
disp$buf$ptr = 0;
end;
if msecond$cnt
if fanoutdelay > 0 then
fanoutdelay = fanoutdelay - 1;
end system$clock;
/*=========================================================================*/
clk$inter: procedure interrupt 1 using 1;
tr0 = 0;
th0 = high(-timer0cnt + 34);
tl0 = low(-timer0cnt + 34);
tr0 = 1;
call system$clock;
end clk$inter;
/* end of system clock interrupt serve program. */
/*=======================================================================*/
sys$reset:procedure;
dcl i byte;
disable;
msecond$cnt = 0;
second = 0;
th0 = high(-timer0cnt);
tl0 = low(-timer0cnt);
ip = 0000$0010b;
ie = 0000$0010b;
tmod = 0001$0001b;
tcon = 0001$0000b;
pcon = 0;
p1 = 0ffh;
p3 = 0ffh;
disp$buf$ptr = 0;
disp$buf(0) = char$img(10);
disp$buf(1) = char$img(10);
temperature = 0;
firstread = 1;
fanoutdelay = 20;
enable;
end sys$reset;
/* 延时部分 */
dmsec:procedure(tm) pub;
dcl tm word;
dcl i byte;
do while (tm > 0);
i = 150;
do while (i > 0);
i = i - 1;
end;
tm = tm - 1;
end;
end dmsec;
/* 发送复位 */
tmreset:procedure pub;
dcl i byte;
tmdat = 0;
i = 150;
do while(i > 0);
i = i - 1; /* 延时 900 us(11.0592mhz时) */
end;
tmdat = 1;
i = 5;
do while (i > 0);
i = i - 1;
end;
end tmreset;
/* 判断ds1820是否存在的子程序。最好不要用,因为当器件不存在时将会进入死循环 */
/* 等待存在脉冲 */
/* 判断器件是否存在 */
tmpre:procedure pub;
dcl i byte;
do while (tmdat);
end;
do while (not tmdat);
end;
i = 7;
do while (i > 0);
i = i - 1;
end;
end tmpre;
/* 读一位 */
tmrbit:procedure bit pub;
dcl i byte;
dcl dat bit;
tmdat = 0;
i = i + 1;
i = i + 1;
tmdat = 1;
i = 2;
do while (i > 0);
i = i - 1; /* 延时 */
end;
dat = tmdat;
i = 10;
do while (i > 0);
i = i - 1; /* 延时 */
end;
return (dat);
end tmrbit;
/* 读一个字节 */
tmrbyte:procedure byte pub;
dcl (j,dat) byte;
dcl (i) byte;
dat = 0;
do i = 1 to 8;
j = expand(tmrbit);
dat = shl(j,7) or shr(dat,1);
end;
return (dat);
end tmrbyte;
/* 写一个字节 */
tmwbyte:procedure(dat) pub;
dcl dat byte;
dcl testb bit;
dcl (i,j) byte;
do j = 1 to 8;
testb = boolean(dat and 1);
dat = shr(dat,1);
if testb = 1 then
do;
tmdat = 0; /* 写1 */
i = i + 1;
i = i + 1;
tmdat = 1;
i = 10;
do while (i > 0);
i = i - 1;
end;
end;
else
do;
tmdat = 0; /* 写0 */
i = 10;
do while (i > 0);
i = i - 1;
end;
tmdat = 1;
i = i + 1;
i = i + 1;
end;
end;
end tmwbyte;
/* 发送ds1820 开始转换 */
tmstart :procedure pub;
call tmreset; /* 复位 */
/* call tmpre; */ /* 等待存在脉冲 */
call dmsec (1); /* 延时 */
call tmwbyte (0cch); /* 跳过序列号命令 */
call tmwbyte (044h); /* 发转换命令 44h */
end tmstart;
/* 读取温度 */
tmrtemp :procedure pub;
dcl (a,b) byte;
call tmreset; /* 复位 */
/* call tmpre; */ /* 等待存在脉冲 */
call dmsec (1); /* 延时 */
call tmwbyte (0cch); /* 跳过序列号命令 */
call tmwbyte (0beh); /* 发送读取命令 */
a = tmrbyte; /* 读取低位温度 */
b = tmrbyte; /* 读取高位温度 */
temp = b * 256;
temp = temp + a;
if firstread = 1 then
do;
firstread = 0;
temperature = temp;
end;
else
do;
temperature = (temperature * 9 + temp) / 10;
end;
end tmrtemp;
/* the program entry point */
dcl cnt byte;
call sys$reset;
cnt = 0;
mainloop:
/* 这段是调试代码 */
/*
call dmsec (1000);
disp$buf(0) = char$img(cnt);
disp$buf(1) = char$img(cnt);
cnt = cnt + 1;
if cnt >= 10 then
do;
cnt = 0;
end;
if fanouttmp = 1 then
do;
fanouttmp = 0;
fanout = fanouttmp;
end;
else
do;
fanouttmp = 1;
fanout = fanouttmp;
end;
*/
/* 启动ds18b20 */
disable;
call tmstart;
enable;
call dmsec (1200);
/* 读取温度,执行完毕温度将存于temperature中 */
disable;
call tmrtemp;
enable;
temp = temperature / 16;
if fanoutdelay = 0 then
do;
if temp >= temperaturelimit then
do;
fanouttmp = 0;
fanout = fanouttmp;
fanoutdelay = 20;
end;
else if temp
call display$temp;
goto mainloop;
end mcs51os;
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=74990&Name=lidongfa
$db pw(94) rom(large) co ot(3) sb
mcs51os: do;
$nolist
$include(\plm51\reg51.dcl)
$include(\plm51\lit.dcl)
$include(ds18b20.dcl)
$list
dcl system$err literally 0;
dcl hard$err literally 1;
dcl command$err literally 2;
dcl time$err literally 3;
dcl date$err literally 4;
dcl temperaturelimit literally 40;
/*=========================================================================*/
dcl copyright(*) byte con
(
copyright(c) 2003 by lidongfa.all right reserved
);
dcl version byte con(00h);
/*=========================================================================*/
/* */
/* system clock interrupt serve program. */
/* use the 1# timer and 1# register. */
/* */
/*=========================================================================*/
dcl timer0cnt word con(1000);
dcl char$img(31) byte con
(
/* edga fbcp */
/* 0 */ 0010$0001b, /* 0 */
/* 1 */ 1111$1001b, /* 1 */
/* 2 */ 0000$1011b, /* 2 */
/* 3 */ 1000$1001b, /* 3 */
/* 4 */ 1101$0001b, /* 4 */
/* 5 */ 1000$0101b, /* 5 */
/* 6 */ 0000$0101b, /* 6 */
/* 7 */ 1110$1001b, /* 7 */
/* 8 */ 0000$0001b, /* 8 */
/* 9 */ 1000$0001b, /* 9 */
/* */ 1111$1111b /* 10 */
);
dcl disp$buf(2) byte;
dcl (disp$buf$ptr) byte;
dcl led1 literally p32;
dcl led2 literally p33;
dcl tmdat literally p35;
dcl fanout literally p37;
dcl fanouttmp bit;
dcl firstread bit;
dcl fanoutdelay byte;
dcl temperature word; /* 读取后温度值存于temperature中 */
dcl temp word;
dcl second word;
dcl msecond$cnt word;
display$temp:procedure pub;
temp = temperature / 16;
disp$buf(0) = char$img(temp mod 10);
disp$buf(1) = char$img((temp / 10) mod 10);
end display$temp;
system$clock:procedure using 1;
msecond$cnt = msecond$cnt + 1;
if msecond$cnt mod 4 = 0 then
do;
led1 = 1;
led2 = 1;
p1 = disp$buf(disp$buf$ptr);
if disp$buf$ptr = 0 then
led1 = 0;
else if disp$buf$ptr = 1 then
led2 = 0;
disp$buf$ptr = disp$buf$ptr + 1;
if disp$buf$ptr >= 2 then
disp$buf$ptr = 0;
end;
if msecond$cnt
if fanoutdelay > 0 then
fanoutdelay = fanoutdelay - 1;
end system$clock;
/*=========================================================================*/
clk$inter: procedure interrupt 1 using 1;
tr0 = 0;
th0 = high(-timer0cnt + 34);
tl0 = low(-timer0cnt + 34);
tr0 = 1;
call system$clock;
end clk$inter;
/* end of system clock interrupt serve program. */
/*=======================================================================*/
sys$reset:procedure;
dcl i byte;
disable;
msecond$cnt = 0;
second = 0;
th0 = high(-timer0cnt);
tl0 = low(-timer0cnt);
ip = 0000$0010b;
ie = 0000$0010b;
tmod = 0001$0001b;
tcon = 0001$0000b;
pcon = 0;
p1 = 0ffh;
p3 = 0ffh;
disp$buf$ptr = 0;
disp$buf(0) = char$img(10);
disp$buf(1) = char$img(10);
temperature = 0;
firstread = 1;
fanoutdelay = 20;
enable;
end sys$reset;
/* 延时部分 */
dmsec:procedure(tm) pub;
dcl tm word;
dcl i byte;
do while (tm > 0);
i = 150;
do while (i > 0);
i = i - 1;
end;
tm = tm - 1;
end;
end dmsec;
/* 发送复位 */
tmreset:procedure pub;
dcl i byte;
tmdat = 0;
i = 150;
do while(i > 0);
i = i - 1; /* 延时 900 us(11.0592mhz时) */
end;
tmdat = 1;
i = 5;
do while (i > 0);
i = i - 1;
end;
end tmreset;
/* 判断ds1820是否存在的子程序。最好不要用,因为当器件不存在时将会进入死循环 */
/* 等待存在脉冲 */
/* 判断器件是否存在 */
tmpre:procedure pub;
dcl i byte;
do while (tmdat);
end;
do while (not tmdat);
end;
i = 7;
do while (i > 0);
i = i - 1;
end;
end tmpre;
/* 读一位 */
tmrbit:procedure bit pub;
dcl i byte;
dcl dat bit;
tmdat = 0;
i = i + 1;
i = i + 1;
tmdat = 1;
i = 2;
do while (i > 0);
i = i - 1; /* 延时 */
end;
dat = tmdat;
i = 10;
do while (i > 0);
i = i - 1; /* 延时 */
end;
return (dat);
end tmrbit;
/* 读一个字节 */
tmrbyte:procedure byte pub;
dcl (j,dat) byte;
dcl (i) byte;
dat = 0;
do i = 1 to 8;
j = expand(tmrbit);
dat = shl(j,7) or shr(dat,1);
end;
return (dat);
end tmrbyte;
/* 写一个字节 */
tmwbyte:procedure(dat) pub;
dcl dat byte;
dcl testb bit;
dcl (i,j) byte;
do j = 1 to 8;
testb = boolean(dat and 1);
dat = shr(dat,1);
if testb = 1 then
do;
tmdat = 0; /* 写1 */
i = i + 1;
i = i + 1;
tmdat = 1;
i = 10;
do while (i > 0);
i = i - 1;
end;
end;
else
do;
tmdat = 0; /* 写0 */
i = 10;
do while (i > 0);
i = i - 1;
end;
tmdat = 1;
i = i + 1;
i = i + 1;
end;
end;
end tmwbyte;
/* 发送ds1820 开始转换 */
tmstart :procedure pub;
call tmreset; /* 复位 */
/* call tmpre; */ /* 等待存在脉冲 */
call dmsec (1); /* 延时 */
call tmwbyte (0cch); /* 跳过序列号命令 */
call tmwbyte (044h); /* 发转换命令 44h */
end tmstart;
/* 读取温度 */
tmrtemp :procedure pub;
dcl (a,b) byte;
call tmreset; /* 复位 */
/* call tmpre; */ /* 等待存在脉冲 */
call dmsec (1); /* 延时 */
call tmwbyte (0cch); /* 跳过序列号命令 */
call tmwbyte (0beh); /* 发送读取命令 */
a = tmrbyte; /* 读取低位温度 */
b = tmrbyte; /* 读取高位温度 */
temp = b * 256;
temp = temp + a;
if firstread = 1 then
do;
firstread = 0;
temperature = temp;
end;
else
do;
temperature = (temperature * 9 + temp) / 10;
end;
end tmrtemp;
/* the program entry point */
dcl cnt byte;
call sys$reset;
cnt = 0;
mainloop:
/* 这段是调试代码 */
/*
call dmsec (1000);
disp$buf(0) = char$img(cnt);
disp$buf(1) = char$img(cnt);
cnt = cnt + 1;
if cnt >= 10 then
do;
cnt = 0;
end;
if fanouttmp = 1 then
do;
fanouttmp = 0;
fanout = fanouttmp;
end;
else
do;
fanouttmp = 1;
fanout = fanouttmp;
end;
*/
/* 启动ds18b20 */
disable;
call tmstart;
enable;
call dmsec (1200);
/* 读取温度,执行完毕温度将存于temperature中 */
disable;
call tmrtemp;
enable;
temp = temperature / 16;
if fanoutdelay = 0 then
do;
if temp >= temperaturelimit then
do;
fanouttmp = 0;
fanout = fanouttmp;
fanoutdelay = 20;
end;
else if temp
call display$temp;
goto mainloop;
end mcs51os;
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=74990&Name=lidongfa