系统设计
设计要求
(1) 主体电路包括晶振、复位、电源指示电路,预留程序下载接口;
(2) 要求能够实现温度数值的自动显示,值根据实际温度变化自动变化。
(3) 并按照题目要求完成程序源码编写、调试及关键代码注释。
设计任务
使用给定硬件实现温度测量和显示电路的搭建和实现,完成相关代码编写,使其具备温度显示功能。
性能指标要求
(1) 要求能够实现温度数值的自动显示,值根据实际温度变化自动变化。
(2) 扩展功能: 实现打开空调控制模拟的功能,即当温度高于某一阈值时,控制空调打开;当其高于某一阈值时关闭。空调的开关控制使用一个LED灯进行模拟,如空调处于打开状态时,将某一LED灯点亮即可
设计思路及设计框图
设计思路
(1) 了解设计要求后,查询各元件的特性及使用方法
(2) 查找类似实验资料,并吸收其设计经验
(3) 由于本次下发的是万能板,需自己排版并焊接。为焊接电路的美观我决定先用AD制图软件进行排版,绘制结束后根据电路图直接焊接即可。
(4) 焊接结束后先测试数码管显示,再测试DS18B20的温度传感器测试温度采集;
(5) 经过上述硬件测试后,开始根据硬件设计出数码管驱动代码及DS18B20的温度传感器驱动代码;
(6) 将DS18B20的温度传感器采集到的数据处理后显示到数码管上;
(7) 对拓展功能进行设计及实现;
硬件设计
原理图
PCB图
用万用板连线时,可参考PCB图,避免连线时飞线的出现
程序如下
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define jump_ROM 0xCC
#define start 0x44
#define read_EEROM 0xBE
#define uchar unsigned char
#define uint unsigned int
unsigned char TMPH,TMPL;
sbit DQ = P3^3; //DS18B20数据口
sbit P30=P3^0;
sbit P31=P3^1;
sbit P27=P2^7;
sbit DATA = P3^3; //DS18B20接入口
unsigned char my_SEG7[] = {0x5f , 0x44 , 0x9d, 0xd5 , 0xc6, 0xd3 , 0xda , 0x45 , 0xdf ,0xc7};
char bai,shi,ge; //定义变量
/*延时子函数*/
void delay(uint num)
{
while(num--) ;
}
Init_DS18B20(void) //传感器初始化
{
uchar x=0;
DATA = 1; //DQ复位
delay(10); //稍做延时
DATA = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us //450
DATA = 1; //拉高总线
delay(20);
x=DATA; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(30);
}
//读一个字节
ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DATA = 0; // 给脉冲信号
dat>>=1;
DATA = 1; // 给脉冲信号
if(DATA)
dat|=0x80;
delay(8);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DATA = 0;
DATA = dat&0x01;
delay(10);
DATA = 1;
dat>>=1;
}
delay(8);
}
//读取温度
int ReadTemperature(void)
{
uchar a=0;
uchar b=0;
int 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;
tt=t*0.0625;
t= tt*10+0.5;
return(t);
}
/*显示子函数*/
void display(int bai,int shi,int ge)
{
P2=0xFD; P0=my_SEG7[bai]; delay(100);
P2=0xFB; P0=my_SEG7[shi]+0x20; delay(100);
P2=0xF7; P0=my_SEG7[ge]; delay(100);
}
void main()
{
int temp;
while(1)
{
temp=ReadTemperature();//读温度
bai=temp%1000/100;//显示百位
shi=temp%100/10;//显示十位
ge=temp%10;//显示个位
if(temp >= 300 && temp <= 320 )//高于30度小于32度P2_7口LED灯亮
{
P27 = 0;
delay(100);
}
display(bai,shi,ge);//显示函数
}
}
调试过程及注意事项
1)DS18B20对于数据的读取、检测等方式讲究严格的时序,在编写程序的过程中,需要考虑好相应指令所需的机器周期,以及进行相应的延时操作来读写数据。我再实验过程中尤其是读取DS18B20传输过来的数据时,最开始一直不对,根本原因就是时序延时没有掌握好,掌握好延时和时序后,就能够顺利读取数据。
2)在对DS18B20操作时需要,讲究遵守规则,需要先复位,跳过 ROM,才能进行读写,更改初值等操作。在编写代码的过程中,需要严格历经这三个过程,不要漏步跳步。
3)动态数码管的温度显示要求时刻不断对数码管有数据输入,不能延迟太大导致肉眼可见的掉帧现象,将显示函数写入函数放在10ms一次的定时器中断当中,完成10ms刷新一次的功能。
4)DS18B20的温度数据传入或给温度传感器的写入都是从地位开始输出,在调试过程中没有注意到这个问题导致,温度读取的数据一直有错误,一直到重新看了一边DS18B20后注意到这个细节,专门写了一个输入和读取函数。