temp:
tempH);
if(KEY1==0){temp=tempL;
test1=0;EA=0;
while(j--)display();
EA=1;
}
if(KEY2==0){
temp=tempH;
test2=0;EA=0;
while(j--)display();
EA=1;}
}
}
B.3显示子程序
8个数码管轮流进行显示,分别显示1ms,依赖人的视觉暂留效应,给人以数码管持续高亮的错觉。
该段程序如下:
voiddisplay()
{uchartmp;
uchartmp1;
staticucharcount;
P3=0XFF;
tmp=dispbit[count];
tmp1=tmp;
P3&=tmp;
//we=0;/////////////////WEI操作
//du=1;//////////////////duan操做
tmp=dispbuf[5-count];
if(tmp1==0xf7)
{tmp=disptabwithdot[tmp];}
else
{tmp=disptab[tmp];}
P0=tmp;
count++;
if(count==6)
{count=0;}
//unsignedinttemp=abs(tempValue);
dispbuf[0]=temp/10000;
dispbuf[1]=temp%10000/1000;
dispbuf[2]=temp%1000/100;
dispbuf[3]=temp%100/10;
dispbuf[4]=temp%10;
//TH0=th0;
//TL0=tl0;
}
程序调试
本程序通过Keil单片机开发平台实现程序的编译,,生成HEX文件。
程序再编译过程中可以发现错位,并及时改正,在设计时非常重要,使错误被扼杀在摇篮中。
通过Keil和硬件仿真平台Proteus的联合,可以将设计效果仿真出来,根据效果,有目的的改变设计,优化程序。
c.利用Keil软件实验过程截图:
c.1汇编程序,并生成HEX文件
c.2利用下载线将文件调入电路板调试,运行结果如下:
下图为温度实时显示结果:
下图为温度报警结果:
D电路板连接实现
通过软,硬件设计和仿真,基本上实现了自己想要的功能,就可以真刀真枪的干一场了。
软件通过调试基本上是没问题的,但是硬件仿真过于泛泛,对电路的细节要求不是那么高,有些问题是不能发现的,最后的实现效果还是要用实物来验证的。
元器件的购买是个苦活,虽然中发市场那么大,但那些元件才是我要的那个它呢?
我们购买的量少,对于那些元器件厂家来说,根本不屑做我们的生意,根本不用说砍价了。
经过一番“跋涉”,终于搜刮齐了元器件。
根据以往经验,焊接电路的布线非常重要,首先要在电路板上将线的大致走向规划好,如何美观,精简是要领。
一下是本次试验的硬件电路实现
五.实验总结及感想
通过这几周的软、硬件设计,不仅加深了我们对理论知识的理解,培养了我们的实践动手能力,还锻炼了我们遇到问题解决问题的能力。
从开始接到任务时的无从下手,到小组成员各司其职,搜集资料,学习新知识,相互讨论,分析交流,解决好问题的这个过程本身就是对我们的锻炼。
此次设计课不同于一般理论课的地方就在于要求我们的并非只是单纯的懂得理论知识,更重要的是小组成员间的团结协作精神以及将理论知识用于实践的能力,由于在实际中,存在各种各样的因素,即使我们有着正确的原理图、软件程序等也不一定能得出正确的结果,正如调试时产生的问题一样,这就需要我们有耐心去分析各种可能存在因素以达到解决问题的最终目的,当然这其中肯定少不了老师的指导和帮助。
这次真得要感谢我们组组长和小组成员,几周以来,我们共同度过了很多困难的时光,也共同收获了很多。
通过这次课程设计我们学到了很多东西,培养了我们的自学能力,接受新事物的心态,以及遇到问题时戒骄戒躁的良好心态和虚心向同学、老师请教自己不会的问题,更重要的是小组成员间的团结协作,相互鼓励,做好分配给自己的任务,用心做每一件事而非应付过关的消极态度。
从最初的连线到最终程序的不断,排错,改进,大家的能力真得提高了不少。
总之,此次设计课使我们受益匪浅。
附:
总程序
#include
#include//要用到取绝对值函数abs()
#defineucharunsignedchar
#defineuintunsignedint
sbitKEY1=P2^4;
sbitKEY2=P2^5;
sbitKEY3=P2^6;
sbitKEY4=P2^7;
sbitKEY5=P2^3;
sbittest1=P3^6;
sbittest2=P3^7;
sbitbeep=P1^5;
sbitled=P1^2;
//sbitdu=P2^6;
//sbitdio=P2^5;
sbitds=P1^0;
//sbitds=P2^2;
inttempValue1;
unsignedinttemp;
unsignedinttempH;
unsignedinttempL;
ucharcodeth0=(65535-3000)/256;
ucharcodetl0=(65535-3000)%256;
uchardispbuf[6];
ucharcodedisptab[]={0x3f,0x6,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
0x79,0x71,0x0};
ucharcodedisptabwithdot[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0xa7,0xff,0xef,0xf7,
0xfc,0xb9,0xf9,0xf1};
ucharcodedispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
//11111110,11111101,11111011,11110111,11101111,11011111;
//延时函数,对于11.0592MHz时钟,例i=10,则大概延时10ms.
voiddisplay();
voidbeeping();
voiddelay(unsignedinti)
{
unsignedintj;
while(i--)
{
for(j=0;j<125;j++);
}
}
voiddsInit()
{
//对于11.0592MHz时钟,unsignedint型的i,作一个i++操作的时间大于1us
unsignedinti;
ds=0;
i=100;//拉低约800us,符合协议要求的480us以上
while(i>0)i--;
ds=1;//产生一个上升沿,进入等待应答状态
i=4;
while(i>0)i--;
}
voiddsWait()
{
unsignedinti;
while(ds);
while(~ds);//检测到应答脉冲
i=4;
while(i>0)i--;
}
//向DS18B20读取一位数据
//读一位,让DS18B20一小周期低电平,然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bitreadBit()//读0时序
{
unsignedinti;
bitb;
ds=0;
i++;//延时约8us,符合协议要求至少保持1us
ds=1;
i++;i++;//延时约16us,符合协议要求的至少延时15us以上
b=ds;
i=8;
while(i>0)i--;//延时约64us,符合读时隙不低于60us要求
returnb;
}
//读取一字节数据,通过调用readBit()来实现
unsignedcharreadByte()
{
unsignedinti;
unsignedcharj,dat;
dat=0;
for(i=0;i<8;i++)
{
j=readBit();
//最先读出的是最低位数据
dat=(j<<7)|(dat>>1);//先把数据放在高位,然后再移到低位
}
returndat;
}
//向DS18B20写入一字节数据
voidwriteByte(unsignedchardat)
{
unsignedinti;
unsignedcharj;
bitb;
for(j=0;j<8;j++)
{
b=dat&0x01;
dat>>=1;
//写"1",将DQ拉低15us后,在15us~60us将DQ拉高,即完成写1
if(b)
{
ds=0;
i++;i++;//拉低约16us,符号要求15~60us
ds=1;
i=8;while(i>0)i--;//延时约64us,符合写时隙不低于60us要求
}
else//写"0",将DQ拉低60us~120us
ds=0;
i=8;while(i>0)i--;//拉低约64us,符号要求
ds=1;
i++;i++;//整个写0时隙过程已经超过60us,这里就不用像写1那样,再延时64us了
}
}
//向DS18B20发送温度转换命令
voidsendChangeCmd()
{
dsInit();//初始化DS18B20,无论什么命令,首先都要发起初始化
dsWait();//等待DS18B20应答
delay
(1);//延时1ms,因为DS18B20会拉低DQ60~240us作为应答信号
writeByte(0xcc);//写入跳过序列号命令字SkipRom
writeByte(0x44);//写入温度转换命令字ConvertT
}
//向DS18B20发送读取数据命令
voidsendReadCmd()
{EA=0;//关闭中断是因为进入显示中断会影响到DS18B20的读写时序
dsInit();
dsWait();
delay
(1);
writeByte(0xcc);//写入跳过序列号命令字SkipRom
writeByte(0xbe);//写入读取数据令字ReadScratchpad
EA=1;
}
//获取当前温度值
intgetTmpValue()
{
unsignedinttmpvalue;
intvalue;//存放温度数值
floatt;
unsignedcharlow,high;
EA=0;
sendReadCmd();
//连续读取两个字节数据
low=readByte();
high=readByte();
//将高低两个字节合成一个整形变量
//计算机中对于负数是利用补码来表示的
//若是负值,读取出来的数值是用补码表示的,可直接赋值给int型的value
tmpvalue=high;
tmpvalue<<=8;
tmpvalue|=low;
value=tmpvalue;
//使用DS18B20的默认分辨率12位,精确度为0.0625度,即读回数据的最低位代表0.0625度
t=value*0.0625;
//将它放大100倍,使显示时可显示小数点后两位,并对小数点后第三进行4舍5入
//如t=11.0625,进行计数后,得到value=1106,即11.06度
//如t=-11.0625,进行计数后,得到value=-1106,即-11.06度
value=t*100+(value>0?
0.5:
-0.5);//大于0加0.5,小于0减0.5
returnvalue;
EA=1;
}
voidInit_timer0()
{
TMOD=0x01;
TH0=th0;
TL0=tl0;
EA=1;
ET0=1;
TR0=1;
}
voidtimer0()interrupt1
{intk=30;
if(temp>3000){while(k--){beeping();
//beep=0;
led=0;}
}
else{led=1;beep=1;}
display();
TH0=th0;
TL0=tl0;
}
voiddisplay()
{
uchartmp;
uchartmp1;
staticucharcount;
P3=0XFF;
tmp=dispbit[count];
tmp1=tmp;
P3&=tmp;
//we=0;/////////////////WEI操作
//du=1;//////////////////duan操做
tmp=dispbuf[5-count];
if(tmp1==0xf7)
{
tmp=disptabwithdot[tmp];
}
else
{
tmp=disptab[tmp];
}
P0=tmp;
count++;
if(count==6)
{
count=0;
}
//unsignedinttemp=abs(tempValue);
dispbuf[0]=temp/10000;
dispbuf[1]=temp%10000/1000;
dispbuf[2]=temp%1000/100;
dispbuf[3]=temp%100/10;
dispbuf[4]=temp%10;
//TH0=th0;
//TL0=tl0;
}
voidbeeping()
{
beep=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
//beep=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();