原帖由 辛昕 于 2012-4-19 02:08 发表 U8 ClearFlag; //我说的那个标志 U8 Counter; //你想要的那个计数器 /* Operation on read out ClearFlag from EEPROM */ if(ClearFlag != 0x55) { Counter = 0; ClearFlag = 0x55; /* Operation on ...
#include<reg52.h>sbit dula=P2^6; //数码管段选sbit wela=P2^7; //数码位选选sbit SDA=P2^0; //IIC数据线sbit SCL=P2^1; //IIC时钟线unsigned char aa,bb,shi,ge,flag,num1;//-------数码管数字显示表----//unsigned char code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//------uS级延时函数----//void delay(){;;}//-----mS级延时函数----//void delay1(unsigned char x){unsigned char a,b;for(a=x;a>0;a--)for(b=100;b>0;b--);} //--------IIC总线函数----//void start() //IIC总线起始{SDA=1;delay();SCL=1;delay();SDA=0;delay();}void writebyte(unsigned char writedata) //IIC写字节{unsigned char temp,i;temp=writedata;for(i=0;i<8;i++){ SCL=0; delay();temp=temp<<1;SDA=CY;delay();SCL=1;delay(); } SCL=0; delay();SDA=1; delay(); } unsigned char readbyte() //IIC读字节{unsigned char i,j;for(i=0;i<8;i++){SCL=0;delay();j=(j<<1)|SDA;delay();SCL=1;delay(); }return j;}void ACK() //IIC应答{unsigned char i;SCL=0;delay();if(SDA==1&&i<250){i++;}SCL=1;delay();SCL=0;delay();}void stop() //IIC总线结束{SDA=0;delay();SCL=1;delay();SDA=1;}//-------数码管显示函数--------//void display(unsigned char one,unsigned char two){ if(bb==1){P0=0x00; //消隐dula=1;P0=table[one];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;}if (bb==2){ dula=1;P0=table[two];dula=0;P=0xff;wela=1;P0=0xfd;wela=0; bb=0;}}//---------初始化函数----------//void init(){ TMOD=0x11; //开定时器0和1TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=(65536-1000)/256;TL1=(65536-1000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=1;start(); //读EEPROM的0x03地址空间,即标志位的值存放的空间writebyte(0xa0);ACK();writebyte(0x03);ACK();start();writebyte(0xa1);ACK();flag=readbyte();stop();if(flag!=0x99) //标志位flag,判断,如果是第一次上电,给0x08地址初始化值0x00;疑问发源地2。{start(); writebyte(0xa0);ACK();writebyte(0x08);ACK();writebyte(0x00);ACK();stop(); delay1(10);start(); //同时给标志位flag赋值=判断的值,防止下次上电再初始化00.writebyte(0xa0);ACK();writebyte(0x03);ACK();writebyte(0x99); //标志位的判断换成0x96,0x94之类的都会有BUG,重新上电后总是从23开始计数ACK();stop(); } start(); //如果不是第一次上电,则读取0x08里面的值num1(0x08是真正数据存储地址,不是标志位地址)writebyte(0xa0);ACK();writebyte(0x08);ACK();start();writebyte(0xa1);ACK();num1=readbyte();stop();}//-----主函数--------//void main(){init();while(1){ start(); //每执行一次while循环都把计数值num1写入0x08地址中,方便重新上电后读取,继续计数。writebyte(0xa0);ACK();writebyte(0x08);ACK();writebyte(num1);ACK();stop(); shi=num1/10; //两位数码管十位个位值的计算ge=num1%10;display(shi,ge);}}//-----定时器0中断,负责计数值加加以及清零-----//void timer0 () interrupt 1{TH0=(65536-10000)/256;TL0=(65536-10000)%256;aa++;if(aa==100){aa=0;num1++;}if(num1>=100) //疑问发源地1。。。{num1=0;}}//-----定时器1中断,负责数码管现实中需要的延时,满足视觉暂留------//void timer1 () interrupt 3{TH1=(65536-1000)/256;TL1=(65536-1000)%256;bb++;}复制代码
[ 本帖最后由 qrswll 于 2012-4-20 10:10 编辑 ]