|
- #include<reg52.h> // 包含51單片機寄存器定義的頭文件
- #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
- sbit SCL=P3^4; //將串行時鐘總線SCL位定義在為P3.4引腳
- sbit SDA=P3^5; //將串行數(shù)據(jù)總線SDA位定義在為P3.5引腳
- sbit P26=P2^6; //十位選通定義
- sbit P27=P2^7; //個位選通定義
- sbit K5=P1^4; //清0按鍵
- unsigned char sec=0; //定義計數(shù)值,每過1秒,sec加1
- unsigned char count=0; //定時中斷次數(shù)
- bit write=0; //寫24C08的標(biāo)志;
- unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//定義共陽數(shù)碼管顯示字型碼
- void delay1ms(unsigned int n) //1ms延時
- {
- unsigned char i;
- while(n--)
- for(i=0;i<115;i++);
- }
- void Start() //起始信號
- {
- SDA=1; //SDA初始化為高電平“1”
- SCL=1; //開始數(shù)據(jù)傳送時,要求SCL為高電平“1”
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA=0; //SDA的下降沿被認為是開始信號
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL=0; //SCL為低電平時,SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞)
- }
-
- void Stop() //終止信號
- {
- SDA=0; //SDA初始化為低電平“0”
- SCL=1; //!!!!注意,SDA和SCL的順序不能顛倒,否則錯誤,切記
- _nop_(); //結(jié)束數(shù)據(jù)傳送時,要求SCL為高電平“1”
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA=1; //SDA的上升沿被認為是結(jié)束信號
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL=0;
- SDA=0;
- }
- bit Ask() //應(yīng)答信號
- {
- bit res;
- SDA=1; // 發(fā)送設(shè)備(主機)應(yīng)在時鐘脈沖的高電平期間(SCL=1)釋放SDA線,
- //以讓SDA線轉(zhuǎn)由接收設(shè)備(AT24Cxx)控制
- _nop_(); //等待一個機器周期
- _nop_(); //等待一個機器周期
- SCL=1; //根據(jù)上述規(guī)定,SCL應(yīng)為高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- res=SDA; //接受設(shè)備(AT24Cxx)向SDA送低電平,表示已經(jīng)接收到一個字節(jié)
- //若送高電平,表示沒有接收到,傳送異常 結(jié)束發(fā)送
- SCL=0; //SCL為低電平時,SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞
- return res;
- }
- unsigned char ReadData() // 從24C08移入數(shù)據(jù)到MCU
- {
- unsigned char i;
- unsigned char x; //儲存從AT24Cxx中讀出的數(shù)據(jù)
- for(i = 0; i < 8; i++)
- {
- SCL = 1; //SCL置為高電平
- x<<=1; //將x中的各二進位向左移一位
- x|=(unsigned char)SDA; //將SDA上的數(shù)據(jù)通過按位“或“運算存入x中
- SCL = 0; //在SCL的下降沿讀出數(shù)據(jù)
- }
- return(x); //將讀取的數(shù)據(jù)返回
- }
- void WriteCurrent(unsigned char y) //向當(dāng)前地址寫入數(shù)據(jù)
- {
- unsigned char i;
- for(i = 0; i < 8; i++) // 循環(huán)移入8個位
- {
- SDA = (bit)(y&0x80); //通過按位“與”運算將最高位數(shù)據(jù)送到S
- //因為傳送時高位在前,低位在后
- _nop_(); //等待一個機器周期
- SCL = 1; //在SCL的高電平將數(shù)據(jù)寫入AT24Cxx
- _nop_(); //等待一個機器周期
- _nop_(); //等待一個機器周期
- SCL = 0; //將SCL重新置為低電平,以在SCL線形成傳送數(shù)據(jù)所需的8個脈沖
- y<<= 1; //將y中的各二進位向左移一位
-
- }
- }
- void WriteSet(unsigned char add, unsigned char dat) // 在指定地址add處寫入數(shù)據(jù)WriteCurrent
- {
- Start(); //開始數(shù)據(jù)傳遞
- WriteCurrent(0xa0); //選擇要操作的24C08芯片,并告知要對其寫入數(shù)據(jù)
- Ask();
- WriteCurrent(add); //寫入指定地址
- Ask();
- WriteCurrent(dat); //向當(dāng)前地址(上面指定的地址)寫入數(shù)據(jù)
- Ask();
- Stop(); //停止數(shù)據(jù)傳遞
- delay1ms(4); //1個字節(jié)的寫入周期為1ms, 最好延時1ms以上
- }
- unsigned char ReadCurrent() //向當(dāng)前地址讀數(shù)據(jù)
- {
- unsigned char x;
- Start(); //開始數(shù)據(jù)傳遞
- WriteCurrent(0xa1); //選擇要操作的AT24Cxx芯片,并告知要讀其數(shù)據(jù)
- Ask();
- x=ReadData(); //將讀取的數(shù)據(jù)存入x
- Stop(); //停止數(shù)據(jù)傳遞
- return x; //返回讀取的數(shù)據(jù)
- }
- unsigned char ReadSet(unsigned char set_addr) // 在指定地址讀取
- {
- Start(); //開始數(shù)據(jù)傳遞
- WriteCurrent(0xa0); //選擇要操作的AT24Cxx芯片,并告知要對其寫入數(shù)據(jù)
- Ask();
- WriteCurrent(set_addr); //寫入指定地址
- Ask();
- return(ReadCurrent()); //從指定地址讀出數(shù)據(jù)并返回
- }
- void LedShow() //LED顯示函數(shù)
- {
- P0=table[sec/10];
- P26=0;
- delay1ms(2);
- P26=1;
- P0=table[sec%10];
- P27=0;
- delay1ms(2);
- P27=1;
- }
-
- void main()
- {
- TMOD=0x01; //定時器0工作在方式1
- ET0=1;
- EA=1;
- TH0=(65536-50000)/256; //對TH0 TL0賦值
- TL0=(65536-50000)%256; //使定時器0.05秒中斷一次
- SDA = 1; // SDA=1,SCL=1,使主從設(shè)備處于空閑狀態(tài)
- SCL = 1;
- sec=ReadSet(2);//讀出保存的數(shù)據(jù)賦于sec
- TR0=1; //開始計時
- while(1)
- {
- LedShow();
- if(write==1) //判斷計時器是否計時一秒
- {
- write=0; //清零
- WriteSet(2,sec); //在24c08的地址2中寫入數(shù)據(jù)sec
- }
- if(K5==0){
- delay1ms(10);
- if(K5==0){
- sec=0;
- }
- }
- }
- }
- void t0() interrupt 1 //定時中斷服務(wù)函數(shù)
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
-
- if(count==20){
- count=0;
- write=1;
- sec++;
- if(sec==100)
- sec=0;
- }
- }
復(fù)制代碼
|
|