据说他

#include <AT89x51.h>#include <string.h>#include<intrins.h> #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};//延时//液晶模块引脚定义#define LCM_RS P2_0 //定义引脚#define LCM_RW P2_1#define LCM_E P2_2#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识//******* 1602LCD驱动 **********************************************************void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);unsigned char ReadStatusLCM(void);void LCMInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);void Delay5Ms(void); void Delay400Ms(void); //*********** DS1302 时间显示定义部分sbit T_CLK=P1^0;sbit T_IO =P1^1;sbit T_RST=P1^2;sbit ACC0=ACC^0;sbit ACC7=ACC^7;void Set(unsigned char,unsigned char); //根据选择调整相应项目void RTInputByte(unsigned char); /* 输入 1Byte */unsigned char RTOutputByte(void); /* 输出 1Byte */void W1302(unsigned char, unsigned char); // 向DS1302写入一个字节unsigned char R1302(unsigned char); // 从DS1302读出一个字节void Set1302(unsigned char * ); // 设置时间 bit sec,min,hour,year,mon,day,weekk; //闪烁标志位//初始化后设置为:04年12月2日星期4 0点0分0秒unsigned char inittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04}; //初始时间 //显示部分unsigned char id;//根据id号选择对应的操作unsigned char timecount;//定时器计数unsigned char dipsmodid; //显示模式bit lmcinit_or_not; //是否需要清屏标志位“1”为需要“0”为不需要bit flag; //flag是时钟冒号闪烁标志void Disp0_line1(void);void Disp0_line2(void);void id_case1_key();void id_case2_key();void Disp_mod0(void);//显示模式0void Disp_mod1(void);//显示模式1//*******闹钟控制部分*********char alarmid; void Set_Time(void); sbit BEEP=P3^6; //蜂鸣器sbit JDQ=P3^7; //继电器bit alarm_hour = 0; //定时小时闪烁标志位bit alarm_min = 0; //定时分钟闪烁标志位bit alarm_timer = 0; //定时开关闪烁标志位bit clock_long = 0; //定时时间长短闪烁标志位void beep(); //蜂鸣器响一下void Delay1MS();void clock_to_time(); //当闹铃改变时,将新的闹铃时间写入寄存器(闹铃到什么时候停止) unsigned char code alarm[] = {"Alarm:"};unsigned int hour_min1;//定时时间转换成数字unsigned int hour_min_now;//现在时间转换成数字unsigned int hour_min2;//定时终止时间转换成数字//AD引脚定义及转换部分#define PCF8591_WRITE 0x90 #define PCF8591_READ 0x91sbit SCL=P3^2; // 将p3.2口模拟时钟口sbit SDA=P3^3; // 将p3.3口模拟数据口bit askflag;bit bdata SystemError; //从机错误标志位unsigned char receivebuf; //数据接收 void iic_start(void);void iic_stop(void);void iicInit(void);void slave_ACK(void);void slave_NOACK(void);void check_ACK(void);void IICSendByte(unsigned char ch);unsigned char IICreceiveByte(void);void ADC_PCF8591(unsigned char controlbyte);void show_value(unsigned char ad_data); //将读到的数转换成电压 void show_V(); //在液晶上显示电压 unsigned int data dis[4]={0x00,0x00,0x00}; //定义3个显示数据单元void main(void){ Delay400Ms(); //启动等待,等LCM讲入工作状态 LCMInit(); //LCM初始化 Delay5Ms(); //延时片刻(可不要) TMOD=0x01; TH0=(65535-50000)/256; TL0=(65535-50000)%256; EA=1; TR0=1; ET0=1; W1302(0x90,0xa5);//打开充电二级管 一个二级管串联一个2K电阻 W1302(0x8e,0x00); W1302(0xc2,0); W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ while(1) { iicInit(); //I2C总线初始化 ADC_PCF8591(0x06); if(SystemError == 1) //有错误,重新来 { iicInit(); //I2C总线初始化 ADC_PCF8591(0x06); }if (P1_7==0) {dipsmodid++; lmcinit_or_not=1; if(dipsmodid>1) dipsmodid=0; while(P1_7==0); } switch(dipsmodid) { case 0: Disp_mod0(); break; case 1: Disp_mod1(); break; }hour_min1=R1302(0xc5)*100+R1302(0xc7);hour_min_now=R1302(0x85)*100+R1302(0x83); hour_min2=R1302(0xcb)*100+R1302(0xcd);if(R1302(0xc3)==1) //闹铃是否打开,0xc3为读闹铃寄存器地址。 { if(hour_min2>=hour_min_now&&hour_min1<=hour_min_now)JDQ=0;else if((hour_min2>=hour_min_now&&hour_min1>=hour_min_now&&hour_min1>=hour_min2)||(hour_min2<=hour_min_now&&hour_min1<=hour_min_now&&hour_min1>=hour_min2)) JDQ=0; else JDQ=1; }if(R1302(0xc3)==0)JDQ=1; if(receivebuf < 107){beep();JDQ=1;} }}void beep() //蜂鸣器响一声函数{ unsigned char i; for(i = 0;i < 100;i++) { Delay1MS(); Delay1MS(); Delay1MS(); Delay1MS(); Delay1MS(); BEEP=!BEEP; //BEEP取反 }}//显示模式0void Disp_mod0(void){ if(lmcinit_or_not==1) {LCMInit(); lmcinit_or_not=0; } if ((P1_4|P1_5)==0) //初始化 { Delay5Ms(); if ((P1_4|P1_5)==0) Set1302(inittime);//复位 } if (P1_6==0) // 设置和选择项目键 { Delay5Ms(); if(P1_6==0){id++;if(id>7) id=0;} while(P1_6==0); } switch(id) { case 0: clock_long = 0; sec=0; Disp0_line1(); Disp0_line2(); break; case 1://小时 sec=0;hour=1; Disp0_line1(); Disp0_line2(); id_case1_key(); break; case 2://分钟 hour=0;min=1; Disp0_line1(); Disp0_line2(); id_case1_key(); break; case 3://秒 min=0;sec=1; Disp0_line1(); Disp0_line2(); id_case1_key(); break; case 4://定时时间——小时 sec=0; alarm_hour = 1;Disp0_line1(); Disp0_line2(); id_case1_key(); break; case 5://定时时间——分钟 alarm_hour = 0;alarm_min = 1;Disp0_line1(); Disp0_line2(); id_case1_key(); break; case 6://定时器开关 alarm_min = 0;alarm_timer = 1;Disp0_line1(); Disp0_line2(); id_case1_key(); break;case 7://定时时间长短 clock_long = 1;alarm_timer = 0;Disp0_line1(); Disp0_line2(); id_case1_key(); break; }}//显示模式1void Disp_mod1(void){ if(lmcinit_or_not==1) {LCMInit(); lmcinit_or_not=0; } DisplayOneChar(0,0,'N'); show_V(); DisplayOneChar(9,0,'L'); DisplayOneChar(10,0,R1302(0xc1)/16+0x30); DisplayOneChar(11,0,R1302(0xc1)%16+0x30); DisplayOneChar(12,0,':'); DisplayOneChar(13,0,'0'); DisplayOneChar(14,0,'0'); DisplayOneChar(15,0,'V'); DisplayOneChar(0,1,'R'); DisplayOneChar(1,1,'V'); DisplayOneChar(2,1,':'); DisplayOneChar(3,1,'1'); DisplayOneChar(4,1,'0'); DisplayOneChar(5,1,'0'); DisplayOneChar(6,1,'%'); DisplayOneChar(8,1,'W'); DisplayOneChar(9,1,'K'); DisplayOneChar(10,1,'3'); DisplayOneChar(11,1,'2'); DisplayOneChar(12,1,'0'); DisplayOneChar(13,1,'m'); DisplayOneChar(14,1,'i'); DisplayOneChar(15,1,'n'); id_case2_key(); }//中断入口,冒号闪烁void t0(void) interrupt 1 using 0{ TH0=(65535-50000)/256; //50ms定时 TL0=(65535-50000)%256; timecount++; if(timecount>9) { timecount=0; flag=~flag; } }//模式0下的按键处理程序void id_case1_key(){ if (P1_5==0) //增加 { Delay5Ms(); if(P1_5==0) Set(id,0); if(id<8) while(P1_5==0); } if (P1_4==0) //减少 { Delay5Ms(); if(P1_4==0) Set(id,1); if(id<8) while(P1_4==0); }}//模式1下的按键处理程序void id_case2_key(){ if (P1_5==0) //增加 { Delay5Ms(); if(P1_5==0) Set(8,0); while(P1_5==0); } if (P1_4==0) //减少 { Delay5Ms(); if(P1_4==0) Set(8,1); while(P1_4==0); }}//根据选择调整相应项目并写入DS1302void Set(unsigned char sel,unsigned char sel_1) { signed char address,item; signed char max,mini; if(sel==3) {address=0x80; max=0;mini=0;} //秒 if(sel==2) {address=0x82; max=59;mini=0;} //分钟 if(sel==1) {address=0x84; max=23;mini=0;} //小时 if(sel==4) {address=0xc4; max=23;mini=0;} //闹铃时寄存器 if(sel==5) {address=0xc6; max=59;mini=0;} //闹铃分寄存器 if(sel==6) {address=0xc2; max=1;mini=0;} //闹铃开关寄存器 if(sel==7) {address=0xc8; max=60;mini=1;} //闹铃时间长短寄存器 if(sel==8) {address=0xc0; max=12;mini=0;} //电压最小值设置寄存器 item=R1302(address+1)/16*10+R1302(address+1)%16; if (sel_1==0) item++; else item--; if(item>max) item=mini; if(item<mini) item=max; W1302(0x8e,0x00);//允许写操作 W1302(address,item/10*16+item%10); W1302(0x8e,0x80);//写保护,禁止写操作 }//屏幕显示第一行 时间void Disp0_line1(void) { // show_V(); DisplayOneChar(13,0,'m'); DisplayOneChar(14,0,'i'); DisplayOneChar(15,0,'n'); //冒号闪烁 if(flag==0) {DisplayOneChar(2,0,0x3a); DisplayOneChar(5,0,0x3a);} else {DisplayOneChar(2,0,0x20); DisplayOneChar(5,0,0x20);} if(sec==1) //秒闪烁标志位 { if(flag==1) { DisplayOneChar(6,0,R1302(0x81)/16+0x30); //显示秒 DisplayOneChar(7,0,R1302(0x81)%16+0x30); } else { DisplayOneChar(6,0,0x20); //显示秒 DisplayOneChar(7,0,0x20); } } else { DisplayOneChar(6,0,R1302(0x81)/16+0x30); //显示秒 DisplayOneChar(7,0,R1302(0x81)%16+0x30); } if(min==1) //分钟闪烁标志位 { if(flag==1) { DisplayOneChar(3,0,R1302(0x83)/16+0x30); //显示分钟 DisplayOneChar(4,0,R1302(0x83)%16+0x30); } else { DisplayOneChar(3,0,0x20); //显示分钟 DisplayOneChar(4,0,0x20); } } else { DisplayOneChar(3,0,R1302(0x83)/16+0x30); //显示分钟 DisplayOneChar(4,0,R1302(0x83)%16+0x30); } if(hour==1) //小时闪烁标志位 { if(flag==1) { DisplayOneChar(0,0,R1302(0x85)/16+0x30);//显示小时 DisplayOneChar(1,0,R1302(0x85)%16+0x30); } else { DisplayOneChar(0,0,0x20); //显示小时 DisplayOneChar(1,0,0x20); } } else { DisplayOneChar(0,0,R1302(0x85)/16+0x30);//显示小时 DisplayOneChar(1,0,R1302(0x85)%16+0x30); } if(clock_long == 1) //闹钟长短闪烁标志位 { if(flag==1) { if(R1302(0xc9)/16==0)DisplayOneChar(10,0,' ');//显示闹钟长短elseDisplayOneChar(10,0,R1302(0xc9)/16+0x30);//显示闹钟长短 DisplayOneChar(11,0,R1302(0xc9)%16+0x30);DisplayOneChar(12,0,'0'); } else { DisplayOneChar(9,0,0x20); //显示空格字符 DisplayOneChar(10,0,0x20); DisplayOneChar(11,0,0x20); DisplayOneChar(12,0,0x20); } } else { if(R1302(0xc9)/16==0)DisplayOneChar(10,0,0x20);//显示闹钟长短elseDisplayOneChar(10,0,R1302(0xc9)/16+0x30);//显示闹钟长短 DisplayOneChar(11,0,R1302(0xc9)%16+0x30);DisplayOneChar(12,0,'0'); }}void Disp0_line2(void){ DisplayListChar(0,1,alarm); DisplayOneChar(8,1,':'); if(alarm_hour==1) //时闪烁标志位 { if(flag==1) { DisplayOneChar(6,1,R1302(0xc5)/16+0x30);//显示时 DisplayOneChar(7,1,R1302(0xc5)%16+0x30); } else { DisplayOneChar(6,1,0x20); //显示空格字符 DisplayOneChar(7,1,0x20); } } else { DisplayOneChar(6,1,R1302(0xc5)/16+0x30);//显示时 DisplayOneChar(7,1,R1302(0xc5)%16+0x30); } if(alarm_min==1) //分闪烁标志位 { if(flag==1) { DisplayOneChar(9,1,R1302(0xc7)/16+0x30);//显示分 DisplayOneChar(10,1,R1302(0xc7)%16+0x30); } else { DisplayOneChar(9,1,0x20); //显示空格字符 DisplayOneChar(10,1,0x20); } } else { DisplayOneChar(9,1,R1302(0xc7)/16+0x30);//显示分 DisplayOneChar(10,1,R1302(0xc7)%16+0x30); } if(alarm_timer==1) //开关闪烁标志位 { if(flag==1) { if(R1302(0xc3)%16 == 1){DisplayOneChar(13,1,'O');//显示开 DisplayOneChar(14,1,'N');DisplayOneChar(15,1,' ');}else{DisplayOneChar(13,1,'O');//显示关 DisplayOneChar(14,1,'F');DisplayOneChar(15,1,'F');} } else { DisplayOneChar(13,1,0x20); //显示空格字符 DisplayOneChar(14,1,0x20); DisplayOneChar(15,1,0x20); }} else { if(R1302(0xc3)%16 == 1){DisplayOneChar(13,1,'O');//显示开 DisplayOneChar(14,1,'N');DisplayOneChar(15,1,' ');}else{DisplayOneChar(13,1,'O');//显示关 DisplayOneChar(14,1,'F');DisplayOneChar(15,1,'F');} } clock_to_time(); //当闹铃改变时,将新的闹铃时间写入寄存器}//延时1MSvoid Delay1MS(){ unsigned char i; for(i = 115;i>0;i--);}//定时至什么时候void clock_to_time(){ unsigned char shi,fen,dingshi; shi = R1302(0xc5)/16*10+ R1302(0xc5)%16; fen = R1302(0xc7)/16*10+ R1302(0xc7)%16; dingshi = R1302(0xc9)/16*10+ R1302(0xc9)%16; fen = fen + dingshi*10; shi += fen/60; shi = shi%24; fen = fen %60; W1302(0x8e,0x00);//允许写操作 W1302(0xca,shi/10*16+shi%10); W1302(0xcc,fen/10*16+fen%10); W1302(0x8e,0x80);//写保护,禁止写操作 }//********* LCM1602驱动程序 ***************//写数据void WriteDataLCM(unsigned char WDLCM){ ReadStatusLCM(); //检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在这后加小的延时 LCM_E = 0; //延时 LCM_E = 1;}//写指令void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{ if (BuysC) ReadStatusLCM(); //根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; }//读状态unsigned char ReadStatusLCM(void){ LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); //检测忙信号 return(LCM_Data);}//LCM初始化void LCMInit(void) { LCM_Data = 0; WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号 Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(0x08,1); //关闭显示 WriteCommandLCM(0x01,1); //显示清屏 WriteCommandLCM(0x06,1); // 显示光标移动设置 WriteCommandLCM(0x0C,1); // 显示开及光标设置}//按指定位置显示一个字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){ Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40; X |= 0x80; //算出指令码 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码 WriteDataLCM(DData);}//按指定位置显示一串字符 ***原来的遇到空格0x20就不显示***void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){ unsigned char ListLength,j; ListLength = strlen(DData); Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (X <= 0xF) //X坐标应小于0xF { for(j=0;j<ListLength;j++) { DisplayOneChar(X, Y, DData[j]); //显示单个字符 X++; } }}//5ms延时void Delay5Ms(void){ unsigned int TempCyc = 5552; while(TempCyc--);}//400ms延时void Delay400Ms(void){ unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); };}//********DS1302读写程序***************/******************************************************************** 函 数 名:RTInputByte() 功 能:实时时钟写入一字节 说 明:往DS1302写入1Byte数据 (内部函数) 入口参数:d 写入的数据 返 回 值:无 ***********************************************************************/void RTInputByte(unsigned char d) { unsigned char i; ACC = d; for(i=8; i>0; i--) { T_IO = ACC0; /*相当于汇编中的 RRC */ T_CLK = 1; T_CLK = 0; ACC = ACC >> 1; } }/******************************************************************** 函 数 名:RTOutputByte() 功 能:实时时钟读取一字节 说 明:从DS1302读取1Byte数据 (内部函数) 入口参数:无 返 回 值:ACC 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/unsigned char RTOutputByte(void) { unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; /*相当于汇编中的 RRC */ ACC7 = T_IO; T_CLK = 1; T_CLK = 0; } return(ACC); }/******************************************************************** 函 数 名:W1302() 功 能:往DS1302写入数据 说 明:先写地址,后写命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: DS1302地址, ucData: 要写的数据 返 回 值:无 ***********************************************************************/void W1302(unsigned char ucAddr, unsigned char ucDa){ T_RST = 0; T_CLK = 0; T_RST = 1; RTInputByte(ucAddr); /* 地址,命令 */ RTInputByte(ucDa); /* 写1Byte数据*/ T_CLK = 1; T_RST = 0;}/******************************************************************** 函 数 名:R1302() 功 能:读取DS1302某地址的数据 说 明:先写地址,后读命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: DS1302地址 返 回 值:ucData :读取的数据***********************************************************************/unsigned char R1302(unsigned char ucAddr){ unsigned char ucData; T_RST = 0; T_CLK = 0; T_RST = 1; RTInputByte(ucAddr); /* 地址,命令 */ ucData = RTOutputByte(); /* 读1Byte数据 */ T_CLK = 1; T_RST = 0; return(ucData);}/******************************************************************** 函 数 名:Set1302() 功 能:设置初始时间 说 明:先写地址,后读命令/数据(寄存器多字节方式) 调 用:W1302() 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 返 回 值:无***********************************************************************/void Set1302(unsigned char *pClock) { unsigned char i; unsigned char ucAddr = 0x80; W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ for(i =7; i>0; i--) { W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ pClock++; ucAddr +=2; } W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ }//-------------------------------------------------------------------// 函数名称: iic_start()// 函数功能: 启动I2C总线子程序//-------------------------------------------------------------------void iic_start(void){ //时钟保持高,数据线从高到低一次跳变,I2C通信开始SDA = 1; SCL = 1;delayNOP(); // 延时5us SDA = 0;delayNOP(); SCL = 0;}//-------------------------------------------------------------------// 函数名称: iic_stop()// 函数功能: 停止I2C总线数据传送子程序//-------------------------------------------------------------------void iic_stop(void){ SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止SCL = 1;delayNOP();SDA = 1;delayNOP(); SCL = 0;}//------------------------------------------------------------------// 函数名称: iicInit_()// 函数功能: 初始化I2C总线子程序//------------------------------------------------------------------void iicInit(void) { SCL = 0; iic_stop(); } //-------------------------------------------------------------------// 函数名称: slave_ACK// 函数功能: 从机发送应答位子程序//-------------------------------------------------------------------void slave_ACK(void){SDA = 0; SCL = 1;delayNOP();SCL = 0;}//-------------------------------------------------------------------// 函数名称: slave_NOACK// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束//-------------------------------------------------------------------void slave_NOACK(void){ SDA = 1;SCL = 1;delayNOP();SDA = 0; SCL = 0; }//-------------------------------------------------------------------// 函数名称: check_ACK// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束//-------------------------------------------------------------------void check_ACK(void){ SDA = 1; // 将p1.1设置成输入,必须先向端口写1SCL = 1;askflag = 0;delayNOP(); if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志askflag askflag = 1; SCL = 0;}//-------------------------------------------------------------------// 函数名称: IICSendByte// 入口参数: ch// 函数功能: 发送一个字节//-------------------------------------------------------------------void IICSendByte(unsigned char ch) { unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位while(n--){ if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1 {SDA = 1; // 传送位1SCL = 1; delayNOP();// SDA = 0;SCL = 0; }else{ SDA = 0; // 否则传送位0SCL = 1;delayNOP(); SCL = 0;}ch = ch<<1; // 数据左移一位}}//-------------------------------------------------------------------// 函数名称: IICreceiveByte// 返回接收的数据// 函数功能: 接收一字节子程序//-------------------------------------------------------------------unsigned char IICreceiveByte(void){unsigned char idata n=8; // 从SDA线上读取一上数据字节,共八位unsigned char tdata=0;while(n--){ SDA = 1; SCL = 1; tdata =tdata<<1; //左移一位 if(SDA == 1) tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1else tdata = tdata&0xfe; // 否则数据的最后一位置0 SCL = 0;}return(tdata);}//-------------------------------------------------------------------// 函数名称: ADC_PCF8591// 入口参数: controlbyte控制字// 函数功能: 连续读入4路通道的A/D转换结果到receivebuf//-------------------------------------------------------------------void ADC_PCF8591(unsigned char controlbyte){ iic_start();IICSendByte(PCF8591_WRITE); //控制字check_ACK();if(askflag == 1){SystemError = 1;return;} IICSendByte(controlbyte); //控制字check_ACK();if(askflag == 1){SystemError = 1;return;} iic_start(); //重新发送开始命令 IICSendByte(PCF8591_READ); //控制字check_ACK();if(askflag == 1){SystemError = 1;return;} IICreceiveByte(); //空读一次,调整读顺序 slave_ACK(); //收到一个字节后发送一个应答位 receivebuf=IICreceiveByte(); slave_ACK(); //收到一个字节后发送一个应答位slave_NOACK(); //收到最后一个字节后发送一个非应答位iic_stop(); }// 将读取的数值转换成实际电压值void show_value(unsigned char ad_data){ unsigned char temp;dis[3]=ad_data/17/10 + '0'; //整数部分,转换为ACSII码 dis[2]=ad_data/17%10 + '0'; //整数部分,转换为ACSII码 temp=ad_data%17*10; dis[1]=temp/17+'0'; //小数点后第一位 temp=temp%17*10; //小数点后第二位dis[0]=temp/17+'0';}void show_V() //在液晶上显示电压{ show_value(receivebuf); //显示通道2 if(dis[3]>0) DisplayOneChar(1,0,dis[3]); DisplayOneChar(2,0,dis[2]); DisplayOneChar(3,0,'.'); DisplayOneChar(4,0,dis[1]); DisplayOneChar(5,0,dis[0]); DisplayOneChar(6,0,'V'); }

评论