主要设计对DS18B20官方驱动的改动和矩阵键盘的逻辑操作,难度不大,主要涉及逻辑问题。
DS18B20官方驱动的改动后如下
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台
日 期: 2011-8-9
*/
#include "onewire.h"
//单总线延时函数
//void Delay_OneWire(unsigned int t)
//{
// unsigned char i =0;
// while(t--)
// for(i=0;i<12;i++);//扩大12倍延时
//}
void Delay_OneWire(unsigned int t)
{
t=12*t;//扩大12倍延时
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
unsigned char temget(void)//温度获取
{
unsigned char temp;
unsigned char low,high;
Init_DS18B20();
Write_DS18B20(0xcc);//忽略rom指令
Write_DS18B20(0x44);//开始温度转换
Delay1ms();//等待1ms温度转换
Init_DS18B20();
Write_DS18B20(0xcc);//忽略rom指令
Write_DS18B20(0xbe);//读取暂存器直到9字节
low=Read_DS18B20();//温度数据16位存储,小数部分在低四位,符号在高四位。在此均不需要
high=Read_DS18B20();
temp=((high<<4)|(low>>4));//DS18B20数据存储为低位到高位
return temp;
}
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//IC引脚定义
sbit DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
//自行添加函数
unsigned char temget(void);//温度获取
void Delay1ms(); //@12.000MHz
#endif
#include
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar temp;//矩阵键盘中间变量
uchar tmax=30,tmin=20;
uchar led1=0;//指示灯和继电器标志位
uchar tt=0;//计数
uchar open=0;//L1打开标志位
uchar num=0;
uchar set=0;//设置
uchar clean=0;//清除
uchar flag=0;//按键是否按下标志位
void allinit();
void Delay1ms(uchar z);
void displayer1(uchar yi,uchar er);
void displayer2(uchar san,uchar si);
void displayer3(uchar wu,uchar liu);
void displayer4(uchar qi,uchar ba);
void Timer0Init(void);
void keyscan16();
void main()
{
uchar tem;//温度
allinit();//板子初始化
Timer0Init();//定时器初始化
EA=1;//开总中断
ET0=1;//开定时器0
while(1)
{
keyscan16();//矩阵键盘
if(set==0)
{
tem=temget();//获取温度
if(tem=tmin)&&(tem<=tmax))
{
// er=1;
led1=1;
}
else if(tem>tmax)
{
//er=2;
led1=2;
}
yi=10,er=led1,san=10,si=11,wu=11,liu=11,qi=tem/10,ba=tem%10;//温度状态显示
}
else if(set==1)
{
if(clean==1)
{
clean=0;
yi=10,er=11,san=11,si=11,wu=11,liu=10,qi=11,ba=11;//按下清除按键进入设置界面
}
if((er==11)&&(flag==1))//获取按键值
{
flag=0;
er=num;
}
else if((san==11)&&(flag==1))
{
flag=0;
san=num;
}
else if((qi==11)&&(flag==1))
{
flag=0;
qi=num;
}
else if((ba==11)&&(flag==1))
{
flag=0;
ba=num;
if((er*10+san)<(qi*10+ba))//确保tmax>tmin
{
yi=10,er=11,san=11,si=11,wu=11,liu=10,qi=11,ba=11;//如果tmax0;k--)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
void displayer1(uchar yi,uchar er)
{
P2=0XC0;//位选
P0=0X01;
P2=0XE0;//段选
P0=tab[yi];
Delay1ms(1);
P2=0XC0;//位选
P0=0X02;
P2=0XE0;//段选
P0=tab[er];
Delay1ms(1);
}
void displayer2(uchar san,uchar si)
{
P2=0XC0;//位选
P0=0X04;
P2=0XE0;//段选
P0=tab[san];
Delay1ms(1);
P2=0XC0;//位选
P0=0X08;
P2=0XE0;//段选
P0=tab[si];
Delay1ms(1);
}
void displayer3(uchar wu,uchar liu)
{
P2=0XC0;//位选
P0=0X10;
P2=0XE0;//段选
P0=tab[wu];
Delay1ms(1);
P2=0XC0;//位选
P0=0X20;
P2=0XE0;//段选
P0=tab[liu];
Delay1ms(1);
}
void displayer4(uchar qi,uchar ba)
{
P2=0XC0;//位选
P0=0X40;
P2=0XE0;//段选
P0=tab[qi];
Delay1ms(1);
P2=0XC0;//位选
P0=0X80;
P2=0XE0;//段选
P0=tab[ba];
Delay1ms(1);
P2=0XC0;//位选
P0=0XFF;
P2=0XE0;//段选
P0=0XFF;//将所有数码管关闭,使其亮度一致,都点亮1ms
}
void Timer0Init(void) //5毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xA0; //设置定时初值
TH0 = 0x15; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void timer0() interrupt 1//中断服务函数
{
tt++;
if(led1==0)
{
P2=(P2&0x1f)|0xa0;
P0=0X00;//关闭继电器
P2=P2&0x1f;
if(tt==160)
{
tt=0;
if(open==0)
{
open=1;
P2=(P2&0x1f)|0x80;
P0=0XFE;//打开L1
P2=P2&0x1f;
}
else
{
open=0;
P2=(P2&0x1f)|0x80;
P0=0XFF;//关闭L1
P2=P2&0x1f;
}
}
}
if(led1==1)
{
P2&=0X1F;
P2=(P2&0x1f)|0xa0;
P0=0X00;//关闭继电器
P2=P2&0x1f;
if(tt==80)
{
tt=0;
if(open==0)
{
open=1;
P2=(P2&0x1f)|0x80;
P0=0XFE;//打开L1
P2=P2&0x1f;
}
else
{
open=0;
P2=(P2&0x1f)|0x80;
P0=0XFF;//关闭L1
P2=P2&0x1f;
}
}
}
if(led1==2)
{
P2=(P2&0x1f)|0xa0;
P0=0X10;//开继电器
P2=P2&0x1f;
if(tt==40)
{
tt=0;
if(open==0)
{
open=1;
P2=(P2&0x1f)|0x80;
P0=0XFE;//打开L1
P2=P2&0x1f;
}
else
{
open=0;
P2=(P2&0x1f)|0x80;
P0=0XFF;//关闭L1
P2=P2&0x1f;
}
}
}
}
//矩阵键盘模块
void keyscan16()
{
//第一列
P3=0X7F;P4=0XEF;//P44=0
temp=P3;
temp=temp&0X0F; //0111 1111&0000 1111=0000 1111
if(temp!=0X0F)
{
Delay1ms(5);
temp=P3;
temp=temp&0X0F; //0111 1111&0000 1111=0000 1111
//判断后四位是否发生变化
if(temp!=0X0F)//如果变化
{
temp=P3;//重新判断P3的值
switch(temp)
{
case 0x7e :num=0;flag=1;break;
case 0x7d :num=3;flag=1;break;
case 0x7b :num=6;flag=1;break;
case 0x77 :num=9;flag=1;break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
}
}
//第二列
P3=0XBF;P4=0XFB;//P42=0
temp=P3;
temp=temp&0X0F;
if(temp!=0X0F)
{
Delay1ms(5);
temp=P3;
temp=temp&0X0F;
//判断后四位是否发生变化
if(temp!=0X0F)//如果变化
{
temp=P3;//重新判断P3的值
switch(temp)
{
case 0xbe :num=1;flag=1;
break;
case 0xbd :num=4;flag=1;
break;
case 0xbb :num=7;flag=1;
break;
case 0xb7 :
{
if(set==0)
{
set=1;
EA=0;ET0=0;//关闭中断
P2=(P2&0x1f)|0x80;
P0=0XFF;//关闭L1
P2=(P2&0x1f)|0xa0;
P0=0x00;//关闭数码管
yi=10,er=11,san=11,si=11,wu=11,liu=10,qi=11,ba=11;//设置界面
}
else if(set==1)
{
set=0;
EA=1;ET0=1;
P2=0x80;
P0=0xff;
tmax=(er*10+san);//将设置温度存储
tmin=(qi*10+ba);
}
}
break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
}
}
//第三列
P4=0XFF;
P3=0XDF;
temp=P3;
temp=temp&0X0F; //0111 1111&0000 1111=0000 1111
if(temp!=0X0F)
{
Delay1ms(5);
temp=P3;
temp=temp&0X0F;
//判断后四位是否发生变化
if(temp!=0X0F)//如果变化
{
temp=P3;//重新判断P3的值
switch(temp)
{
case 0xde :num=2;flag=1;break;
case 0xdd :num=5;flag=1;break;
case 0xdb :num=8;flag=1;break;
case 0xd7 :clean=1;break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
}
}
}