- #include "reg52.h"
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
- void delay(); //短暂延时
- void start(); //开始信号
- void stop(); //停止信号
- void respons(); //应答
- void init(); //初始化 两条线都拉高
- void write_byte(u8); //写一个字节
- u8 read_byte(); //读一个字节,带带返回值的函数
- void write_add(u8,u8);//写入 指定地址 数据
- u8 read_add(u8); //读出 指定地址 数据
- u8 fanye=0; //定义外部中断1 存数次数标志位,翻页次数
- u8 gg=0; //定义存第几数 ,翻到第几个数
- u16 cc=0; //定义定时器0溢出次数
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit int0=P3^2; //外部中断0,端口
- sbit int1=P3^3; //外部中断1,端口
- sbit scl=P1^3; //时钟线
- sbit sda=P1^4; //数据线
- u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
- u8 ssec,sec,min;
- u8 DisplayData[8];
- u8 qc=0; //定义长按外部中断0 取出保存的数
- u8 zant=0; //暂停开始标志位,外部中断0控制
- /*******************************************************************************
- * 函 数 名 : delay
- * 函数功能 : 延时函数,i=1时,大约延时10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /*******************************************************************************
- * 函 数 名 : Timer0Init
- * 函数功能 : 定时器0初始化
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
- TH0=0Xd8; //给定时器赋初值,定时10ms
- TL0=0Xf0;
- ET0=1;//打开定时器0中断允许
- EA=1;//打开总中断
- TR0=1;//打开定时器
- }
- /*******************************************************************************
- * 函 数 名 : DigDisplay
- * 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
- *******************************************************************************/
- void DigDisplay()
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,
- {
- case(7):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(6):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(5):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(4):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(3):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(2):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(1):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(0):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- P0=DisplayData[i];//发送段码
- delay(100); //间隔一段时间扫描
- P0=0x00;//消隐
- }
- }
- /*************************延时********************************/
- void delayms(u16 x) //延时函数
- {
- u16 p,q;
- for(p=x;p>0;p--)
- for(q=110;q>0;q--);
- }
- void datapros()
- {
- DisplayData[0]=smgduan[ssec%10];
- DisplayData[1]=smgduan[ssec/10];
- DisplayData[2]=0x40;
- DisplayData[3]=smgduan[sec%10];
- DisplayData[4]=smgduan[sec/10];
- DisplayData[5]=0x40;
- DisplayData[6]=smgduan[min%10];
- DisplayData[7]=smgduan[min/10];
- }
- /*******************外部中断0*******************/
- void wbzd0()interrupt 0
- {
- u8 p=0; //判断按键按下的时间
- delayms(20); //消抖
- if(int0==0)
- {
- while(!int0&&p<250) //最多按25秒
- { p++;
- delayms(100);}
- if(p>15) //长按2秒 调出数据,
- {
- qc=1; //主程序开始 读eeprom数据
- TR0=0; //停止定时器工作
- }
- else // 低于两秒
- {
- zant=~zant;
- TR0=zant; //来回反转实现定时器0的启停
- }
- }
- }
- void wbzd1()interrupt 2
- {
- delayms(20); //消抖
- if(int1==0)
- {
- fanye=1; //主程序进入存数据,后跳出,直到下次按键按下
- gg++; //用于判断存数据位,和读数据位,在不同的位置实现的功能不同
- if(gg==5)
- {gg=1;}
- while(!int1); //按键不松,程序不往下执行
- }
- }
- void T0_time()interrupt 1 //八位自动装填
- {
- cc++;
- if(cc>=400) //0.1秒到来
- {
- cc=0;
- ssec++;
- }
- }
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- Timer0Init(); //定时器0初始化
- while(1)
- { IT0=1; //外部0低电平触发
- EX0=1; //开外部中断0
- IT1=1; //外部1低电平触发
- EX1=1; //开外部中断1
- ET0=1; //开定时器0
- EA=1; // 开总中断
-
- IP=0x04; //外部1优先
- datapros();
- DigDisplay();
- /**************************按键处理*************************/
- if(fanye==1) //存数据 判断外部中断1是否按下
- {
- switch(gg) //通过gg的值“按第几下”,存到不同的位置
- {
- case 1:
- init();
- write_add(0x01,DisplayData[0]);
- init();
- write_add(0x02,DisplayData[1]);
- init();
- write_add(0x03,DisplayData[2]);
- init();
- write_add(0x04,DisplayData[3]);
- init();
- write_add(0x05,DisplayData[4]);
- init();
- write_add(0x06,DisplayData[5]);
- break;
- /* case 2:
- init();
- write_add(0x03,num0);
- init();
- write_add(0x04,num1);
- break;
- case 3:
- init();
- write_add(0x05,num0);
- init();
- write_add(0x06,num1);
- break;
- case 4:
- init();
- write_add(0x07,num0);
- init();
- write_add(0x08,num1);
- break; */
- }
- fanye=0; //退出存数,直到下次外部中断1到来
- }
- if(qc==1) //判断外部中断0长按键 开始读存进EEPROM的数据
- {
- while(1)
- {
- switch(gg) //通过判断外部中断1,按键次数gg实现翻页功能
- { //因为又进入到现在这个大循环 所以外部中断1中的
- case 1: //fanye=1;不能在返回上面控制 存第几个数据了,相当与无用
- init();
- DisplayData[0]=read_add(0x01);
- init();
- DisplayData[1]=read_add(0x02);
- init();
- DisplayData[2]=read_add(0x03);
- init();
- DisplayData[3]=read_add(0x04);
- init();
- DisplayData[4]=read_add(0x05);
- init();
- DisplayData[5]=read_add(0x06);
- break;
- /*case 2:
- init();
- num0=read_add(0x03);
- init();
- num1=read_add(0x04);
- break;
- case 3:
- init();
- num0=read_add(0x05);
- init();
- num1=read_add(0x06);
- break;
- case 4:
- init();
- num0=read_add(0x07);
- init();
- num1=read_add(0x08);
- break; */
- }
- /*mb[0]=num1%10; //秒表个位
- mb[1]=num1/10; //秒表十位
- mb[2]=num0; */
- //display(num0,num1); //程序将在此一直判断gg,实现翻页,显示存的数据
- } //若想再次计数,按下单片机的RST复位键,程序重头执行
- }
- }
- }
-
- /*******************************************************************************
- * 函 数 名 : void Timer0() interrupt 1
- * 函数功能 : 定时器0中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0=0Xd8; //给定时器赋初值,定时10ms
- TL0=0Xf0;
- ssec++;
- if(ssec>=100) //1s
- {
- ssec=0;
- sec++;
- if(sec>=60)
- {
- sec=0;
- min++;
- if(min>=60)
- {
- min=0;
- }
- }
- }
- }
- /*void delay2()
- {;;} */
-
- void start() //开始信号
- {
- sda=1;
- delay2();
- scl=1;
- delay2();
- sda=0;
- delay2();
- }
- void stop() //停止信号
- {
- sda=0;
- delay2();
- scl=1;
- delay2();
- sda=1;
- delay2();
- }
- void respons() //应答
- {
- u8 i;
- scl=1;
- delay2();
- while((sda==1)&&(i<250)) //防止一直没有收到应答,程序停止
- {i++;}
- scl=0;
- delay2();
- }
- void init() //初始化 两条线都拉高
- {
- sda=1;
- delay2();
- scl=1;
- delayms(1); //加延时,否则用不了
- }
- void write_byte(u8 date) //写一个字节
- {
- u8 i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- delay2();
- sda=CY; //最高位移入PSW寄存器中CY位中
- delay2(); //将CY中的值赋给sda
- scl=1;
- delay2();
- }
- scl=0;
- delay2();
- sda=1;
- delay2();
- }
- u8 read_byte() //读一个字节,带带返回值的函数
- {
- u8 i,k;
- scl=0;
- delay2();
- sda=1;
- delay2();
- for(i=0;i<8;i++)
- {
- scl=1;
- delay2();
- k=(k<<1)|sda; //将K左移一位后与sda进行或运算,
- scl=0; //依次把8个位放入一个字节中来完成接收
- delay2();
- }
- return k; //返回值为k
- }
- void write_add(u8 address,u8 date) //写入 指定地址 数据
- {
- start();
- write_byte(0xa0); //接下来为写操作
- respons();
- write_byte(address); //送入地址
- respons();
- write_byte(date); //写入数据
- respons();
- stop();
- delayms(1); //加延时,否则用不了
- }
- u8 read_add(u8 address) //读出 指定地址 数据
- {
- u8 date;
- start();
- write_byte(0xa0); //接下来为写操作
- respons();
- write_byte(address); //送入地址 ,下面读数据的地址
- respons();
- start();
- write_byte(0xa1); //接下来为读操作 存储器发送数据
- respons();
- date=read_byte(); //把SDA数据线上的数据用date存
- stop();
- return date;
- delayms(1); //加延时,
- }
复制代码
|