#include<reg51.h>
#include <math.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar hour,min,sec,count,hour1,hour2,
sec1,sec2,min1,min2,keystopc,temp;
sbit lcden=P2^7;
sbit lcdrw=P2^6;
sbit lcdrs=P2^5;
sbit SCL=P1^0; //PCF8591T的 SCL 引脚接于单片机的P1^7引脚上
sbit SDA=P1^1; //PCF8591T的 SDA 引脚接于单片机的P1^6引脚上
//HC-SR04相关I/O设置
sbit TIRG=P3^4; //定义IO口
sbit ECHO=P3^2; //定义IO口
bit flag =0;
unsigned char k;
uchar code table[]={
'0','1','2','3','4','5','6','7','8','9',':','.'};
uint num=0;
float f_temp;
unsigned char ADbuf1,ADbuf2;//设置8位的寄存器用来暂存A/D转换结果
void init() //定时器初始化
{
count=0;
hour=0; //时
min=0; //分
sec=0; //秒
TMOD=0x01;
TH0=(65536-50000)/256; //TH0=60
TL0=(65536-50000)%256; //TL0=6
TR0=0;
EA=0;
ET0=0;
}
void delay(uint z) //延时程序
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**************************************************************
LCD1602显示函数
*************************************************************/
void write_com(uchar com) //写命令函数
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //写数据函数
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_1602() //初始化1602
{
lcden=0;
lcdrw=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void write_Char(unsigned char x,unsigned char y,unsigned char date) //在1602上显示数据位置
{
if (y == 0)
{
write_com(0x80 + x);
}
else
{
write_com(0xC0 + x);
}
write_data(date);
}
void display(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2) //显示程序
{
write_Char(4,1,table[hour1]);
write_Char(5,1,table[hour2]);
write_Char(6,1,table[0x0a]);
write_Char(7,1,table[min1]);
write_Char(8,1,table[min2]);
write_Char(9,1,table[0x0a]);
write_Char(10,1,table[sec1]);
write_Char(11,1,table[sec2]);
}
// 计时器/定时器0
void count0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==12)
{
hour=0;
}
}
}
}
}
//名称:生IIC启动信号函数
void IICstart(void)
{
SDA=1; //先将SDA=1,以准备在SCL=1时,将SDA=0
SCL=1; //时钟总线拉高
_nop_(); //略做延时
_nop_(); //略做延时
SDA=0; //SCL=1时,将SDA拉低即产生启动信号
_nop_(); //略做延时
_nop_(); //略做延时
SCL=0; //将SCL=0,完成启动信号操作
}
//名称:IIC停止信号函数
void IICstop(void)
{
SDA=0; //先将SDA=0,以准备在SCL=1时,将SDA=1
SCL=1; //时钟总线拉高
_nop_(); //略做延时
_nop_(); //略做延时
SDA=1; //SCL=1时,将SDA拉高即产生停止信号
_nop_(); //略做延时
_nop_(); //略做延时
SCL=0; //将SCL=0,完成启动信号操作
}
//名称:向IIC总线写入1个字节函数
void Write1Byte(unsigned char Buf1)
{
unsigned char k; //1个字节要分8次写入,需要定义一个寄存器用来计数
for(k=0;k<8;k++) //做一个8次的循环,每次写入1位,需要写8次
{
if(Buf1&0x80) //从最高位开始写
{
SDA=1; //如果欲写入数据为1,就将数据线置1
}
else
{
SDA=0; //如果欲写入数据为0,就将数据线写0
}
_nop_(); //略做延时
_nop_(); //略做延时
SCL=1; //时钟线做一个上升沿,将一位数据写入
Buf1=Buf1<<1; //数据左移一位,将下次要写入的位数据移到最高位
_nop_(); //略做延时
SCL=0; //将SCL=0,以准备通过上升沿将数据写入
_nop_(); //略做延时
}
SDA=1; //将SDA=1,准备读应答信号
_nop_(); //略做延时
SCL=1; //将SCL=1,做个上升沿准备读应答信号
_nop_(); //略做延时
_nop_(); //略做延时
SCL=0; //将SCL=0,结束应答信号读操作
}
//名称:从IIC总线读入1个字节函数
unsigned char Read1Byte(void)
{
unsigned char k; //1个字节要分8次读出,需要定义一个寄存器用来计数
unsigned char t=0; //定义一个寄存器用保存读出数据
for(k=0;k<8;k++) //做一个8次的循环,每次读入1位,需要读8次
{
t=t<<1; //数据左移一位,空出最低位以准备保存读入的一位数据
SDA=1; //将SDA写1准备读
SCL=1; //将SCL=1,做个上升沿准备读一位数据
_nop_(); //略做延时
_nop_(); //略做延时
if(SDA==1) //读一位数据,并判断
{
t=t|0x01; //如果读入数据为1,就将接收缓冲区最低一位置1
}
else
{
t=t&0xfe; //如果读入数据为0,就将接收缓冲区最低一位写0
}
SCL=0; //SCL恢复为0,结束一位数据读操作
_nop_(); //略做延时
_nop_(); //略做延时
}
return t; //将读入的一个字节返回
}
//名称:软件模拟IIC向PCF8591指定地址写一个字节函数
void WritePCF8591(unsigned char Databuf)
{ //直接调用本函数即可启动PCF8591的D/A转换
IICstart(); //IIC启动信号
Write1Byte(0x90); //发送PCF8591的器件地址和写信号
Write1Byte(0x40); //发送器件子地址
Write1Byte(Databuf); //发送数据
IICstop(); //产生IIC停止信号
}
//名称:软件模拟IIC从PCF8563指定地址读一个字节函数
unsigned ReadPCF8591(unsigned char Ch)
{ //直接调用本函数即可从PCF8591的Ch通道读出数据返回
unsigned char buf; //定义一个寄存器用来暂存读出的数据
IICstart(); //IIC启动信号
Write1Byte(0x90); //发送PCF8591的器件地址和写信号
Write1Byte(0x40|Ch); //发送器件通道参数Ch=0-3
IICstart(); //IIC启动信号
Write1Byte(0x91); //发送PCF8591的器件地址和读信号
buf=Read1Byte();//读一个字节数据
IICstop(); //产生IIC停止信号
return(buf); //将读出数据返回
}
/*********************************1602数据显示函数88*********************************/
void dis_guangzhao(uchar t)
{
uchar i;
t=t*100/255;
i=t/100;
write_com(0x80+0x07); //显示光照百位
write_data(table[i]);
i=t%100/10;
write_com(0x80+0x08); //显示光照十位
write_data(table[i]);
i=t%100%10;
write_com(0x80+0x09); //显示光照个位
write_data(table[i]);
}
/**************************************************************
主函数
*************************************************************/
void main()
{
unsigned char b=255;
unsigned char a;
init();
init_1602();
delay(1000);
delay(1000);
while(1)
{
delay(1000);
ADbuf1=ReadPCF8591(0); //将AIN0通道A/D转换结果暂存在ADbuf
dis_guangzhao(b-ADbuf1);
delay(1000);
delay(1000); //延时等待
a=b-ADbuf1;
if(a>=80)
{
//init();
delay(1000);
TR0=1;
EA=1;
ET0=1;
hour1=hour/10;
hour2=hour%10;
min1=min/10;
min2=min%10;
sec1=sec/10;
sec2=sec%10;
display(hour1,hour2,min1,min2,sec1,sec2); //一直显示时钟
}
}
}
|