课程设计说明书
4.2 初始化子程序
使用DS18B20时,单片机先向DS18B20送出复位信号,单片机将数据拉低并保持480~960μs;再释放数据线,由上拉电阻拉高15~60μs;然后再由DS18B20发出低电平60~240μs,就完成了复位操作。
通过init_ds18b20()函数来实现18B20的初始化 char init_ds18b20() {
uchar status;
dq = 1;delay(8);//高电平 dq = 0;delay(90); dq = 1;delay(8);//高电平 status = dq; delay(100); dq = 1;高电平 return status; }
4.3 读子程序
读数据之前,单片机先将数据线拉低,再释放。DS18B20在数据线从高电平跳低后15μs内将数据送到数据线上。单片机在15μs后读数据线。
通过read_temperature()函数读取温度值到DS18B20 void read_temperature() {
if( init_ds18b20() ==1)
ds18b20_is_ok = 0;//DS18B20故障 else {
writeonebyte(0xcc);//跳过序列号 writeonebyte(0x44);//启动温度转换 init_ds18b20();//DS18B20初始化 writeonebyte(0xcc);//跳过序列号 writeonebyte(0xbe);//读取温度寄存器
temp_value[0] = readonebyte();//温度低8位
temp_value[1] = readonebyte();//温度高8位
11
课程设计说明书
alarm_temp_hl[0] = readonebyte();//报警温度DH alarm_temp_hl[1] = readonebyte();//报警温度DL ds18b20_is_ok = 1;//DS18B20正常工作 }
}
4.4 写子程序
在单片机对DS18B20写数据时,应先将数据线拉低1μs以上,再写入数据(写1为高,写0为低)。待单片机写入的数据变化15~60μs后,DS18B20将对数据线采样。单片机写入数据到DS18B20的保持时间为60~120μs。通过writeonebyte()函数写入8位字节。
void writeonebyte(uchar dat) { uchar i;
for(i = 0;i < 8;i++)
{dq = 0;dq = dat & 0x01;delay(5); dq = 1;dat >>=1; } }
通过set_alarm_temp_value()函数中的实现数据的读入
void set_alarm_temp_value()
{
init_ds18b20();初始化DS18B20 writeonebyte(0xcc); //跳过序列号
writeonebyte(0x4e);//将设定的温度报警值写入DS18B20 writeonebyte(alarm_temp_hl[0]); //写入TH writeonebyte(alarm_temp_hl[1]); //写入TL writeonebyte(0x7f);//12位精度 init_ds18b20(); //初始化DS18B20 writeonebyte(0xcc); //跳过序列号
writeonebyte(0x48); //温度报警值存入DS18B20
}
4.5 数据处理子程序
12
课程设计说明书
先判断温度高8位,如果CY为1,则将高、低8八位求补;对高、低8位的数据按权整合称一个整数,判断是否在-50~110℃之间,超出范围则置报警灯为亮;将该数按百、十、个位分别存入相应的存储单元。流程图如图11所示:
取温度值 符号为正? Y N 求补码 高、低8位整合成为一个整数存入A中 -50~110之间? N 报警 Y 分别存入百、十、个、小数位
图11 数据处理流程图
通过子函数display_temperature()中的 uchar ng = 0 , np = 0; char signed_current_temp;
if ( ( temp_value[1] & 0xf8) == 0xf8 )//如果是负数则取反加1 {temp_value[1] = ~temp_value[1]; temp_value[0] =~temp_value[0] + 1;
if ( temp_value[0] == 0x00 ) temp_value[1]++;正数显示温度值加1
ng = 1;np = 0xfd;//默认负号显示在左边第2排 }
display_digit[0] = df_table[temp_value[0] & 0x0f ];//查表得到温度小数部分 currentt = ((temp_value[0] & 0xf0)>>4) | ((temp_value[1] & 0x07)<<4);//获取温度整数部分
signed_current_temp = ng? -currentt :currentt;//有符号数当前温度值
13
课程设计说明书
hi_alarm = signed_current_temp >= alarm_temp_hl[0] ? 1 : 0;//高温报警设置 lo_alarm = signed_current_temp <= alarm_temp_hl[1] ? 1: 0;//低温报警设置 // 将整数部分分解为三位待显示数字 display_digit[3] = currentt /100;//百位 display_digit[2] = currentt % 100 /10;//十位 display_digit[1] = currentt % 10;//个位 if (display_digit[3] == 0 ) {
display_digit[3] = 10;//高位是零则不显示
np = 0xfb;//调整负号位置 if( display_digit[2] == 0) {
display_digit[2] =10;//高位是零则不显示 np = 0xf7;//调整负号位置 }
语句实现温度数据处理,如果 温度数据是正,则直接分别显示百、十、个位,如果最高位是零,则最高位不显示。如果温度是负,则取反后再显示。
4.6 显示子程序
将百、十、个、小数位的数据查表,送到对应的数码管显示,程序流程图如12所示:
14
课程设计说明书
取温度
温度为负? Y N 显示百位,延时 显示负号,延时 显示十位,延时 显示个位,延时 显示小数位,延时 N 显示400遍? N Y 超过范围? Y 延时 返回
图12 显示程序流程图
通过子函书中display_temperature()中的
for (i = 0;i <30;i ++)
{
P0 = 0x39;P2 = 0x7f; delay(t);P2 = 0xff;//显示C
P0 = 0x63; P2 = 0xbf;delay(t);P2 = 0xff;//显示。
15