|
- /****************************************************************
- AT24C前四位固定為1010 A1-A2由管腳電平默認接地,最后一位表示讀寫操作所以AT24C讀地址0xa1 寫地址0xa0
- 寫AT24C02的時候從器件地址為10100 0000,(0xa0),讀AT24C02的時候從器件地址為10100 0001,(0xa1)
- ***************************************************************/
- #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;
- // unsigned int Count;
- // unsigned int Set_Count;
- uint Num_L;
- uint Num_H;
- uint num1;
- uint num2;
- char yiwei_Count;//移位計數
- sbit I2C_SCL= P1^6;
- sbit I2C_SDA= P1^7;
- sbit Start_Dianji=P3^0; //電機啟動_dianji
- sbit forward=P3^1; //正轉檢測
- //sbit back=P3^1; //反轉檢測
- sbit run=P3^7; //運行信號
- 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}; //共陰數碼管編碼0-9
- uchar data Ledbuff[8]={1};//顯示緩沖區
- #define I2CDelay_us(){_nop_();_nop_();_nop_();_nop_();}//voidI2CDelay_us
- /***********************
- AT24C初始化
- *************************/
- void I2C_init()
- {
- I2C_SCL=1;
- // I2CDelay_us(4);
- I2C_SDA=1;//首先確保SCL SDA都是高電平
- // I2CDelay_us(4);
-
- }
- /***********************
- 產生總線起始信號
- *************************/
- void I2C_Start(void )
- {
- I2C_SDA=1;//首先確保SCL SDA都是高電平
- // I2CDelay_us(5);
- I2C_SCL=1; //確保SCL高電平
- // I2CDelay_us(5);
- I2C_SDA=0;//先在SCL為高時拉低SDA,即為起始信號
- // I2CDelay_us(5);
- I2C_SCL=0; //在拉低 SCL,鉗住I2C總線準備發送或接收數據
- }
- /***********************
- 產生總線停止信號:先拉低SDA在拉低SCL
- *************************/
- void I2C_Stop(void )
- {
- I2C_SDA=0;//首先確保SCL SDA都是低電平
- I2C_SCL=1; //先拉高 SCL
- I2C_SDA=1;//在拉高 SDA
- /*
- I2C_SCL=0;
- I2C_SDA=0;
- // I2CDelay_us(4);
- I2C_SCL=1;
- I2C_SDA=1;
- // I2CDelay_us(4);
- */
- }
- /*******************************************************************************
- *@brief I2C發送一個字節數據
- *@param Byte要發送的字節
- *@retval 無
- 起始信號后必須送一個從機地址(7)位,1-7位為要接收器件的地址,第八位讀寫位0發送1接收,第9位ACK應答位,
- 緊接著為第一個數據字節,然后一位應答位ACK后面繼續第二個數據字節
- **********************************************************************************/
- void I2C_SendByte(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- I2C_SDA=Byte&(0x80>>i);
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- }
- /***********************************************************************************************
- *@brief I2C讀取 接收一個字節
- *@param 無
- *@retval 讀取 接收到的一個字節數據
- ********************************************************************************************/
- 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發送應答Ack
- *@param AckBit應答位 0為應答(成功) 1為非應答(失敗)
- *@retval 無
- ************************/
- void I2C_SendAck(unsigned char AckBit)
- {
- I2C_SDA=AckBit;
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- /*********************
- *@brief I2C接收應答位
- *@param 無
- *@retval AckBit應答位 0為應答(成功) 1為非應答(失敗)
- ************************/
- unsigned char I2C_ReceiveAck(void)
- {
- unsigned char AckBit;
- I2C_SDA=1;
- I2C_SCL=1; //先拉高 SCL
- AckBit=I2C_SDA;
- I2C_SCL=0; //SCL
- return AckBit; //返回值
- }
- /**********向AT24C寫數據***********
- *@brief AT24C寫入一個字節
- *@param WordAddress要寫入字節的地址
- *@param Data要寫入的數據
- *@retval無
- 寫多字節時,寫入一個字節。在寫一個字節前,必須延時5ms
- ************************/
- void AT24C_WriteByte(unsigned char WordAddress,Data)
- {
- I2C_Start();//啟動總線
- I2C_SendByte(AT24C02_ADDRESS);//發送寫操作地址+寫數據(0xa0)
- I2C_ReceiveAck(); //等待應答
- I2C_SendByte(WordAddress);//要寫入的地址
- I2C_ReceiveAck(); //等待應答完成
- I2C_SendByte(Data); //要寫入的數據,第一字節 ,第二字節注意:每個字節都回應一個應答位0,如果沒有回應說明寫入不成功
- I2C_ReceiveAck(); //等待完成 注意:每個字節都回應一個應答位0,如果沒有回應說明寫入不成功
- I2C_Stop(); //發送結束信號:停止總線
- }
- /************從AT24C中讀出數據*********
- *@brief AT24C讀取一個字節
- *@param WordAddress要讀出字節的地址
- *@param 無
- *@retval要讀出的數據
- ************************/
- unsigned char AT24C_ReadByte(unsigned char WordAddress) //void
- {
- unsigned char Data;
- I2C_Start(); //發送起始信號:啟動總線
- I2C_SendByte(AT24C02_ADDRESS); //接上首字節,發送器件寫操作地址+寫數據(0xa0)這里寫操作時維綸把所要讀的數據地址AT24C02_ADDRESS通知讀取哪個地址信息
- I2C_ReceiveAck(); //等待完成應答
- I2C_SendByte(WordAddress);//發送要讀取內存的地址(WORD ADDRESS)
- I2C_ReceiveAck(); //等待應答完成
- I2C_Start();//在次啟動總線
- I2C_SendByte(AT24C02_ADDRESS| 0x01); //對E2PROM進行讀操作(0XA1)E2PROM會自動向主機發回數據,讀取一個字節后回應一個應答位,后會繼續傳送下一個地址的數據0xa1
- I2C_ReceiveAck(); //等待完成
- Data= I2C_ReceiveByte(); //要讀出的數據到Data
- I2C_SendAck(1); //等待完成::如果不想讀了,就發送一個非應答位NAK(1),發送結束,停止總線
- I2C_Stop(); //停止總線
- return Data ;//返回值
- }
- /***********************************/
- void delayms(uint ms)
- {
- uchar k;
- while(ms--)
- {
- for(k = 0; k < 120; k++);
- }
- }
- void display() //顯示程序display(uchar a,b,c,d,e) char i;
- {
- static unsigned char i = 0;
- switch(i)//使用多分支選擇語句 i=count display 0x代表16進制
- {
- case(0):Ledbuff[7]=Set_Count/1000;break; //取設定千位字符送緩存
- case(1):Ledbuff[6]=Set_Count/100%10;break; //取設定百位字符送緩沖
- case(2):Ledbuff[5]=Set_Count/10%10;break; //取設定十位字符送緩沖
- case(3):Ledbuff[4]=Set_Count%10;break; //取設定個位字符送緩存
-
- case(4):Ledbuff[3]=Count/1000;break; //取計數千位字符送緩存
- 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; //消陰:段碼全部低電平關閉
- P2=~(0x01<<i); //P2位選,左移i位取反
- P0=ledcode[Ledbuff[i]]; //P0字符刷新顯示
- delayms(1); //顯示2MS
- i=++i%8; //自加1
- }
- /*
- void Adjust(void) //按鍵設定匝數,用P2.4個位-P2.7(千位)前四位數碼管顯示
- {
-
- if(yiwei_up==0) //移位按鍵按下
- {
- while(!yiwei_up); //等待移位按鍵松開
- if(yiwei_Count<3) //移位
- {
- yiwei_Count +=1;
- }
- else //如果>3
- {
- yiwei_Count=0; //設定位在個位
- }
- }
-
- if(Set_Count>=0 && Set_Count<9999)//最大9999yiwei_Count=0; //設定加 jia_up==0
- {
- if (jia_up==0) //增加按鍵按下
- {
- while(!jia_up);//等待加按鍵松開
- {
- if (yiwei_Count==0) //
- {
- Set_Count += 1; //設定+1
- }
- if (yiwei_Count==1&&Set_Count<9990)
- {
- Set_Count += 10; //設定+1
- }
- if (yiwei_Count==2&&Set_Count<9900)
- {
- Set_Count += 100; //設定+1
- }
- if (yiwei_Count==3 && Set_Count<9000)
- {
- Set_Count += 1000; //設定+1
- }
- }
- }
- if (jian_down==0) //減少按鍵按下
- {
- while(!jian_down);//等待按鍵松開
- {
- if (yiwei_Count==0&&Set_Count>1) // 移位在個位
- {
- Set_Count -= 1; //設定+1
- }
- if (yiwei_Count==1&&Set_Count>9)
- {
- Set_Count -= 10; //設定+1
- }
- if (yiwei_Count==2 && Set_Count>99)
- {
- Set_Count -= 100; //設定+1
- }
- if (yiwei_Count==3 && Set_Count>999)
- {
- Set_Count -= 1000; //設定+1
- }
- }
- //寫入數據
- /* AT24C_WriteByte(0,Set_Count%256);
- delayms(5) ; //顯示2MS
- AT24C_WriteByte(1,Set_Count/256);
- delayms(5); //顯示2MS
- }
- */
- /**********************************************************
- 主函數
- **********************************************************/
- void main()
- {
- I2C_init();
- // init(); //初始化24C02
- // num=5678; //num為小于等于65535的整數。 */
- Set_Count=1234;
- Num_H =Set_Count/256; //1234/256就簡單了,高位:取的是整數倍,不被整除的部分自然就被剔除了1234/256=4
- Num_L =Set_Count%256; //%256是取余,低位:也就是你把前面的數值除以256取余,商跟除數則是256的整數倍部分1234%256=210 ;4*256=1024 %256=1234-1024=210
- AT24C_WriteByte(0,Num_L);
- delayms(10); //顯示2MS
- AT24C_WriteByte(1,Num_H );
- delayms(10); //顯示2MS
- num1=AT24C_ReadByte(0); //用地址0單元存儲num十六進制表示時的低兩位
- num2=AT24C_ReadByte(1); //用地址0單元存儲num十六進制表示時的高兩位
- Count=num2*256+num1;
- //寫入24C02
- // AT24C_WriteByte(0,Set_Count%256); //低8位寫入0x00
- /*
- AT24C_WriteByte(0,120); //低8位寫入0x00
- delayms(5); //顯示2MS
- // AT24C_WriteByte(1,Set_Count/256); //高8位寫入0x01
- AT24C_WriteByte(1,0); //高8位寫入0x01
- delayms(5); //顯示2MS
- //讀取數據 /*
- Num_L = AT24C_ReadByte(0);
- Num_H |=AT24C_ReadByte(1)<<8;
- Count= Num_H+Num_L;
- */
- while(1)
- {
- /* Adjust();
- if (jia_up==0) //增加按鍵按下
- {
- while(!jia_up);//等待加按鍵松開
- {
- Set_Count += 1; //設定+1
- }
- }
- if (jian_down==0) //減少按鍵按下
- {
- while(!jian_down);//等待按鍵松開
- {
- Set_Count -= 1; //設定+1
- }
- }
- if(yiwei_up==0) //保存按鍵按下,向AT24C寫入數據
- {
- while(!yiwei_up); //等待移位按鍵松開
- {
- AT24C_WriteByte(0,Set_Count%256);
- delayms(6) ; //顯示2MS
- AT24C_WriteByte(1,Set_Count/256);
- delayms(6); //顯示2MS
- }
- }
-
- if( qingling==0) //讀取按鍵按下
- {
- while(! qingling); //等待移位按鍵松開
- {
- Count=AT24C_ReadByte(0);
- Count |=AT24C_ReadByte(1)<<8;
- // Count = Num_H+Num_L;
- }
- } */
- display();
- }
- }
復制代碼 |
-
-
gongyang.rar
2023-8-1 12:59 上傳
點擊文件名下載附件
19.96 KB, 下載次數: 2
仿真文件
|