/***********************************************
* 12864+1302+dh11
***********************************************/
#include <reg51.h> //头文件
#include <intrins.h>
#include <ds1302.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
/*TS12864A-3 端口定义*/
#define LCD_data P0 //数据口
sbit LCD_RS = P3^5; //寄存器选择输入
sbit LCD_RW = P3^6; //液晶读/写控制
sbit LCD_EN = P3^4; //液晶使能控制
sbit LCD_PSB = P3^7; //串/并方式控制sbit DATA=P1^1; //dh11口定义
sbit Beep = P1^2; //蜂鸣器
uchar ucStatus;
uint uiCount;
uint uiStatus;
uchar mun_char_table[]={"0123456789"};
uchar RHL,RHH,CL,CH;
uint m,n,flag=0;
void lcd_pos(uchar X,uchar Y); //确定显示位置
void My_T0(void); //定时器初始化
void Xianshi(void); //滚动文字
void LCDWrituenumber(uchar x,uchar y,uchar ucDAT);
void LCDWritueString(uchar x,uchar y,uchar *str) ;
void delayus(uchar n);
void Delay10ms(void);
void delay_ms(uint z);
uint integer(uchar x);
uchar readdht11_byte();
void read_dht11();
void wenxian(void); //温度显示+固定字 数
//*************************************************//
// LCD12864模块 //
//*************************************************//
void delay(int ms) //LCD12864延时函数
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*******************************************************************/
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/*******************************************************************/
//bit lcd_busy()
// {
//
// bit result;
// P0=0X00; //关掉数码管的信号。阻止数码管受到P0口信号的影响
// LCD_RS = 0;
// LCD_RW = 1;
// LCD_EN = 1;
// delay(1);
// result = (bit)(P0&0x80);
// LCD_EN = 0;
// return(result);
// }
/*******************************************************************/
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
// while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delay(1);
LCD_EN = 1;
delay(1);
LCD_EN = 0;
}
/*******************************************************************/
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
// while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delay(1);
LCD_EN = 1;
delay(1);
LCD_EN = 0;
}
/*******************************************************************/
/* LCD初始化设定 */
/*******************************************************************/
void lcd_init()
{
LCD_PSB = 1; //并口方式
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
///////////////////*********///////////////////////////
//* 主程序 *//
///////////////////*********////////////////////////*//
void main()
{
SYSTEMTIME CurrentTime; //系统时间 当前时间
Initial_DS1302(); //DS1302初始化
lcd_init(); //初始化LCD
My_T0(); //定时器初始化
while(1)
{
Xianshi(); //文字滚动
wenxian(); //温度显示
if(flag == 1)
{
DS1302_GetTime(&CurrentTime); //ds1302主函数中有什么就粘贴复制过去
DateToStr(&CurrentTime); //将日期格式转换为字符串函数
TimeToStr(&CurrentTime); //将时间格式转换为字符串
LCDWrituenumber(0,1,CurrentTime.Hour); //在第1行第1位显示当前时间的时
LCDWrituenumber(0,3,CurrentTime.Minute);//在第1行第3位显示当前时间的分
LCDWrituenumber(0,5,CurrentTime.Second);//在第1行第5位显示当前时间的秒
LCDWrituenumber(1,1,CurrentTime.Year); //在第2行第2位显示当前时间的年
LCDWrituenumber(1,3,CurrentTime.Month); //在第2行第4位显示当前时间的月
LCDWrituenumber(1,5,CurrentTime.Day); //在第2行第6位显示当前时间的日
}
}
}
/*********************************************************
* 写字符
**********************************************************/
void LCDWritueString(uchar x,uchar y,uchar *str) //固定格式
{
uchar i;
lcd_pos(x,y);
i = 0;
while(str[i] != '\0')
{
lcd_wdat(str[i]); //显示字符
i++;
}
}
/*********************************************************
* 写字符串
*********************************************************/
void LCDWrituenumber(uchar x,uchar y,uchar ucDAT)
{
lcd_pos(x,y);
lcd_wdat((ucDAT / 10)+ 48);
lcd_wdat((ucDAT % 10) + 48);
}
///////////////////************///////////////////
//* 设定显示位置 *//
///////////////////************///////////////////
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if (X==0)
{X=0x80;}
else if (X==1)
{X=0x90;}
else if (X==2)
{X=0x88;}
else if (X==3)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //显示地址
}
///////////////////*******///////////////////
// 定时器T0初始化 //
//////////////////*********//////////////////
void My_T0(void)
{
TMOD = 0x01;
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
//////////////////*******////////////////////
// 定时器服务函数 //
/////////////////*********///////////////////
void Tim0()interrupt 1
{
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
uiCount++;
uiStatus++;
if(uiStatus == 4000)
{
uiStatus = 0;
ucStatus = 8;
flag = 1;
}
}
//**************************************//
// 显示函数 //
//**************************************//
void Xianshi(void)
{
switch(ucStatus)
{
case 0:LCDWritueString(0,0,"大学生单片机竞赛");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 1;
}
break;
case 1:LCDWritueString(0,0," ");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 2;
}
break;
case 2:LCDWritueString(1,2,"H001组");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 3;
}
break;
case 3:LCDWritueString(1,2," ");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 4;
}
break;
case 4:LCDWritueString(2,2,"只因追求");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 5;
}
break;
case 5:LCDWritueString(2,2," ");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 6;
}
break;
case 6:LCDWritueString(3,2,"源于热爱");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 7;
}
break;
case 7:LCDWritueString(3,2," ");
if(uiCount >= 500)
{
uiCount = 0;
ucStatus = 0;
}
break;
}
}
///////////////////////////////////////////////////
//* 温湿度模块 *//
///////////////////////////////////////////////////
void delayus(uchar n) //很重要的延时
{
while(n--);
}
void Delay10ms(void) //很重要的延时
{
uchar a,b; //12M晶振下延时
for(b=249;b>0;b--)
for(a=17;a>0;a--);
}
void delay_ms(uint z) //粗延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=614;y>0;y--);
}
void Start(void) //起始
{
DATA=1;
delay_ms(10);
DATA=0;
Delay10ms(); //主机把总线拉低必须大于18msDHT11能检测到起始信号
Delay10ms();
Delay10ms();
DATA=1;
delay_ms(1);
}
uint integer(uchar x)
{
uchar h,l;
uint n;
l=x&0x0f;
h=(x&0xf0)>>4;
n=h*16+l;
return n;
}
uchar readdht11_byte()
{
uchar i,dht;
for(i=8;i>0;i--)
{
dht=dht<<1;
while(!DATA); //等待50ms
delayus(30); //延时29us
if(DATA==1)
{
dht=dht|0x01;
delayus(60);
}
else
delayus(30); //延时29us
}
return(dht);
}
void read_dht11()
{
Start();
DATA=0; //数据线拉低>18ms
delay_ms(20); //延时>18ms
DATA=1; //拉高等待
delayus(30); //延时29us
DATA=1;
if(!DATA)
{
while(!DATA);
while(DATA);
RHH=readdht11_byte();//湿度整数数据
RHL=readdht11_byte();//湿度小数数据
CH=readdht11_byte();//温度整数数据
CL=readdht11_byte();//温度小数数据
}
}
void wenxian(void)
{
if(flag == 1)
{
LCDWritueString(0,2," -");
LCDWritueString(0,4," -");
LCDWritueString(1,0,"20");
LCDWritueString(1,2,"年");
LCDWritueString(1,4,"月");
LCDWritueString(1,6,"日");
LCDWritueString(2,0,"温度:");
LCDWritueString(3,0,"湿度:");
read_dht11();
m=integer(RHH);
delay_ms(1);
n=integer(CH);
lcd_pos(2,3);
lcd_wdat(mun_char_table[n/10]);
lcd_wdat(mun_char_table[n%10]);
lcd_pos(3,3);
lcd_wdat(mun_char_table[m/10]);
lcd_wdat(mun_char_table[m%10]);
}
}
|