|
我的程序是通過AT24C02寫入和讀取數(shù)據(jù),并由四個(gè)獨(dú)立按鍵控制數(shù)碼管顯示出來。按鍵1是保存目前的數(shù)據(jù),按鍵2是顯示上次保存的數(shù)據(jù),按鍵3是+1功能,按鍵4是清零功能,開始的時(shí)候,數(shù)碼管會(huì)顯示4個(gè)0,然后按3 +1,按1,保存數(shù)據(jù),按4清零,并按2 ,顯示數(shù)據(jù),前面的都沒有問題,就是按2的時(shí)候,不管保存的數(shù)據(jù)是多少,數(shù)碼管都顯示的是0006(6的最下面一橫還沒有),這是為什么呢?單片機(jī)代碼如下,初學(xué)51,請(qǐng)多指教!
- /**************************************************************************************
- * EEPROM-IIC實(shí)驗(yàn) *
- 實(shí)現(xiàn)現(xiàn)象:下載程序后數(shù)碼管后4位顯示0,按K1保存顯示的數(shù)據(jù),按K2讀取上次保存的數(shù)據(jù),
- 按K3顯示數(shù)據(jù)加一,按K4顯示數(shù)據(jù)清零。最大能寫入的數(shù)據(jù)是255.
- 注意事項(xiàng):由于P3.2口跟紅外線共用,所以做按鍵實(shí)驗(yàn)時(shí)為了不讓紅外線影響實(shí)驗(yàn)效果,最好把紅外線先取下來。
- ***************************************************************************************/
- #include "reg52.h" //此文件中定義了單片機(jī)的一些特殊功能寄存器
- #include "i2c.h"
- typedef unsigned int u16; //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
- typedef unsigned char u8;
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit k1=P3^1;
- sbit k2=P3^0;
- sbit k3=P3^2;
- sbit k4=P3^3; //定義按鍵端口
- char num=0;
- u8 disp[4];
- u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- /*******************************************************************************
- * 函 數(shù) 名 : delay
- * 函數(shù)功能 : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /*******************************************************************************
- * 函數(shù)名 :Keypros()
- * 函數(shù)功能 :按鍵處理函數(shù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void Keypros()
- {
- if(k1==0)
- {
- delay(1000); //消抖處理
- if(k1==0)
- {
- At24c02Write(1,num); //在地址1內(nèi)寫入數(shù)據(jù)num
- }
- while(!k1);
- }
- if(k2==0)
- {
- delay(1000); //消抖處理
- if(k2==0)
- {
- num=At24c02Read(1); //讀取EEPROM地址1內(nèi)的數(shù)據(jù)保存在num中
- }
- while(!k2);
- }
- if(k3==0)
- {
- delay(100); //消抖處理
- if(k3==0)
- {
- num++; //數(shù)據(jù)加1
- if(num>255)num=0;
- }
- while(!k3);
- }
- if(k4==0)
- {
- delay(1000); //消抖處理
- if(k4==0)
- {
- num=0; //數(shù)據(jù)清零
- }
- while(!k4);
- }
- }
- /*******************************************************************************
- * 函數(shù)名 :datapros()
- * 函數(shù)功能 :數(shù)據(jù)處理函數(shù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void datapros()
- {
- disp[0]=smgduan[num/1000];//千位
- disp[1]=smgduan[num%1000/100];//百位
- disp[2]=smgduan[num%1000%100/10];//個(gè)位
- disp[3]=smgduan[num%1000%100%10];
- }
- /*******************************************************************************
- * 函數(shù)名 :DigDisplay()
- * 函數(shù)功能 :數(shù)碼管顯示函數(shù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void DigDisplay()
- {
- u8 i;
- for(i=0;i<4;i++)
- {
- switch(i) //位選,選擇點(diǎn)亮的數(shù)碼管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//顯示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//顯示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//顯示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//顯示第3位
- }
- P0=disp[3-i];//發(fā)送數(shù)據(jù)
- delay(100); //間隔一段時(shí)間掃描
- P0=0x00;//消隱
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : main
- * 函數(shù)功能 : 主函數(shù)
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void main()
- {
- while(1)
- {
- Keypros(); //按鍵處理函數(shù)
- datapros(); //數(shù)據(jù)處理函數(shù)
- DigDisplay();//數(shù)碼管顯示函數(shù)
- }
- }
- #include"i2c.h"
- /*******************************************************************************
- * 函數(shù)名 : Delay10us()
- * 函數(shù)功能 : 延時(shí)10us
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void Delay10us()
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=2;a>0;a--);
- }
- /*******************************************************************************
- * 函數(shù)名 : I2cStart()
- * 函數(shù)功能 : 起始信號(hào):在SCL時(shí)鐘信號(hào)在高電平期間SDA信號(hào)產(chǎn)生一個(gè)下降沿
- * 輸入 : 無
- * 輸出 : 無
- * 備注 : 起始之后SDA和SCL都為0
- *******************************************************************************/
- void I2cStart()
- {
- SDA=1;
- Delay10us();
- SCL=1;
- Delay10us();//建立時(shí)間是SDA保持時(shí)間>4.7us
- SDA=0;
- Delay10us();//保持時(shí)間是>4us
- SCL=0;
- Delay10us();
- }
- /*******************************************************************************
- * 函數(shù)名 : I2cStop()
- * 函數(shù)功能 : 終止信號(hào):在SCL時(shí)鐘信號(hào)高電平期間SDA信號(hào)產(chǎn)生一個(gè)上升沿
- * 輸入 : 無
- * 輸出 : 無
- * 備注 : 結(jié)束之后保持SDA和SCL都為1;表示總線空閑
- *******************************************************************************/
- void I2cStop()
- {
- SDA=0;
- Delay10us();
- SCL=1;
- Delay10us();//建立時(shí)間大于4.7us
- SDA=1;
- Delay10us();
- }
- /*******************************************************************************
- * 函數(shù)名 : I2cSendByte(unsigned char dat)
- * 函數(shù)功能 : 通過I2C發(fā)送一個(gè)字節(jié)。在SCL時(shí)鐘信號(hào)高電平期間,保持發(fā)送信號(hào)SDA保持穩(wěn)定
- * 輸入 : num
- * 輸出 : 0或1。發(fā)送成功返回1,發(fā)送失敗返回0
- * 備注 : 發(fā)送完一個(gè)字節(jié)SCL=0,SDA=1
- *******************************************************************************/
- unsigned char I2cSendByte(unsigned char dat)
- {
- unsigned char a=0,b=0;//最大255,一個(gè)機(jī)器周期為1us,最大延時(shí)255us。
- for(a=0;a<8;a++)//要發(fā)送8位,從最高位開始
- {
- SDA=dat>>7; //起始信號(hào)之后SCL=0,所以可以直接改變SDA信號(hào)
- dat=dat<<1;
- Delay10us();
- SCL=1;
- Delay10us();//建立時(shí)間>4.7us
- SCL=0;
- Delay10us();//時(shí)間大于4us
- }
- SDA=1;
- Delay10us();
- SCL=1;
- while(SDA)//等待應(yīng)答,也就是等待從設(shè)備把SDA拉低
- {
- b++;
- if(b>200) //如果超過2000us沒有應(yīng)答發(fā)送失敗,或者為非應(yīng)答,表示接收結(jié)束
- {
- SCL=0;
- Delay10us();
- return 0;
- }
- }
- SCL=0;
- Delay10us();
- return 1;
- }
- /*******************************************************************************
- * 函數(shù)名 : I2cReadByte()
- * 函數(shù)功能 : 使用I2c讀取一個(gè)字節(jié)
- * 輸入 : 無
- * 輸出 : dat
- * 備注 : 接收完一個(gè)字節(jié)SCL=0,SDA=1.
- *******************************************************************************/
- unsigned char I2cReadByte()
- {
- unsigned char a=0,dat=0;
- SDA=1; //起始和發(fā)送一個(gè)字節(jié)之后SCL都是0
- Delay10us();
- for(a=0;a<8;a++)//接收8個(gè)字節(jié)
- {
- SCL=1;
- Delay10us();
- dat<<=1;
- dat|=SDA;
- Delay10us();
- SCL=0;
- Delay10us();
- }
- return dat;
- }
- /*******************************************************************************
- * 函數(shù)名 : void At24c02Write(unsigned char addr,unsigned char dat)
- * 函數(shù)功能 : 往24c02的一個(gè)地址寫入一個(gè)數(shù)據(jù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void At24c02Write(unsigned char addr,unsigned char dat)
- {
- I2cStart();
- I2cSendByte(0xa0);//發(fā)送寫器件地址
- I2cSendByte(addr);//發(fā)送要寫入內(nèi)存地址
- I2cSendByte(dat); //發(fā)送數(shù)據(jù)
- I2cStop();
- }
- /*******************************************************************************
- * 函數(shù)名 : unsigned char At24c02Read(unsigned char addr)
- * 函數(shù)功能 : 讀取24c02的一個(gè)地址的一個(gè)數(shù)據(jù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- unsigned char At24c02Read(unsigned char addr)
- {
- unsigned char num;
- I2cStart();
- I2cSendByte(0xa0); //發(fā)送寫器件地址
- I2cSendByte(addr); //發(fā)送要讀取的地址
- I2cStart();
- I2cSendByte(0xa1); //發(fā)送讀器件地址
- num=I2cReadByte(); //讀取數(shù)據(jù)
- I2cStop();
- return num;
- }
- #ifndef __I2C_H_
- #define __I2C_H_
- #include <reg52.h>
- sbit SCL=P2^1;
- sbit SDA=P2^0;
- void I2cStart();
- void I2cStop();
- unsigned char I2cSendByte(unsigned char dat);
- unsigned char I2cReadByte();
- void At24c02Write(unsigned char addr,unsigned char dat);
- unsigned char At24c02Read(unsigned char addr);
- #endif
復(fù)制代碼
|
|