万年历的简易设计与仿真
电路原理图如下:
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /***********定义LCD功能管脚************************************/
- sbit rs=P2^0; //控制LCD数据或命令的读写
- sbit rw=P2^1; //控制LCD读写信号
- sbit e=P2^2; //使能LCD
- /***********定义DS1302功能管脚*********************************/
- sbit DSRST = P1^0; //DS1302复位管脚
- sbit DSCLK = P1^1; //DS1302时钟
- sbit DSIO = P1^2; //控制DS1302数据传输
- sbit dq=P3^7; //温度传感器I/O口定义
- uint numh=110,numl=50; //上下限温度
- uchar bai,shi,ge,xiaoshu,fuhao;
- uchar th_temp,tl_temp;
- uchar secondh,secondl,minuteh,minutel,hourh,hourl,second,minute,hour;
- uint monthl,monthh,month,day,datel,dateh,date,year,yearl,yearh;
- void delay_ms(uint z);
- void delay_us(uchar z);
- void lcd1602_init();
- bit judge_lcd();
- void write_com(uchar com);
- void write_date(uchar date);
- void HELLO_lcd();
- void ds18b20_init();
- void write_byte(uchar dat);
- uchar read_byte();
- void display();
- void convert_temp();
- void beyond();
- void ds1302_init();
- uchar read_ds1302();
- void init_ds1302();
- void write_ds1302() ;
- void read1302_write1602 ();
- void HELLO();
- /*********************延时函数*****************/
- void delay_us(uchar z)
- {
- while(z--);
- }
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /********************lcd1602初始化***************************/
- void lcd1602_init()
- {
- write_com(0x01);
- delay_ms(50);
- write_com(0x38);
- delay_ms(50);
- write_com(0x0c);
- delay_ms(50);
- write_com(0x06);
- delay_ms(50);
- }
- /***********************lcd1602忙碌判断子程序*******************/
- bit judge_lcd()
- {
- bit flag;
- e = 0;
- rs = 0;
- rw = 1;
- e = 1;
- delay_ms(1);
- flag=(bit)(P0&0x80); //状态位第7位为1时禁止读写,为0时可读写
- e = 0;
- return flag;
- }
- /**********************lcd1602写指令子程序*******************/
- void write_com(uchar addr)
- {
-
- while(judge_lcd()); //检测LCD是否为忙碌状态
- rs=0;
- rw=0;
- P0=addr;
- delay_us(5);
- e=0;
- delay_us(5);
- e=1;
- delay_us(5);
- e=0;
- }
- /***********************lcd写数据子程序*******************/
- void write_date(uchar date)
- {
- while(judge_lcd()); //检测LCD是否为忙碌状态
- rs=1;
- rw=0;
- P0=date;
- delay_us(5);
- e=0;
- delay_us(5);
- e=1;
- delay_us(5);
- e=0;
- }
- /***********lcd1602写指令及数据********************************/
- void write_com_date(uint addr,uint date)
- {
- write_com(addr);
- delay_ms(1);
- write_date(date);
- }
- /************************DS18B20初始化************************/
- void ds18b20_init()
- {
- dq=1;
- delay_us(2);
- dq=0;
- delay_us(80);
- dq=1;
- delay_us(2);
- delay_us(40);
- }
- /************************ds18b20写数据子程序**********************/
- void write_byte(uchar dat)
- {
- uchar i,value;
- dq=1;
- for(i=0;i<8;i++)
- {
- dq=0;
- value=dat&0x01;
- if(value==0)
- {
- dq=0;
- delay_us(10);
- }
- else
- {
- dq=1;
- delay_us(10);
- }
- dq=1;
- dat=dat>>1;
- }
- }
- /************************ds18b20读数据子程序*********************/
- uchar read_byte()
- {
- uchar i, value;
- dq=1;
- for(i=0;i<8;i++)
- {
- dq=0;
- value=value>>1;
- dq=1;
- delay_us(1);
- if(dq==1)
- value=value|0x80;
- delay_us(10);
- }
- return value;
- }
- /**********************DS1302读数据子程序********************************/
- uchar read_ds1302(uchar addr)
- {
- uchar i,temp=0x00;
- DSRST=0;
- DSIO=1;
- DSCLK=0;
- DSRST=1;
- for (i=0;i<8;i++) //循环8次 写入地址数据
- {
- DSCLK=0;
- DSIO=addr&0x01; //每次传输低字节
- addr>>=1; //右移一位
- DSCLK=1;
- }
- delay_ms(1);
- if(DSIO)
- temp|=0x80; //每次传输低字节
- DSCLK=0;
- temp>>=1;
- for (i=0;i<7;i++) //循环8次 读取数据
- {
- DSCLK=0;
- if(DSIO)
- temp|=0x80; //每次传输低字节
- DSCLK=1;
- temp>>=1; //右移一位
- }
- DSCLK=1;
- DSRST=0;
- DSIO=0;
- return temp; //返回
- }
- /******************ds1302写指令子程序**********************************/
- void write_ds1302(uchar addr, uchar date)
- {
- uchar i;
- DSRST=0;
- DSCLK=0;
- DSRST=1;
- for (i=0;i<8;i++) //循环8次 写入地址数据
- {
- DSCLK=0;
- _nop_();
- DSIO=addr&0x01; //每次传输低字节
- addr>>=1; //右移一位
- DSCLK=1;
- _nop_();
- }
- for (i=0;i<8;i++) //循环8次 写入数据
- {
- DSCLK=0;
- _nop_();
- DSIO=date&0x01; //每次传输低字节
- date>>=1; //右移一位 DSCLK=1
- DSCLK=1;
- _nop_();
- }
- DSRST=0;
- delay_ms(1);
- }
- /*****************ds1302初始化子程序********************************/
- void ds1302_init()
- {
- if((((second=read_ds1302(0x81))>>7)&&0x01)==1) //读秒
- {
- write_ds1302(0x8e,0x00); //关闭写保护
- write_ds1302(0x80,0x00); //00秒
- write_ds1302(0x82,0x54); //54分
- write_ds1302(0x84,0x17); //17点
- write_ds1302(0x86,0x08); //8日
- write_ds1302(0x88,0x06); //6月
- write_ds1302(0x8a,0x05); //星期五
- write_ds1302(0x8c,0x12); //2012年
- write_ds1302(0x8e,0x80); //允许写保护
- }
- }
- /*****************************温度转化与LCD显示部分****************************/
- void convert_temp()
- {
- uint temp_zhen;
- uchar temp_fu;
- ds18b20_init();
- write_byte(0xcc);
- write_byte(0x44);
- delay_ms(300);
- ds18b20_init();
- write_byte(0xcc);
- write_byte(0xbe);
- tl_temp=read_byte();
- th_temp=read_byte();
- if((th_temp&0xf0)!=0xf0)
- {
- fuhao=0x2b; //正数处理
- temp_zhen=th_temp*256+tl_temp;
- temp_zhen=temp_zhen/16;
- temp_zhen=((tl_temp&0xf0)>>4)|(th_temp<<4);
- bai=temp_zhen/100; //将十进制的每一位都拆开
- shi=temp_zhen/10%10;
- ge=temp_zhen%10;
- xiaoshu=(tl_temp&0x0f)*10*0.0625;
- }
- else
- {
- fuhao=0x2d; //负数处理
- temp_fu=((tl_temp&0xf0)>>4)|(th_temp<<4);
- temp_fu=~temp_fu;
- if((tl_temp&0x0f)==0x00)
- {
- temp_fu=temp_fu+1;
- }
- bai=temp_fu/100;
- shi=temp_fu/10%10;
- ge=temp_fu%10;
- xiaoshu=((~(tl_temp&0x0f)&0x0f)+1)*10*0.0625;
- xiaoshu=xiaoshu%10; //精确到小数点后一位
- }
- if(temp_zhen>numh|temp_fu>numl)
- {
- beyond();
- }
- }
- /**********************lcd1602温度显示子程序*********************/
- void display()
- {
- write_com(0xCa);
- write_date(fuhao);
- if(bai!=0) //百位为0不显示
- {
- write_date(bai+0x30);
- write_date(shi+0x30);
- }
- else if(bai==0&&shi!=0)
- {
- write_date(shi+0x30);
- }
- write_date(ge+0x30);
- write_date(0x2e);
- write_date(xiaoshu+0x30);
- write_date(0x43);
- write_date(0x20);
- }
- /**********************初始欢迎界面函数************************/
- void HELLO()
- {
-
- write_com_date(0x85,'H');
- write_com_date(0x86,'E');
- write_com_date(0x87,'L');
- write_com_date(0x88,'L');
- write_com_date(0x89,'O');
- write_com_date(0xc4,'E');
- write_com_date(0xc5,'V');
- write_com_date(0xc6,'E');
- write_com_date(0xc7,'R');
- write_com_date(0xc8,'Y');
- write_com_date(0xc9,'O');
- write_com_date(0xca,'N');
- write_com_date(0xcb,'E');
- delay_ms(1500);
- }
- /********************超过温度上下限子程序***********************/
- void beyond()
- {
- uint temp_zhen;
- uchar temp_fu;
- while(1)
- {
- write_com(0xCA);
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- read1302_write1602();
- if(temp_zhen<=numh||temp_fu<=numl)
- break;
- }
- }
- /************************从ds1302中读时间并在LCD1602上显示***************************/
- void read1302_write1602 ()
- {
- second=read_ds1302(0x81);
- secondl=second&0x0f;
- secondh=second>>4;
- minute=read_ds1302(0x83);
- minutel=minute&0x0f;
- minuteh=minute>>4;
- hour=read_ds1302(0x85);
- hourl=hour&0x0f;
- hourh=hour>>4;
- month=read_ds1302(0x89);
- monthl=month&0x0f;
- monthh=month>>4;
- year=read_ds1302(0x8d);
- yearl=year&0x0f;
- yearh=year>>4;
- date=read_ds1302(0x87);
- datel=date&0x0f;
- dateh=date>>4;
- day=read_ds1302(0x8b);
- day=day&0x0f;
- delay_ms(5);
- write_com_date(0xc7,0x30+secondl);
- write_com_date(0xc6,0x30+secondh);
- write_com_date(0xc5,'-');
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
rl.zip
(123 KB, 下载次数: 44)
|