- #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); //加延時,
- }
復制代碼
|