急寻单片机高手帮指点下课程设计
发布网友
发布时间:2023-04-23 08:54
我来回答
共3个回答
热心网友
时间:2023-04-27 16:55
17. 99秒马表设计
1. 实验任务
(1. 开始时,显示“00”,第1次按下SP1后就开始计时。
(2. 第2次按SP1后,计时停止。
(3. 第3次按SP1后,计时归零。
2. 电路原理图
图4.17.1
3. 系统板上硬件连线
(1. 把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,……,P0.7/AD7对应着h。
(2. 把“单片机系统”区域中的P2.0/A8-P2.7/A15端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P2.0/A8对应着a,P2.1/A9对应着b,……,P2.7/A15对应着h。
(3. 把“单片机系统“区域中的P3.5/T1用导线连接到”独立式键盘“区域中的SP1端口上;
4. 程序框图
主程序框图
T0中断服务程序框图
图4.17.2
5. 汇编源程序
TCNTA EQU 30H
TCNTB EQU 31H
SEC EQU 32H
KEYCNT EQU 33H
SP1 BIT P3.5
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV KEYCNT,#00H
MOV SEC,#00H
MOV A,SEC
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P2,A
MOV TMOD,#02H
SETB ET0
SETB EA
WT: JB SP1,WT
LCALL DELY10MS
JB SP1,WT
INC KEYCNT
MOV A,KEYCNT
CJNE A,#01H,KN1
SETB TR0
MOV TH0,#06H
MOV TL0,#06H
MOV TCNTA,#00H
MOV TCNTB,#00H
LJMP DKN
KN1: CJNE A,#02H,KN2
CLR TR0
LJMP DKN
KN2: CJNE A,#03H,DKN
MOV SEC,#00H
MOV A,SEC
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P2,A
MOV KEYCNT,#00H
DKN: JNB SP1,$
LJMP WT
DELY10MS:
MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
INT_T0:
INC TCNTA
MOV A,TCNTA
CJNE A,#100,NEXT
MOV TCNTA,#00H
INC TCNTB
MOV A,TCNTB
CJNE A,#4,NEXT
MOV TCNTB,#00H
INC SEC
MOV A,SEC
CJNE A,#100,DONE
MOV SEC,#00H
DONE: MOV A,SEC
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P2,A
NEXT: RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
6. C语言源程序
#include <AT89X51.H>
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char second;
unsigned char keycnt;
unsigned int tcnt;
void main(void)
{
unsigned char i,j;
TMOD=0x02;
ET0=1;
EA=1;
second=0;
P0=dispcode[second/10];
P2=dispcode[second%10];
while(1)
{
if(P3_5==0)
{
for(i=20;i>0;i--)
for(j=248;j>0;j--);
if(P3_5==0)
{
keycnt++;
switch(keycnt)
{
case 1:
TH0=0x06;
TL0=0x06;
TR0=1;
break;
case 2:
TR0=0;
break;
case 3:
keycnt=0;
second=0;
P0=dispcode[second/10];
P2=dispcode[second%10];
break;
}
while(P3_5==0);
}
}
}
}
void t0(void) interrupt 1 using 0
{
tcnt++;
if(tcnt==400)
{
tcnt=0;
second++;
if(second==100)
{
second=0;
}
P0=dispcode[second/10];
P2=dispcode[second%10];
}
}
热心网友
时间:2023-04-27 16:56
数字温度计设计
详细内容请到我空间下载
#include<reg51.h> //头文件//
#define uchar unsigned char
#define uint unsigned int
#define ulint unsigned long int
#define hi 400
#define low 200
uchar dat=0;
uchar data dis_buf[4]={0,0,0,15};//显示的数值 "10"--默认不显示
uchar sign[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,};//七段显示码
sbit DQ=P0^0; //定义通信端口
sbit Hiout=P3^4;//温度过高输出控制
sbit Lowout=P3^5;//温度过低输出控制
//************延时函数************//
void delay(uchar s)
{
uchar l;
for(l=0;l<=s;l++);
}
//************延时函数a************//
void delaya(unsigned int i)
{
while(i--);
}
//***********键盘扫描*************//
/*
void keyscan(void)
{
}
*/
//************初始化函数**********//
Init_DS18B20(void)
{
uchar x=0;
DQ = 1; //DQ复位
delaya(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delaya(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delaya(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delaya(20);
}
//************读一个字节**********//
ReadOneChar(void)
{
uchar i=0;
uchar dat= 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;//
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delaya(4);
}
return(dat);
}
//************写一个字节a*********//
WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delaya(5);
DQ = 1;
dat>>=1;
}
delaya(4);
}
//*******DS18B20程序读取温度******//
ReadTemperature(void)
{
uchar a=0;
uchar b=0;
ulint t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t<<=8;
t=t|a;
if(t>=2048)//判断是不是负值
{
t^=0xffff;
dis_buf[3]=14;//若是负值,则首位显示E
}
else dis_buf[3]=15;
tt=t*0.0625;//数值转换
t=tt*10;//放大10倍, 使显示时可显示小数点后一位
return(t);
}
//************输出控制************//
void Ctrl(ulint in)
{
if(in<low||in>hi)
if(in>hi)
Hiout=1;//高温输出
else Lowout=1;//低温输出
}
//**********数据转换处理**********//
void zhuanh(ulint d)
{
uchar i=0;
uchar j=4;
ulint f;
dis_buf[2]=16;//调试显示改,避免前数据对后数据影响
dis_buf[1]=0;
for(f=d;f>=10;)
{
dis_buf[i]=f%10;//取低位
f=f/10;
i++;
}
dis_buf[i]=f;
dis_buf[1]=dis_buf[1]|0x10;//sign[dis_buf[1]]=sign[dis_buf[1]]|0x80;//显示小数点(定点)
}
//************显示程序************//
void display(void)
{
uchar i=0;
uchar a=96;//a=0x77;
for(i=0;i<4;i++)
{P2=dis_buf[i]+a;
a-=32;
//P0=sign[dis_buf[i]];//P0输出七段码
//P2=a;//点亮指定位
////
//a>>=1;
delay(50);
//P2=0xff; //让数码管灭,去除对下一位的影响,去掉低位对高位重影
}
}
//*************主程序*************//
main()
{
ulint i=0;
uchar j=53;
uchar k=3;
while(1)
{
Hiout=0;
Lowout=0;
i=ReadTemperature(); //读温度值
Ctrl(i); //输出控制
zhuanh(i); //数据处理
while(k--)
display(); //连续显示5次
}
}
热心网友
时间:2023-04-27 16:56
题目:电子时钟设计
电路原理图:(联接http://photo.store.qq.com/http_imgload.cgi?/rurl2=9a73765bb5d81558f98eb2a5ac58adefd50cc2bf38cbb348279f8c8d792098d3b3cfbccc88bbda4f084edb9b7dfcf9e76d21316f9d6636928595946cd4eff7dbf1b057189e3aae528891911551985c1dad173864)
说明:图中,年、月、日及时间选用的是1.2寸共阳数码管,星期选用的是2.3寸数码管,温度选用的是0.5寸数码管,也可根据个人的爱好选用不同规格的数码管。上图中,CPU选用的是AT89C2051,时钟芯片选用的是Dallas公司的DS1302,温度传感器选用的是Dallas公司的数字温度传感器DS1820,显示驱动芯片选用的是德州仪器公司的TPIC6B595,也可选用与其兼容的芯片NC595或国产的AMT9595。整个电子钟用两个键来调节时间和日期。一个是位选键,一个是数字调节键。按一下位选键,头两位数字开始闪动,进入设定调节状态,此时按数字调节键,当前闪动位的数字就可改变。全部参数调节完后,五秒钟内没有任何键按下,则数字停止闪动,退出设定调节状态。
源程序清单如下(无温度显示程序):start:do;
$include(reg51.dcl)
declare (sclk,io,rst) bit at (0b3h) register; /* p33,p34,p35 */
declare (command,data,n,temp1,num) byte;
declare a(9) byte;
declare ab(6) byte;
declare aco(11) byte constant (0fdh,60h,0dah,0f2h,66h,0b6h,0beh,
0e0h,0feh,0f6h,00h);
declare week(11) byte constant (0edh,028h,0dch,7ch,39h,75h,0f5h,
2ch,0fdh,7dh,00h);
declare da literally 'p15',clk literally 'p16',ale literally 'p17',
mk literally 'p11',sk literally 'p12';
clear:procere;
sclk=0;io=0;rst=0;
end clear;
send1302:procere(comm);
declare (i,comm) byte;
do i=0 to 7;
comm=scr(comm,1);
io=cy;
call time(1);
sclk=0;
call time(1);
sclk=1;
end;
end send1302;
wbyt1:procere(com,dat);/*字节写过程*/
declare (com,dat) byte;
call clear;
rst=1;
call send1302(com);
call send1302(dat);
call clear;
end wbyt1;
wbyt8:procere;/*时钟多字节突发模式写过程*/
declare j byte;
call clear;
a(7)=A(6);a(6)=a(0);
rst=1;
call send1302(command);
do j=1 to 8;
call send1302(a(j));
end;
call clear;
end wbyt8;
RBYT1:PROCEDURE;
DECLARE I BYTE;
CALL CLEAR;
RST=1;
call send1302(0c1h);
IO=1;
DO I=0 TO 7;
SCLK=1;
SCLK=0;
CY=IO;
N=SCR(N,1);
END;
A(8)=N;
CALL CLEAR;
END RBYT1;
send595:procere;
declare k byte;
do k=0 to 7;
data=scr(data,1);
da=cy;
clk=1;
clk=0;
end;
end send595;
send595_1:procere;
declare k byte;
do k=0 to 7;
data=scr(data,1);
da1=cy;
clk1=1;
clk1=0;
end;
end send595_1;
rb1:procere(abc,j);
DECLARE (I,j,abc) BYTE;
CALL CLEAR;
RST=1;
call send1302(abc);
IO=1;
DO I=0 TO 7;
SCLK=1;
SCLK=0;
CY=IO;
N=SCR(N,1);
END;
ab(j)=N;
ab(j)=dec(ab(j));
CALL CLEAR;
end rb1;
rbyt6:procere;
call rb1(0f1h,0);
call rb1(0f3h,1);
call rb1(0f5h,2);
call rb1(0f7h,3);
call rb1(0f9h,4);
call rb1(0fbh,5);
call rb1(0fdh,6);
end rbyt6;
wbyt6:procere;
call wbyt1(8eh,0); /* write enable */
call wbyt1(0f0h,ab(0));
call wbyt1(0f2h,ab(1));
call wbyt1(0f4h,ab(2));
call wbyt1(0f6h,ab(3));
call wbyt1(0f8h,ab(4));
call wbyt1(0fah,ab(5));
call wbyt1(0fch,ab(6));
call wbyt1(8eh,80h); /* write disable */
end wbyt6;
rbyt8:procere;/*时钟多字节突发模式读过程*/
declare (i,j) byte;
call clear;
rst=1;
call send1302(command);
io=1;
do j=1 to 8;
do i=0 to 7;
sclk=1;
call time(1);
sclk=0;
cy=io;
n=scr(n,1);
end;
a(j)=n;
end;
call clear;
a(0)=a(6);a(6)=A(7);
a(0)=a(0) and 0fh;
if a(0)>6 then a(0)=0;
CALL RBYT1;
if (a(1)=0 and a(2)=0 and a(3)=0) then
do;
do num=0 to 35;
call time(250);
end;
temp1=1;
end;
if temp1=1 then
do;
temp1=0;
ab(4)=ab(4)+1;
if ab(4)>99h then
do;
ab(4)=0;
ab(5)=ab(5)+1;
if ab(5)>99h then ab(5)=0;
end;
call wbyt6;
end;
end rbyt8;
display:procere; /*jieya,yima,fasong*/
declare (i,n,m) byte;
n=a(0) and 0fh; /* send week */
data=week(n);
call send595;
n=a(4); /* send date */
n=n and 0fh;
data=aco(n);
call send595;
n=a(4);
n=shr(n,4);
data=aco(n);
call send595;
do i=1 to 3; /* send second,minute,hour */
n=a(i);
n=n and 0fh;
data=aco(n);
call send595;
n=a(i);
n=shr(n,4);
data=aco(n);
call send595;
end;
do i=5 to 6; /* send month,year */
n=a(i);
n=n and 0fh;
data=aco(n);
call send595;
n=a(i);
n=shr(n,4);
data=aco(n);
call send595;
end;
n=a(8); /* send 19 or 20 */
n=n and 0fh;
data=aco(n);
call send595;
n=a(8);
n=shr(n,4);
data=aco(n);
call send595;
do m=0 to 5;
n=ab(m);
n=n and 0fh;
data=aco(n);
call send595_1;
n=ab(m);
n=shr(n,4);
data=aco(n);
call send595_1;
end;
ale=0;
ale=1;
end display;
beginset:procere;
a(0)=06h;a(1)=58h;a(2)=59h;a(3)=23h;
a(4)=30h;a(5)=06h;a(6)=97h;a(7)=00;
a(8)=19h; /* set date/time (1997,7,1,8:00:00,week 3) */
call wbyt1(8eh,0); /* write enable*/
call wbyt1(80h,00h);/* start colock */
call wbyt1(0beh,0abh);/*两个二极管与8K电阻串联充电*/
command=0beh; /* write colock/date */
call wbyt8;
call wbyt1(0c0h,a(8));
call wbyt1(8eh,80h); /* set write protect bit */
end beginset;
key:procere;
declare (i,time1,k1,tem) byte;
call time(100);
k1=7;time1=30;
if mk=0 then
do;
do while time1>0;
week: if k1=0 then
do;
do i=0 to 5;
/* call hz(a(0)); */
end;
do i=0 to 3;
/* call hz0; */
end;
end;
tem=a(k1);
if k1=7 then tem=a(8);
a(k1)=0aah;
if k1=7 then a(8)=0aah;
call display;
call time(254);
call time (254);
a(k1)=tem;
if k1=7 then a(8)=tem;
call display;
call time(254);
call time(254);
call time(254);
time1=time1-1;
if mk=0 then
do;call time(100); /*MOD KEY PROCESS*/
TIME1=30;
IF MK=0 THEN
DO;
k1=k1-1;
DO WHILE K1=0FFH;
K1=7;
END;
END;
end;
IF SK=0 THEN
DO;CALL TIME(100); /*SET KEY PROCESS*/
TIME1=30;
IF SK=0 THEN
DO;
tem=tem+1;
tem=dec(tem);
DO CASE K1;
DO WHILE tem=7;/*week*/
tem=0;
END;
DO WHILE tem=60H;/*scond*/
tem=0;
END;
DO WHILE tem=60H;/*minute*/
tem=0;
END;
DO WHILE tem=24H;/*hour*/
tem=0;
END;
DO WHILE tem=32H;/*date*/
tem=1;
END;
DO WHILE tem=13H;/*month*/
tem=1;
END;
DO while tem=100h; /* YEAR */
tem=00;
END;
DO WHILE TEM>=21H;
tem=19H;
END;
END;
A(K1)=tem;
if k1=7 then a(8)=tem;
END;
END;
END;
END;
end key;
main$program:
mk=1;sk=1;temp1=0;num=0;p32=1;
if sk=0 then call beginset;
clk=0;da=0;ale=1;
loop:
do while mk=1 ;
if a(0)>6 then a(0)=0;
command=0bfh;
call rbyt8;
call display;
do while mk=0;
call key;
call wbyt1(8eh,0);
command=0beh;
call wbyt8;
call wbyt1(0C0H,A(8));
call wbyt1(8eh,80h);
end;
end;
goto loop;
end start;
参考资料:百度