|
- #include "reg52.h"
- typedef unsigned int u16; //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
- typedef unsigned char u8;
- void delay(); //短暫延時(shí)
- void start(); //開始信號(hào)
- void stop(); //停止信號(hào)
- void respons(); //應(yīng)答
- void init(); //初始化 兩條線都拉高
- void write_byte(u8); //寫一個(gè)字節(jié)
- u8 read_byte(); //讀一個(gè)字節(jié),帶帶返回值的函數(shù)
- void write_add(u8,u8);//寫入 指定地址 數(shù)據(jù)
- u8 read_add(u8); //讀出 指定地址 數(shù)據(jù)
- u8 fanye=0; //定義外部中斷1 存數(shù)次數(shù)標(biāo)志位,翻頁(yè)次數(shù)
- u8 gg=0; //定義存第幾數(shù) ,翻到第幾個(gè)數(shù)
- u16 cc=0; //定義定時(shí)器0溢出次數(shù)
- 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; //時(shí)鐘線
- sbit sda=P1^4; //數(shù)據(jù)線
- 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; //定義長(zhǎng)按外部中斷0 取出保存的數(shù)
- u8 zant=0; //暫停開始標(biāo)志位,外部中斷0控制
- /*******************************************************************************
- * 函 數(shù) 名 : delay
- * 函數(shù)功能 : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Timer0Init
- * 函數(shù)功能 : 定時(shí)器0初始化
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD|=0X01;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動(dòng)。
- TH0=0Xd8; //給定時(shí)器賦初值,定時(shí)10ms
- TL0=0Xf0;
- ET0=1;//打開定時(shí)器0中斷允許
- EA=1;//打開總中斷
- TR0=1;//打開定時(shí)器
- }
- /*******************************************************************************
- * 函 數(shù) 名 : DigDisplay
- * 函數(shù)功能 : 數(shù)碼管動(dòng)態(tài)掃描函數(shù),循環(huán)掃描8個(gè)數(shù)碼管顯示
- *******************************************************************************/
- void DigDisplay()
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- switch(i) //位選,選擇點(diǎn)亮的數(shù)碼管,
- {
- 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];//發(fā)送段碼
- delay(100); //間隔一段時(shí)間掃描
- P0=0x00;//消隱
- }
- }
- /*************************延時(shí)********************************/
- void delayms(u16 x) //延時(shí)函數(shù)
- {
- 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; //判斷按鍵按下的時(shí)間
- delayms(20); //消抖
- if(int0==0)
- {
- while(!int0&&p<250) //最多按25秒
- { p++;
- delayms(100);}
- if(p>15) //長(zhǎng)按2秒 調(diào)出數(shù)據(jù),
- {
- qc=1; //主程序開始 讀eeprom數(shù)據(jù)
- TR0=0; //停止定時(shí)器工作
- }
- else // 低于兩秒
- {
- zant=~zant;
- TR0=zant; //來(lái)回反轉(zhuǎn)實(shí)現(xiàn)定時(shí)器0的啟停
- }
- }
- }
- void wbzd1()interrupt 2
- {
- delayms(20); //消抖
- if(int1==0)
- {
- fanye=1; //主程序進(jìn)入存數(shù)據(jù),后跳出,直到下次按鍵按下
- gg++; //用于判斷存數(shù)據(jù)位,和讀數(shù)據(jù)位,在不同的位置實(shí)現(xiàn)的功能不同
- if(gg==5)
- {gg=1;}
- while(!int1); //按鍵不松,程序不往下執(zhí)行
- }
- }
- void T0_time()interrupt 1 //八位自動(dòng)裝填
- {
- cc++;
- if(cc>=400) //0.1秒到來(lái)
- {
- cc=0;
- ssec++;
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : main
- * 函數(shù)功能 : 主函數(shù)
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- void main()
- {
- Timer0Init(); //定時(shí)器0初始化
- while(1)
- { IT0=1; //外部0低電平觸發(fā)
- EX0=1; //開外部中斷0
- IT1=1; //外部1低電平觸發(fā)
- EX1=1; //開外部中斷1
- ET0=1; //開定時(shí)器0
- EA=1; // 開總中斷
-
- IP=0x04; //外部1優(yōu)先
- datapros();
- DigDisplay();
- /**************************按鍵處理*************************/
- if(fanye==1) //存數(shù)據(jù) 判斷外部中斷1是否按下
- {
- switch(gg) //通過(guò)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; //退出存數(shù),直到下次外部中斷1到來(lái)
- }
- if(qc==1) //判斷外部中斷0長(zhǎng)按鍵 開始讀存進(jìn)EEPROM的數(shù)據(jù)
- {
- while(1)
- {
- switch(gg) //通過(guò)判斷外部中斷1,按鍵次數(shù)gg實(shí)現(xiàn)翻頁(yè)功能
- { //因?yàn)橛诌M(jìn)入到現(xiàn)在這個(gè)大循環(huán) 所以外部中斷1中的
- case 1: //fanye=1;不能在返回上面控制 存第幾個(gè)數(shù)據(jù)了,相當(dāng)與無(wú)用
- 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; //秒表個(gè)位
- mb[1]=num1/10; //秒表十位
- mb[2]=num0; */
- //display(num0,num1); //程序?qū)⒃诖艘恢迸袛鄃g,實(shí)現(xiàn)翻頁(yè),顯示存的數(shù)據(jù)
- } //若想再次計(jì)數(shù),按下單片機(jī)的RST復(fù)位鍵,程序重頭執(zhí)行
- }
- }
- }
-
- /*******************************************************************************
- * 函 數(shù) 名 : void Timer0() interrupt 1
- * 函數(shù)功能 : 定時(shí)器0中斷函數(shù)
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0=0Xd8; //給定時(shí)器賦初值,定時(shí)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() //開始信號(hào)
- {
- sda=1;
- delay2();
- scl=1;
- delay2();
- sda=0;
- delay2();
- }
- void stop() //停止信號(hào)
- {
- sda=0;
- delay2();
- scl=1;
- delay2();
- sda=1;
- delay2();
- }
- void respons() //應(yīng)答
- {
- u8 i;
- scl=1;
- delay2();
- while((sda==1)&&(i<250)) //防止一直沒有收到應(yīng)答,程序停止
- {i++;}
- scl=0;
- delay2();
- }
- void init() //初始化 兩條線都拉高
- {
- sda=1;
- delay2();
- scl=1;
- delayms(1); //加延時(shí),否則用不了
- }
- void write_byte(u8 date) //寫一個(gè)字節(jié)
- {
- 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() //讀一個(gè)字節(jié),帶帶返回值的函數(shù)
- {
- u8 i,k;
- scl=0;
- delay2();
- sda=1;
- delay2();
- for(i=0;i<8;i++)
- {
- scl=1;
- delay2();
- k=(k<<1)|sda; //將K左移一位后與sda進(jìn)行或運(yùn)算,
- scl=0; //依次把8個(gè)位放入一個(gè)字節(jié)中來(lái)完成接收
- delay2();
- }
- return k; //返回值為k
- }
- void write_add(u8 address,u8 date) //寫入 指定地址 數(shù)據(jù)
- {
- start();
- write_byte(0xa0); //接下來(lái)為寫操作
- respons();
- write_byte(address); //送入地址
- respons();
- write_byte(date); //寫入數(shù)據(jù)
- respons();
- stop();
- delayms(1); //加延時(shí),否則用不了
- }
- u8 read_add(u8 address) //讀出 指定地址 數(shù)據(jù)
- {
- u8 date;
- start();
- write_byte(0xa0); //接下來(lái)為寫操作
- respons();
- write_byte(address); //送入地址 ,下面讀數(shù)據(jù)的地址
- respons();
- start();
- write_byte(0xa1); //接下來(lái)為讀操作 存儲(chǔ)器發(fā)送數(shù)據(jù)
- respons();
- date=read_byte(); //把SDA數(shù)據(jù)線上的數(shù)據(jù)用date存
- stop();
- return date;
- delayms(1); //加延時(shí),
- }
復(fù)制代碼
|
|