|
- #include<reg51.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define AT24C02_ADDRESS 0xA0 //0xA0 1010 00000寫地址
- uint Count;
- uint Set_Count;
- uint Num_L;
- uint Num_H;
- uint num1;
- char num2=0;
- sbit I2C_SCL= P1^6;
- sbit I2C_SDA= P1^7;
- sbit Start_Dianji=P3^0; //電機(jī)啟動(dòng)_dianji
- sbit forward=P3^1; //正轉(zhuǎn)檢測
- //sbit back=P3^1; //反轉(zhuǎn)檢測
- sbit run=P3^7; //運(yùn)行信號(hào)
- sbit jia_up=P1^0;// 增加鍵
- sbit jian_down=P1^1;//減少鍵
- sbit yiwei_up=P1^2; //移位鍵
- sbit qingling=P1^3; //清零鍵
- uchar code ledcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共陰數(shù)碼管編碼0-9 modtable={ {0,0,0,0},{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} ,{1,1,1,1} }
- uchar data Ledbuff[]={0, 0, 0, 0, 0, 0, 0, 0};//顯示緩沖區(qū)
- unsigned char n = 0, n_50ms; //添加閃爍.n=數(shù)碼管移動(dòng)位數(shù)
- bit flag; //添加閃爍
- #define I2CDelay_us(){_nop_();_nop_();_nop_();_nop_();}//voidI2CDelay_us
- /***********************
- AT24C初始化I2C_init
- *************************/
- void I2C_init()
- {
- I2C_SCL=1;
- I2C_SDA=1;//首先確保SCL SDA都是高電平
- }
- /***********************
- 產(chǎn)生總線起始信號(hào)I2C_Start
- *************************/
- void I2C_Start(void )
- {
- I2C_SDA=1;//首先確保SCL SDA都是高電平
- I2C_SCL=1; //確保SCL高電平
- I2C_SDA=0;//先在SCL為高時(shí)拉低SDA,即為起始信號(hào)
- I2C_SCL=0; //在拉低 SCL,鉗住I2C總線準(zhǔn)備發(fā)送或接收數(shù)據(jù)
- }
- /***********************
- 產(chǎn)生總線停止信號(hào):先拉低SDA在拉低SCL
- *************************/
- void I2C_Stop(void )
- {
- I2C_SDA=0;//首先確保SCL SDA都是低電平
- I2C_SCL=1; //先拉高 SCL
- I2C_SDA=1;//在拉高 SDA
- }
- /*******************************************************************************
- *@brief I2C發(fā)送一個(gè)字節(jié)數(shù)據(jù)
- *@param Byte要發(fā)送的字節(jié)
- *@retval 無
- 起始信號(hào)后必須送一個(gè)從機(jī)地址(7)位,1-7位為要接收器件的地址,第八位讀寫位0發(fā)送1接收,第9位ACK應(yīng)答位,
- 緊接著為第一個(gè)數(shù)據(jù)字節(jié),然后一位應(yīng)答位ACK后面繼續(xù)第二個(gè)數(shù)據(jù)字節(jié)
- **********************************************************************************/
- void I2C_SendByte(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- I2C_SDA=Byte&(0x80>>i); //1000 0000右移 i個(gè)位
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- }
- /***********************************************************************************************
- *@brief I2C讀取 接收一個(gè)字節(jié)
- *@param 無
- *@retval 讀取 接收到的一個(gè)字節(jié)數(shù)據(jù)
- ********************************************************************************************/
- unsigned char I2C_ReceiveByte(void)
- {
- unsigned char i,Byte=0x00;//
- I2C_SDA=1; //
- for(i=0;i<8;i++)
- {
- I2C_SCL=1; //先拉高 SCL
- if(I2C_SDA){Byte |= (0x80>>i); }
- I2C_SCL=0; //SCL
- }
- return Byte;
- }
- /*********************
- *@brief I2C發(fā)送應(yīng)答Ack
- *@param AckBit應(yīng)答位 0為應(yīng)答(成功) 1為非應(yīng)答(失敗)
- *@retval 無
- ************************/
- void I2C_SendAck(unsigned char AckBit)
- {
- I2C_SDA=AckBit;
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- /*********************
- *@brief I2C接收應(yīng)答位
- *@param 無
- *@retval AckBit應(yīng)答位 0為應(yīng)答(成功) 1為非應(yīng)答(失敗)
- ************************/
- unsigned char I2C_ReceiveAck(void)
- {
- unsigned char AckBit;
- I2C_SDA=1;
- I2C_SCL=1; //先拉高 SCL
- AckBit=I2C_SDA;
- I2C_SCL=0; //SCL
- I2C_SDA=1;//少此行錯(cuò)誤不能讀取
- return AckBit; //返回值
- }
- /**********向AT24C寫數(shù)據(jù)***********
- *@brief AT24C寫入一個(gè)字節(jié)
- *@param WordAddress要寫入字節(jié)的地址
- *@param Data要寫入的數(shù)據(jù)
- *@retval無
- 寫多字節(jié)時(shí),寫入一個(gè)字節(jié)。在寫一個(gè)字節(jié)前,必須延時(shí)5ms
- ************************/
- void AT24C_WriteByte(unsigned char WordAddress,Data)
- {
- I2C_Start();//啟動(dòng)總線
- I2C_SendByte(AT24C02_ADDRESS);//發(fā)送寫操作地址+寫數(shù)據(jù)(0xa0)
- I2C_ReceiveAck(); //等待應(yīng)答
- I2C_SendByte(WordAddress);//要寫入的地址
- I2C_ReceiveAck(); //等待應(yīng)答完成
- I2C_SendByte(Data); //要寫入的數(shù)據(jù),第一字節(jié) ,第二字節(jié)注意:每個(gè)字節(jié)都回應(yīng)一個(gè)應(yīng)答位0,如果沒有回應(yīng)說明寫入不成功
- I2C_ReceiveAck(); //等待完成 注意:每個(gè)字節(jié)都回應(yīng)一個(gè)應(yīng)答位0,如果沒有回應(yīng)說明寫入不成功
- I2C_Stop(); //發(fā)送結(jié)束信號(hào):停止總線
- }
- /************從AT24C中讀出數(shù)據(jù)*********
- *@brief AT24C讀取一個(gè)字節(jié)
- *@param WordAddress要讀出字節(jié)的地址
- *@param 無
- *@retval要讀出的數(shù)據(jù)
- ************************/
- unsigned char AT24C_ReadByte(unsigned char WordAddress) //void
- {
- unsigned char Data;
- I2C_Start(); //發(fā)送起始信號(hào):啟動(dòng)總線
- I2C_SendByte(AT24C02_ADDRESS); //接上首字節(jié),發(fā)送器件寫操作地址+寫數(shù)據(jù)(0xa0)這里寫操作時(shí)維綸把所要讀的數(shù)據(jù)地址AT24C02_ADDRESS通知讀取哪個(gè)地址信息
- I2C_ReceiveAck(); //等待完成應(yīng)答
- I2C_SendByte(WordAddress);//發(fā)送要讀取內(nèi)存的地址(WORD ADDRESS)
- I2C_ReceiveAck(); //等待應(yīng)答完成
- I2C_Start();//在次啟動(dòng)總線
- I2C_SendByte(AT24C02_ADDRESS| 0x01); //對(duì)E2PROM進(jìn)行讀操作(0XA1)E2PROM會(huì)自動(dòng)向主機(jī)發(fā)回?cái)?shù)據(jù),讀取一個(gè)字節(jié)后回應(yīng)一個(gè)應(yīng)答位,后會(huì)繼續(xù)傳送下一個(gè)地址的數(shù)據(jù)0xa1
- I2C_ReceiveAck(); //等待完成
- Data= I2C_ReceiveByte(); //要讀出的數(shù)據(jù)到Data
- I2C_SendAck(1); //等待完成::如果不想讀了,就發(fā)送一個(gè)非應(yīng)答位NAK(1),發(fā)送結(jié)束,停止總線
- I2C_Stop(); //停止總線
- return Data ;//返回值
- }
- /************延時(shí)函數(shù)***********************/
- void delay_ms(uint ms)
- {
- uchar k;
- while(ms--)
- {
- for(k = 0; k < 120; k++);
- }
- }
- ///////////////////////////////////////////////////////////////
- void display() //顯示程序display(uchar a,b,c,d,e)
- {
- unsigned char i,w = 1;//添加閃爍 i, w = 128
- /********************************/
- switch(i)//使用多分支選擇語句 i=count display 0x代表16進(jìn)制
- {
- case(0):Ledbuff[7]=Set_Count/1000;break; //取設(shè)定千位字符送緩存
- case(1):Ledbuff[6]=Set_Count/100%10;break; //取設(shè)定百位字符送緩沖
- case(2):Ledbuff[5]=Set_Count/10%10;break; //取設(shè)定十位字符送緩沖
- case(3):Ledbuff[4]=Set_Count%10;break; //取設(shè)定個(gè)位字符送緩存
-
- case(4):Ledbuff[3]=Count/1000;break; //取計(jì)數(shù)千位字符送緩存
- case(5):Ledbuff[2]=Count/100%10;break;
- case(6):Ledbuff[1]=Count/10%10;break;
- case(7):Ledbuff[0]=Count%10;break;
- }
- P0=0x00; //消陰:段碼全部低電平關(guān)閉
- //添加閃爍: 閃爍字符 0,N閃爍位置 Ledbuff[n] = 10; Ledbuff[ n ] = i Ledbuff[ n+3 ] 是從第四個(gè)字符開始閃爍
- if (flag) Ledbuff[ n+3 ] = 245 ; //共陰字碼表取反10 ,共陽=10 因?yàn)閚是從1開始,所以第一個(gè)閃爍的是Ledbuff[4] ~10=(0000 1010)
- /**********************************/
- P2=~(0x01<<i); //P2位選,左移i位取反
- P0=ledcode[Ledbuff[i]]; //P0字符刷新顯示
- delay_ms(1); //顯示2MS
- i=++i%8; //自加1
- }
- void Adjust() //按鍵設(shè)定匝數(shù),用P2.4個(gè)位-P2.7(千位)前四位數(shù)碼管顯示void
- {
- // **********原程序************************
- if(yiwei_up==0) //移位按鍵按下
- {
- //********這里開啟定時(shí)中斷,進(jìn)入閃爍計(jì)時(shí)**************************
- while(!yiwei_up); //等待移位按鍵松開
- {
- n ++; if(n>4) n=1; //移位:左移一位 ,移到千位后,在按返回個(gè)位
- }
- ET0=1; //開啟T0
- TR0 = 1; // 啟動(dòng)T0 工作開始 選擇的數(shù)碼管開始閃爍
- }
-
- //加減按鍵檢測
- if(Set_Count>=0 && Set_Count<9999)//最大9999yiwei_Count=0; //設(shè)定加 jia_up==0
- {
- if (jia_up==0) //增加按鍵按下
- {
- while(!jia_up);//等待加按鍵松開
- num1=Set_Count ;
- {
- if (n == 1 ) //
- {
- Set_Count += 1; //設(shè)定+1
- }
- if ( n == 2 &&Set_Count<9990)
- {
- Set_Count += 10; //設(shè)定+10
- }
- if ( n == 3 && Set_Count<9900 )
- {
- Set_Count += 100; //設(shè)定+100
- }
- if ( n == 4 && Set_Count<9000 )
- {
- Set_Count += 1000; //設(shè)定+1000
- }
- }
- }
- if (jian_down==0) //減少按鍵按下
- {
- while(!jian_down);//等待按鍵松開
- num1=Set_Count ;
- {
- if ( n ==1 && Set_Count>1 ) // 移位在個(gè)位
- {
- Set_Count -= 1; //設(shè)定-1
- }
- if ( n == 2 && Set_Count>9)
- {
- Set_Count -= 10; //設(shè)定+1
- }
- if (n == 3 && Set_Count>99 )
- {
- Set_Count -= 100; //設(shè)定-100
- }
- if ( n == 4 && Set_Count>999 )
- {
- Set_Count -= 1000; //設(shè)定+1
- }
- }
- }
- if ( num1 != Set_Count ) // 設(shè)定值有變化,存入24c
- {
- //寫入數(shù)據(jù)
- AT24C_WriteByte(0,Set_Count%256);
- delay_ms(5) ; //顯示2MS
- AT24C_WriteByte(1,Set_Count/256);
- delay_ms(5); //顯示2MS
- }
- }
- if( num2==3) //設(shè)定超時(shí)保存后,閃爍幾次關(guān)閉閃爍
- {ET0=1;TR0 = 0; num2=0 ;} //num2++ ;
- num1=Set_Count ; //保存完成 將設(shè)定值送到設(shè)定值變化緩存
-
- }
-
- /**********************************************************
- 主函數(shù) ET=1 // 是打開定時(shí)器0中斷允許,EA = 1; // 是打開總中斷允許
- **********************************************************/
- void main()
- {
- /*****************Y添加閃爍中斷初始化**********************/
- TMOD = 0x01; //是配置定時(shí)器0為16位定時(shí)模式
- TH0 = 0x3C; // 設(shè)定高位初值
- TL0 = 0xB0; // 設(shè)定低位初值
- EA=1 ; //開啟總中斷
- // IE = 0x82; //中斷允許寄存器0x82=10000010開了總中斷 ,相當(dāng)于EA=1打開總中斷 ;ET0=1;打開T0
- /*********************************************************************/
- I2C_init(); //初始化24C02
- //讀取低八位從24C-02的0x00讀取到Num_L,高八位從0x01讀取到Num_H
- Num_L = AT24C_ReadByte(0);
- Num_H |=AT24C_ReadByte(1)<<8; //左移8位
- Set_Count = Num_H+Num_L; //高八位加上低八位
- while(1)
- {
- Adjust();
- display();
- }
- }
- //-------------閃爍中斷--------------------------
- void T0_INT() interrupt 1
- {
- TH0 = 0x3C; // 設(shè)定低位初值
- TL0 = 0xB0; // 設(shè)定高位初值
- n_50ms++; // 進(jìn)入中斷自加
- n_50ms %= 6; //10對(duì)應(yīng)1Hz 取余后如果=6
- if(!n_50ms)
- {
- flag = ~flag;
- if ( num1 != Set_Count ) //設(shè)定后延時(shí)關(guān)閉閃爍
- {
- num2++ ;
- // if( num2==3)
- // { flag =0;ET0=1;TR0 = 0; num2=0 ; num1=Set_Count ;} //num2++ ;
- }
- }
- }
復(fù)制代碼 |
|