单片机源程序如下:
- #include <reg52.h>//头文件
- #include <intrins.h>
- #include <math.h>
- #define uchar unsigned char//宏定义
- #define uint unsigned short int//宏定义
- #define sint short int
- #define nop _nop_()
- void delay(uint z);//延时1MS
- void delay1(uchar x2);//延时7us左右;
- void write_Directive(uchar a);//写LCD指令
- void write_Data(uchar a);//写LCD数据
- void write_lcd_com_date(uchar addr,uchar date);//实现LCD写指令及数据
- void LCD_init();//LCD初始化
- void start(); //AT24C02开始程序
- void send(uchar send_data);//AT24C02发送一个字节
- uchar receive();//AT24C02接收一个程序
- void ack();//AT24C02是否应答
- void yack();//AT24C02应答
- void nack();//AT24C02无应答
- void stop();//AT24C02停止
- void write(uchar xaddress,sint temp);//AT24C02写入温度
- uint read(uchar daddress);//AT24C02读出温度
- void send_str(sint cc,uchar chflag); // 传送字串
- void DB18B20_init_1();//DB18B20_1复位
- void write_DB18B20_1(uchar dat);//写DB18B20_1
- uchar read_DB18B20_1();//读DB18B20_1
- void DB18B20_init_1();//DB18B20_2复位
- void write_DB18B20_1(uchar dat);//写DB18B20_2
- uchar read_DB18B20_1();//读DB18B20_2
- void tempzh_1(); //温度转换1
- void tempzh_2(); //温度转换2
- void tempread_1(); //读取温度1
- void tempread_2(); //读取温度2
- void temp(sint TEMPS,uchar t,bit fuflag);//显示温度函数
- void readcc(); //读取存储芯片中最高及最低温度
- void keyscan(); //键扫描程序
- void write_ds1302(uchar addr, uchar date);//写DS1302
- uchar read_ds1302(uchar addr);//读DS1302
- void init_ds1302();//DS1302初始化
- void time();//时间显示
- void timekey();//时间部分功能键
- void tempkey();//温度部分功能键
- void shuma(uchar addr,uchar xz,bit flag);//1302调节函数及转换
- void flash(uchar bz);//字符闪烁函数
- void tempbj(); //温度比较
- uchar bdata ch;//定义可位寻址空间,用于24c02的读取
- sbit RS=P1^4;//1602数据/命令选择
- sbit RW=P1^5;//1602读写命令选择
- sbit E=P1^6;//1602使能端
- sbit led=P0^1;//发光二极管
- sbit beep=P0^0;//蜂鸣器
- sbit SDA=P0^2;//24c02数据总线
- sbit SCL=P0^3;//24c02时钟总线
- sbit DQ1=P1^0;//温度传感器1
- sbit DQ2=P3^2;//温度传感器2
- sbit DSIO=P1^2;//1302输入输出口
- sbit DSCLK=P1^1;//1302脉冲
- sbit DSRST=P1^3;//1302复位
- sbit key1=P3^7;//五个按键及其标志
- sbit key2=P0^7;
- sbit key3=P0^6;
- sbit key4=P0^5;
- sbit key5=P0^4;
- bit k1flag=0;
- bit k2flag=0;
- bit k3flag=0;
- bit k4flag=0;
- bit k5flag=0;
- sbit a0=ch^0;//定义ch各位
- sbit a1=ch^1;
- sbit a2=ch^2;
- sbit a3=ch^3;
- sbit a4=ch^4;
- sbit a5=ch^5;
- sbit a6=ch^6;
- sbit a7=ch^7;
- bit fuflag1=0;//负温度标志1
- bit fuflag2=0;//负温度标志2
- bit ackflag=0;//24c02应答是否标志
- bit sendflag=0;//串口发送标志
- sint temps1,temps2,tempd1,tempd2,tempx1,tempx2,uptem1,downtem1,uptem2,downtem2;//温度参数
- uchar count=0,tcount=0,scount=0,t=0;
- uchar secondh,secondl,minuteh,minutel,hourh,hourl,second,minute,hour;//时钟参数
- uchar monthl,monthh,month,dayl,dayh,day,year,yearl,yearh,week;
- uchar code DispTab_1[12]={'0','1','2','3','4','5','6','7','8','9',' ','-'};//1602:0-9 数字
- uchar DispBuf[5]; //5字节的显示缓冲区
- uchar code zzz[] = {"Made In Gao J C"};//定义字符串
- uchar code cc1[4] = {"DQ1:"};
- uchar code cc2[4] = {"DQ2:"};
- uchar code cc3[14] = {"DQ1 is so high"};
- uchar code cc4[13] = {"DQ1 is so low"};
- uchar code cc5[14] = {"DQ2 is so high"};
- uchar code cc6[13] = {"DQ2 is so low"};
- void delay(uint z)//1ms延时
- {
- uchar i;
- while(z--)
- for(i = 120;i > 0;i--);
- }
- void delay1(uchar x2)//短延时,由于18b20
- {
- while(x2--);
- }
- void write_Directive(uchar a)//写LCD指令
- {
- RS = 0;
- RW = 0;
- delay(1);
- E = 0;
- P2 = a;
- delay(1);
- E = 1;
- delay(1);
- E = 0;
- delay(1);
- }
- void write_Data(uchar a)//写LCD数据
- {
- RS = 1;
- RW = 0;
- delay(1);
- E = 0;
- P2 = a;
- delay(1);
- E = 1;
- delay(1);
- E = 0;
- delay(1);
- }
- void write_lcd_com_date(uchar addr,uchar date)//实现LCD写指令及数据
- {
- write_Directive(addr);
- delay(1);
- write_Data(date);
- }
- void LCD_init()//LCD初始化
- {
- uchar i;
- delay(15);
- write_Directive(0x38);
- delay(5);
- write_Directive(0x38);
- delay(5);
- write_Directive(0x38);
- write_Directive(0x01);
- write_Directive(0x02);//光标复位
- write_Directive(0x0c);//不显示光标
- //write_Directive(0x0f);//显示光标
- write_Directive(0x84);//显示字符串
- for(i = 0;i < 7;i++)
- write_Data(zzz[i]);
- write_Directive(0xc3);
- for(i = 8;i < 15;i++)
- write_Data(zzz[i]);
- }
- void start() //AT24C02开始程序
- {
- SCL = 1;
- SDA = 1;
- nop;
- nop;
- SDA = 0;
- nop;
- nop;
- SCL = 0;
- }
- void send(uchar send_data)//AT24C02发送一个字节
- {
- ch = send_data;
- SDA = a7; SCL = 1; nop;nop; SCL = 0;
- SDA = a6; SCL = 1; nop;nop; SCL = 0;
- SDA = a5; SCL = 1; nop;nop; SCL = 0;
- SDA = a4; SCL = 1; nop;nop; SCL = 0;
- SDA = a3; SCL = 1; nop;nop; SCL = 0;
- SDA = a2; SCL = 1; nop;nop; SCL = 0;
- SDA = a1; SCL = 1; nop;nop; SCL = 0;
- SDA = a0; SCL = 1; nop;nop; SCL = 0;
- }
- uchar receive()//AT24C02接收一个程序
- {
- SDA = 1;
- SCL = 1; nop;nop; a7 = SDA; SCL = 0;
- SCL = 1; nop;nop; a6 = SDA; SCL = 0;
- SCL = 1; nop;nop; a5 = SDA; SCL = 0;
- SCL = 1; nop;nop; a4 = SDA; SCL = 0;
- SCL = 1; nop;nop; a3 = SDA; SCL = 0;
- SCL = 1; nop;nop; a2 = SDA; SCL = 0;
- SCL = 1; nop;nop; a1 = SDA; SCL = 0;
- SCL = 1; nop;nop; a0 = SDA; SCL = 0;
- return(ch);
- }
- void ack()//AT24C02是否应答
- {
- SDA = 1;
- SCL = 1;
- nop;
- nop;
- if(SDA)
- ackflag = 1;
- else
- ackflag = 0;
- SCL=0;
- }
- void yack()//AT24C02应答
- {
- SDA = 0;
- SCL = 1;
- nop;
- nop;
- SCL = 0;
- SDA = 1;
- }
- void nack()//AT24C02无应答
- {
- SDA = 1;
- SCL = 1;
- nop;
- nop;
- SCL = 0;
- SDA = 0;
- }
- void stop()//AT24C02停止
- {
- SDA = 0;
- SCL = 1;
- nop;
- nop;
- SDA = 1;
- nop;
- nop;
- SCL = 0;
- SDA = 0;
- }
- void write(uchar xaddress,sint temp)//AT24C02写入温度
- {
- uchar a,b;
- do{
- start();
- send(0xa0);
- ack();
- } while(ackflag);
- do{
- send(xaddress);
- ack();
- }while(ackflag);
- a = temp;
- temp >>= 8;
- b = temp;
- do{
- send(a);
- ack();
- }while(ackflag);
- do{
- send(b);
- ack();
- }while(ackflag);
- stop();
- }
- uint read(uchar daddress)//AT24C02读出温度
- {
- uchar a,b;
- sint temp;
- do{
- start();
- send(0XA0);
- ack();
- }while(ackflag);
- do{
- send(daddress);
- ack();
- }while(ackflag);
- do{
- start();
- send(0XA1);
- ack();
- }while(ackflag);
- a = receive();
- yack();
- b = receive();
- yack();
- nack();
- stop();
- temp = b;
- temp <<= 8;
- temp |= a;
- return temp;
- }
- void send_str(sint cc,uchar chflag) // 传送字串
- {
- uchar i,a,b,ch[4];
- ES=0;
- cc = abs(cc);
- a = cc / 100;
- b = cc % 100;
- ch[1] = b;
- ch[2] = a;
- ch[3] = chflag;
- for(i = 3;i > 0;i--){
- SBUF = ch[i];
- while(!TI); // 等特数据传送
- TI = 0; // 清除数据传送标志
- ES=1;
- }
- }
- /*void serial() interrupt 4
- {a=SBUF;
- RI=0;
- flag=1;
- }
- */
- void DB18B20_init_1()//DB18B20复位
- {
- DQ1 = 1;
- delay1(20);
- DQ1 = 0;
- delay1(80);
- DQ1 = 1;
- delay1(15);
- }
- void write_DB18B20_1(uchar dat)//写DB18B20
- {
- uchar i;
- for(i = 8;i > 0;i--){
- DQ1 = 1;
- delay1(10);
- DQ1 = 0;
- nop;
- DQ1 = dat&0x01;
- delay1(10);
- DQ1 = 1;
- dat >>= 1;
- }
- delay1(7);
- }
- uchar read_DB18B20_1()//读DB18B20
- {
- uchar i,date;
- for(i = 8;i > 0;i--){
- DQ1 = 0;
- date >>= 1;
- DQ1 = 1;
- if(DQ1)
- date |= 0x80;
- delay(4);
- }
- return date;//返回温度值
- }
- void DB18B20_init_2()//DB18B20复位
- {
- DQ2=1;
- delay1(20);
- DQ2=0;
- delay1(80);
- DQ2=1;
- delay1(15);
- }
- void write_DB18B20_2(uchar dat)//写DB18B20
- {
- uchar i;
- for(i = 8;i > 0;i--){
- DQ2 = 1;
- delay1(10);
- DQ2 = 0;
- nop;
- DQ2 = dat&0x01;
- delay1(10);
- DQ2 = 1;
- dat >>= 1;
- }
- delay1(7);
- }
- uchar read_DB18B20_2()//读DB18B20
- {
- uchar i,date;
- for(i = 8;i > 0;i--){
- DQ2 = 0;
- date >>= 1;
- DQ2 = 1;
- if(DQ2)
- date |= 0x80;
- delay(4);
- }
- return date;//返回温度值
- }
- void tempzh_1() //温度转换
- {
- DB18B20_init_1();//DB18B20复位
- write_DB18B20_1(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20_1(0x44);//写DB18B20;0x44 启动温度转换指令
- }
- void tempzh_2() //温度转换
- {
- DB18B20_init_2();//DB18B20复位
- write_DB18B20_2(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20_2(0x44);//写DB18B20;0x44 启动温度转换指令
- }
- void tempread_1()//温度读取
- {
- uint temp;
- uchar a,b;
- fuflag1 = 0;
- DB18B20_init_1();//DB18B20复位
- write_DB18B20_1(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20_1(0xbe);//写DB18B20;0xbe 读温度指令
- a = read_DB18B20_1(); //a为低字节8位
- b = read_DB18B20_1(); //b为高字节8位
- temp = b; //temp为温度值UINT 16bit
- temp <<= 8; //两个字节组合到一起
- temp |= a;//此处可以直接把补码转换过来,只是关于负数标志的问题需要考虑
- if(b > 7){ //判断正负,因为负温度高五位是1,故而可得
- fuflag1 = 1;
- temps1 = (temp*0.0625-4096)*10-0.5;
- }
- else{
- fuflag1 = 0;
- temps1 = temp*0.0625*10+0.5;
- }
- if(tempd1 < temps1){
- tempd1 = temps1;
- write(0x00,tempd1);
- }
- else if(tempx1 > temps1){
- tempx1 = temps1;
- write(0x04,tempx1);
- }
- if(sendflag){
- t++;
- if(t == 5){
- send_str(temps1,1);
- send_str(tempd1,2);
- send_str(tempx1,3);
- }
- }
- }
- void tempread_2()
- {
- uint temp;
- uchar a,b;
- fuflag2 = 0;
- DB18B20_init_2();//DB18B20复位
- write_DB18B20_2(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20_2(0xbe);//写DB18B20;0xbe 读温度指令
- a = read_DB18B20_2(); //a为低字节8位
- b = read_DB18B20_2(); //b为高字节8位
- temp = b; //temp为温度值UINT 16bit
- temp <<= 8; //两个字节组合到一起
- temp |= a;//此处可以直接把补码转换过来,只是关于负数标志的问题需要考虑
- if(b>7){
- fuflag2 = 1;
- temps2=(temp*0.0625-4096)*10-0.5;
- }
- else{
- fuflag2=0;
- temps2=temp*0.0625*10+0.5;
- }
- if(tempd2<temps2){
- tempd2=temps2;
- write(0x08,tempd2);
- }
- else if(tempx2>temps2){
- tempx2=temps2;
- write(0x0c,tempx2);
- }
- if(sendflag){
- if(t == 5){
- t = 0;
- send_str(temps2,4);
- send_str(tempd2,5);
- send_str(tempx2,6);
- }
- }
- }
- void temp(sint temps,uchar t,bit fuflag)//显示温度函数
- {
- uchar i;
- uint mm;
- temps = abs(temps);
- DispBuf[0] = temps / 1000;//显示百位
- mm = temps % 1000;
- DispBuf[1] = mm / 100;//显示十位
- mm = mm % 100;
- DispBuf[2] = mm / 10;//显示个位
- DispBuf[3] = mm % 10;//显示小数点:0.1
- i = DispBuf[0];//百位判断,如果为0,则消隐
- if(i == 0) i = 10;
- if(fuflag)//负温度判断,如果为0,则温度为负的,显示负号
- i = 11;
- DispBuf[0] = DispTab_1[i];//查表,取字符
- i = DispBuf[1];
- DispBuf[1] = DispTab_1[i];
- i = DispBuf[2];
- DispBuf[2] = DispTab_1[i];
- i = DispBuf[3];
- DispBuf[3] = DispTab_1[i];
- i = DispBuf[4];
- DispBuf[4] = DispTab_1[i];
- write_Directive(0x84+t);//第一行,第五个位置地址
- write_Data(DispBuf[0]);//第一行,第五个位置
- write_Data(DispBuf[1]);//第一行,第六个位置
- write_Data(DispBuf[2]);//第一行,第八个位置
- write_Data('.');//第一行,第七个位置
- write_Data(DispBuf[3]);//第一行,第九个位置
- }
- void readcc()//读24c02中最高和最低温度并显示
- {
- bit flag;
- tempd1 = read(0x00);
- if(tempd1 > 0) flag = 0;
- else flag = 1;
- temp(tempd1,0x00,flag);
- tempx1 = read(0x04);
- if(tempx1 > 0) flag = 0;
- else flag=1;
- temp(tempx1,0x06,flag);
- tempd2 = read(0x08);
- if(tempd2 > 0) flag = 0;
- else flag = 1;
- temp(tempd2,0x40,flag);
- tempx2 = read(0x0c);
- if(tempx2 > 0) flag = 0;
- else flag = 1;
- temp(tempx2,0x46,flag);
- }
- void keyscan() //键扫描程序
- {
- bit flag = 0;
- if(!key1){ //按键1
- delay(30);
- if(!key1){
- while(!key1);
- k1flag = 1;
- flag = 1;
- }
- }
- if(!key2){ //按键2
- delay(30);
- if(!key2){
- while(!key2);
- k2flag = 1;
- flag = 1;
- }
- }
- if(!key3){ //按键3
- delay(30);
- if(!key3){
- while(!key3);
- k3flag = 1;
- flag = 1;
- }
- }
- if(!key4){ //按键4
- delay(30);
- if(!key4){
- while(!key4);
- k4flag = !k4flag;
- flag = 1;
- }
- }
- if(!key5){ //按键5
- delay(30);
- if(!key5){
- while(!key5);
- k5flag=!k5flag;
- flag=1;
- write_Directive(0x01);
- }
- }
- if(flag){
- beep=0;
- delay(100);
- beep=1;
- }
- }
- uchar read_ds1302(uchar addr)//读DS1302
- {
- uchar i,temp = 0x00;
- DSRST = 0;
- DSIO = 1;
- DSCLK = 0;
- DSRST = 1;
- for(i = 8;i > 0;i--){ //循环8次 写入地址数据
- DSCLK = 0;
- DSIO = addr&0x01; //每次传输低字节
- addr >>= 1; //右移一位
- DSCLK = 1;
- }
- delay(1);
- if(DSIO)
- temp |= 0x80; //每次传输低字节
- DSCLK = 0;
- temp >>= 1;
- for(i = 7;i > 0;i--){ //循环7次 读取数据此处如果读8次就会出现乱码
- DSCLK = 0;
- if(DSIO)
- temp |= 0x80; //每次传输低字节
- DSCLK = 1;
- temp >>= 1; //右移一位
- }
- DSCLK = 1;
- DSRST = 0;
- DSIO = 0;
- return temp;
- }
- void write_ds1302(uchar addr, uchar date)//写DS1302
- {
- uchar i;
- DSRST = 0;
- DSCLK = 0;
- DSRST = 1;
- for (i = 8;i > 0;i--){ //循环8次 写入地址数据
- DSCLK = 0;
- nop;
- DSIO = addr&0x01; //每次传输低字节
- addr >>= 1; //右移一位
- DSCLK = 1;
- nop;
- }
- for (i = 8;i > 0;i--){ //循环8次 写入数据
- DSCLK = 0;
- nop;
- DSIO = date&0x01; //每次传输低字节
- date >>= 1; //右移一位 DSCLK=1
- DSCLK = 1;
- nop;
- }
- DSRST = 0;
- delay(1);
- }
- void init_ds1302()//DS1302初始化
- {
- write_ds1302(0x8e,0x00);
- write_ds1302(0x90,0xa5);
- /*write_ds1302(0x80,0x00); //00秒
- write_ds1302(0x82,0x54); //54分
- write_ds1302(0x84,0x17); //17点
- write_ds1302(0x86,0x13); //13日
- write_ds1302(0x88,0x03); //3月
- write_ds1302(0x8a,0x05); //星期五
- write_ds1302(0x8c,0x12); //2012年*/
- }
- void time()//时间显示
- {
- write_lcd_com_date(0x81,'2');
- write_lcd_com_date(0x82,'0');
- 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;
- day = read_ds1302(0x87);
- dayl = day & 0x0f;
- dayh = day >> 4;
- week = read_ds1302(0x8b);
- week = week&0x0f;
- write_lcd_com_date(0xca,0x30 + secondl);
- write_lcd_com_date(0xc9,0x30 + secondh);
- write_lcd_com_date(0xc8,':');
- write_lcd_com_date(0xc7,0x30 + minutel);
- write_lcd_com_date(0xc6,0x30 + minuteh);
- write_lcd_com_date(0xc5,':');
- write_lcd_com_date(0xc4,0x30 + hourl);
- write_lcd_com_date(0xc3,0x30 + hourh);
- write_lcd_com_date(0x84,0x30 + yearl);
- write_lcd_com_date(0x83,0x30 + yearh);
- write_lcd_com_date(0x85,'-');
- write_lcd_com_date(0x87,0x30 + monthl);
- write_lcd_com_date(0x86,0x30 + monthh);
- write_lcd_com_date(0x88,'-');
- write_lcd_com_date(0x8a,0x30 + dayl);
- write_lcd_com_date(0x89,0x30 + dayh);
- write_lcd_com_date(0x8c,0x30 + week);
- }
- void shuma(uchar addr,uchar xz,bit flag)
- {
- char date;
- uchar day=0;
- date = read_ds1302(addr + 1); //读分寄存器上的数据
- date = ((date >> 4) * 10) + (date & 0x0f); //BCD Convert to shi
- if(flag == 0) date++;
- else date--;
- switch(xz)
- {
- case 0:if(date > 59) date=0;if(date < 0) date = 59;break;//分秒
- case 1:if(date > 23) date=0;if(date < 0) date = 23;break;//时
- case 2:if(date > 12) date=0;if(date < 0) date = 12;break;//月
- case 3:if(date > 99) date=0;if(date < 0) date = 99;break;//年
- case 4:if(date > 7) date=1;if(date < 1) date = 7;break;//星期
- case 5:
- day = read_ds1302(0X87);
- day = ((day >> 4) * 10) + (day & 0x0f);
- if(day != 2){
- if(day % 2 == 1){
- if(date > 31)
- date = 0;
- else if(date < 0)
- date = 31;
- }
- else{
- if(date > 30)
- date = 0;
- else if(date < 0)
- date = 30;
- }
- }
- else{
- if(date > 29)
- date = 0;
- else if(date < 0)
- date = 29;
- }
- break;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
以上是仿真报错,求大神指导修改一下
所有资料51hei提供下载:
资料.7z
(4.42 MB, 下载次数: 91)
|