還在為找不到I2C設備的地址而煩惱??
別慌,我帶著代碼走來了
按下按鍵,開始從0x01開始測試器件地址,一直到0xff結束。
查詢到正確地址后,蜂鳴器叫2聲,串口打印地址碼,不再繼續查詢。
地址碼輸出至P1,在沒有顯示屏和不方便使用串口監視的情況下可通過LED狀態讀出地址。
初始版本沒有增加地址碼驗證(驗證的話就是用這個地址去讀寫數據顯示出來就行)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
效果圖.png (34.34 KB, 下載次數: 73)
下載附件
2020-9-13 16:06 上傳
單片機源程序如下:
- #include<intrins.h>
- #include<uart.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define uint unsigned int //函數聲明
-
- #define yh 0x80 //第1行+3位數顯示
- #define er 0x80+0x40
- #define Address_Test count //定義器件在 IIC 總線中的地址
- #define Read_Address count+1
- unsigned char TAB[16] ={'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
- uint open,count,num,disp;
- uchar key,flag,temp;
- sbit RS=P3^5;
- sbit RW=P3^6;
- sbit E=P3^4;
- sbit k2=P3^2; //檢測地址
- sbit SCL=P2^6; //時鐘
- sbit SDA=P2^7; //數據
- sbit beep=P2^3; //蜂鳴提示
- void write_1602com(uchar com)//****液晶寫入指令函數****
- {
- RS=0;//數據/指令選擇置為指令
- RW=0;
- P0=com;//送入數據
- delayms(1);
- E=1;//拉高使能端,為制造有效的下降沿做準備
- delayms(1);
- E=0;//en由高變低,產生下降沿,液晶執行命令
- }
- void write_1602dat(uchar dat)//***液晶寫入數據函數****
- {
- RS=1;//數據/指令選擇置為數據
- RW=0;
- P0=dat;//送入數據
- delayms(1);
- E=1; //en置高電平,為制造下降沿做準備
- delayms(1);
- E=0; //en由高變低,產生下降沿,液晶執行命令
- }
- void lcd_init()//***液晶初始化函數****
- {
- write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
- write_1602com(0x0c);//開顯示不顯示光標
- write_1602com(0x06);//整屏不移動,光標自動右移
- write_1602com(0x01);//清顯示
- }
- void dsplay()
- {
- if(disp==0)
- {
- uint a,b; //地址數據緩存
-
- a = (Address_Test%256)/16; // 十位
- b = (Address_Test%256)%16; // 個位
-
- if(open==1&&flag==1)
- {
- SendString("ID:0x"); //打印地址碼
- SendASC(TAB[a]);
- delayms(5);
- SendASC(TAB[b]);
- SendString("\r\n");
-
- P1=((a*16)+b); //無顯示器則用LED表示出地址碼
- open=0;flag=2;
- }
-
- write_1602com(yh);//指定第一行顯示
- write_1602dat('I');
- write_1602dat('D');
- write_1602dat(':');
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(TAB[a]);
- write_1602dat(TAB[b]);
-
-
- }
- }
- void Start() //開始總線
- {
- SDA=1;
- delay();
- SCL=1;
- delay();
- SDA=0;
- delay();
- SCL=0;
- delay();
- }
-
- void Stop() //結束總線
- {
- SCL=0;
- delay();
- SDA=0;
- delay();
- SCL=1;
- delay();
- SDA=1;
- delay();
- }
-
- bit TestAck() //測試 ACK
- {
-
- bit ErrorBit;
- SDA=1;
- delay();
- SCL=1;
- delay();
- ErrorBit=SDA;
- if(ErrorBit==0){open=1;flag=1;} //ErrorBit=0;時代表應答成功
- delay();
- SCL=0;
- delay();
- return(ErrorBit);
- }
- void Write8Bit(unsigned char input)//寫入 8 個 bit 到 24c02
- {
- unsigned char temp;
- for(temp=8;temp!=0;temp--)
- {
- SDA=(bit)(input&0x80);
- delay();
- SCL=1;
- delay();
- SCL=0;
- delay();
- input=input<<1;
- }
- }
- void About() //查詢
- {
- Start();
- Write8Bit(Address_Test);
- TestAck();
- delayms(5);
- Stop();
- delayms(20);
-
- }
- void keyscan()
- {
- if(k2==0)
- {
- delayms(10);
- if(!k2)
- {
- delayms(10);
- while(!k2);
- key+=1;
- if(key>2)
- {
- key=1;
- }
- switch(key)
- {
- case 1:open=2;//關閉光標
- break;
- case 2:open=1;num=0;count=0;disp=0;
- lcd_init();delayms(500);open=2; //再次按下測試
- break;
- }
- }
- }
- }
-
- void main()
- {
- lcd_init();
- Uart_init();
-
- while(1)
- {
- keyscan();
- dsplay();
- if(flag==2){beep=0; delayms(1500);beep=1;delayms(500);beep=0; delayms(1500);beep=1;flag=0;}
-
-
- }
- }
- void Timer0_isr(void) interrupt 1
- {
-
- TH0=(65536-50000)/256; //重新賦值 2ms 62500
- TL0=(65536-50000)%256;
-
- if(open==2)
- {
- num++;
- if(num==3)
- {
- num=0;
- count++;
- About();
- if(count>255) count=255;
- }
-
- }
- }
-
- // 通訊中斷接收程序 中斷函數無返回值
- void uart_rx(void) interrupt 4
- {
- unsigned char dat;
- if(RI) //是否接收中斷
- {
- RI=0;
- dat = SBUF;
- }
- }
-
復制代碼
51hei.png (8.98 KB, 下載次數: 57)
下載附件
2020-9-13 16:26 上傳
所有資料51hei提供下載:
I2C地址查詢.zip
(94.15 KB, 下載次數: 28)
2020-9-13 16:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|