|
#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相關(guān)I/O設(shè)置
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;//設(shè)置8位的寄存器用來暫存A/D轉(zhuǎn)換結(jié)果
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顯示函數(shù)
*************************************************************/
void write_com(uchar com) //寫命令函數(shù)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //寫數(shù)據(jù)函數(shù)
{
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上顯示數(shù)據(jù)位置
{
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啟動信號函數(shù)
void IICstart(void)
{
SDA=1; //先將SDA=1,以準(zhǔn)備在SCL=1時,將SDA=0
SCL=1; //時鐘總線拉高
_nop_(); //略做延時
_nop_(); //略做延時
SDA=0; //SCL=1時,將SDA拉低即產(chǎn)生啟動信號
_nop_(); //略做延時
_nop_(); //略做延時
SCL=0; //將SCL=0,完成啟動信號操作
}
//名稱:IIC停止信號函數(shù)
void IICstop(void)
{
SDA=0; //先將SDA=0,以準(zhǔn)備在SCL=1時,將SDA=1
SCL=1; //時鐘總線拉高
_nop_(); //略做延時
_nop_(); //略做延時
SDA=1; //SCL=1時,將SDA拉高即產(chǎn)生停止信號
_nop_(); //略做延時
_nop_(); //略做延時
SCL=0; //將SCL=0,完成啟動信號操作
}
//名稱:向IIC總線寫入1個字節(jié)函數(shù)
void Write1Byte(unsigned char Buf1)
{
unsigned char k; //1個字節(jié)要分8次寫入,需要定義一個寄存器用來計數(shù)
for(k=0;k<8;k++) //做一個8次的循環(huán),每次寫入1位,需要寫8次
{
if(Buf1&0x80) //從最高位開始寫
{
SDA=1; //如果欲寫入數(shù)據(jù)為1,就將數(shù)據(jù)線置1
}
else
{
SDA=0; //如果欲寫入數(shù)據(jù)為0,就將數(shù)據(jù)線寫0
}
_nop_(); //略做延時
_nop_(); //略做延時
SCL=1; //時鐘線做一個上升沿,將一位數(shù)據(jù)寫入
Buf1=Buf1<<1; //數(shù)據(jù)左移一位,將下次要寫入的位數(shù)據(jù)移到最高位
_nop_(); //略做延時
SCL=0; //將SCL=0,以準(zhǔn)備通過上升沿將數(shù)據(jù)寫入
_nop_(); //略做延時
}
SDA=1; //將SDA=1,準(zhǔn)備讀應(yīng)答信號
_nop_(); //略做延時
SCL=1; //將SCL=1,做個上升沿準(zhǔn)備讀應(yīng)答信號
_nop_(); //略做延時
_nop_(); //略做延時
SCL=0; //將SCL=0,結(jié)束應(yīng)答信號讀操作
}
//名稱:從IIC總線讀入1個字節(jié)函數(shù)
unsigned char Read1Byte(void)
{
unsigned char k; //1個字節(jié)要分8次讀出,需要定義一個寄存器用來計數(shù)
unsigned char t=0; //定義一個寄存器用保存讀出數(shù)據(jù)
for(k=0;k<8;k++) //做一個8次的循環(huán),每次讀入1位,需要讀8次
{
t=t<<1; //數(shù)據(jù)左移一位,空出最低位以準(zhǔn)備保存讀入的一位數(shù)據(jù)
SDA=1; //將SDA寫1準(zhǔn)備讀
SCL=1; //將SCL=1,做個上升沿準(zhǔn)備讀一位數(shù)據(jù)
_nop_(); //略做延時
_nop_(); //略做延時
if(SDA==1) //讀一位數(shù)據(jù),并判斷
{
t=t|0x01; //如果讀入數(shù)據(jù)為1,就將接收緩沖區(qū)最低一位置1
}
else
{
t=t&0xfe; //如果讀入數(shù)據(jù)為0,就將接收緩沖區(qū)最低一位寫0
}
SCL=0; //SCL恢復(fù)為0,結(jié)束一位數(shù)據(jù)讀操作
_nop_(); //略做延時
_nop_(); //略做延時
}
return t; //將讀入的一個字節(jié)返回
}
//名稱:軟件模擬IIC向PCF8591指定地址寫一個字節(jié)函數(shù)
void WritePCF8591(unsigned char Databuf)
{ //直接調(diào)用本函數(shù)即可啟動PCF8591的D/A轉(zhuǎn)換
IICstart(); //IIC啟動信號
Write1Byte(0x90); //發(fā)送PCF8591的器件地址和寫信號
Write1Byte(0x40); //發(fā)送器件子地址
Write1Byte(Databuf); //發(fā)送數(shù)據(jù)
IICstop(); //產(chǎn)生IIC停止信號
}
//名稱:軟件模擬IIC從PCF8563指定地址讀一個字節(jié)函數(shù)
unsigned ReadPCF8591(unsigned char Ch)
{ //直接調(diào)用本函數(shù)即可從PCF8591的Ch通道讀出數(shù)據(jù)返回
unsigned char buf; //定義一個寄存器用來暫存讀出的數(shù)據(jù)
IICstart(); //IIC啟動信號
Write1Byte(0x90); //發(fā)送PCF8591的器件地址和寫信號
Write1Byte(0x40|Ch); //發(fā)送器件通道參數(shù)Ch=0-3
IICstart(); //IIC啟動信號
Write1Byte(0x91); //發(fā)送PCF8591的器件地址和讀信號
buf=Read1Byte();//讀一個字節(jié)數(shù)據(jù)
IICstop(); //產(chǎn)生IIC停止信號
return(buf); //將讀出數(shù)據(jù)返回
}
/*********************************1602數(shù)據(jù)顯示函數(shù)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]);
}
/**************************************************************
主函數(shù)
*************************************************************/
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轉(zhuǎn)換結(jié)果暫存在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); //一直顯示時鐘
}
}
}
|
|