本帖最后由 ksljxxq 于 2020-2-24 14:13 編輯
I2C通信ID自動查找,在維修時碰到I2C通信要找ID地址也很麻煩,我們常用的比如24Cxx系列,顯示屏通信,一般都是信號SDA與SCL,本主板用的主控芯片是stc15f2k60s2,編碼開關,1602顯示屏,二個按鈕,編碼開關按鈕是移動光標,見下圖24C測試ID 0XA0,TW8816測試ID 0X8A讀寫都正常,在i2c壓縮包是程序和仿真
制作出來的實物圖如下:
IMG_20200223_183218.jpg (3.61 MB, 下載次數: 81)
下載附件
2020-2-23 20:18 上傳
IMG_20200223_183521.jpg (6.04 MB, 下載次數: 82)
下載附件
2020-2-23 20:08 上傳
IMG_20200223_183505.jpg (5.94 MB, 下載次數: 73)
下載附件
2020-2-23 20:08 上傳
IMG_20200223_183206.jpg (6.04 MB, 下載次數: 87)
下載附件
2020-2-23 20:05 上傳
IMG_20200223_164345.jpg (3.39 MB, 下載次數: 103)
下載附件
2020-2-23 20:01 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖.png (211.71 KB, 下載次數: 79)
下載附件
2020-2-23 20:21 上傳
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int //函數聲明
- #define yh 0x80 //第1行+3位數顯示
- uint yi,ra,si,ra1,si1;
- void Init_Timer0(void);
- sbit rs=P1^0;
- sbit rw=P1^1;
- sbit en=P1^2;
- sbit k3=P3^4; //光標
- sbit k1=P3^2; //讀開關
- sbit k2=P3^3; //檢測地址
- sbit CodingsWitch_B=P3^5; //A腳定義(即1腳) 這兩腳必須接10K上拉電阻
- sbit CodingsWitch_A=P3^6; //B腳定義(即3腳?
- sbit SCL=P2^7; //24c02 6
- sbit SDA=P2^6; // 5
- void delay()
- {;;}
- void delay1(uint z)//延時為 1ms
- {
- uchar x,x1;
- for(;z>0;z--)
- {
- for(x=0;x<114;x++)
- {
- for(x1=0;x1<1;x1++);
- }
- }
- }
- write_1602com(uchar com)//****液晶寫入指令函數****
- {
- rs=0;//數據/指令選擇置為指令
- rw=0;
- P0=com;//送入數據
- delay1(1);
- en=1;//拉高使能端,為制造有效的下降沿做準備
- delay1(1);
- en=0;//en由高變低,產生下降沿,液晶執行命令
- }
- write_1602dat(uchar dat)//***液晶寫入數據函數****
- {
- rs=1;//數據/指令選擇置為數據
- rw=0;
- P0=dat;//送入數據
- delay1(1);
- en=1; //en置高電平,為制造下降沿做準備
- delay1(1);
- en=0; //en由高變低,產生下降沿,液晶執行命令
- }
- lcd_init()//***液晶初始化函數****
- {
- write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
- write_1602com(0x0c);//開顯示不顯示光標
- write_1602com(0x06);//整屏不移動,光標自動右移
- write_1602com(0x01);//清顯示
- }
- void dsplay()
- {
- if(xianshi==0)
- {
- unsigned int c, d;
- // a = (WriteDeviceAddress/256)/16; // 16進制千位
- // b = (WriteDeviceAddress/256)%16; // 百位
- c = (WriteDeviceAddress%256)/16; // 十位
- d = (WriteDeviceAddress%256)%16; // 個位
-
- write_1602com(yh);//指定顯示
- write_1602dat('I'); //
- write_1602dat('D'); //
- write_1602dat(':'); //
- write_1602dat('0'); //
- write_1602dat('x'); //
- write_1602dat(hex_table[c]); //
- write_1602dat(hex_table[d]); //
- }
- if(xianshi==1)
- {
- uchar a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1;
- a = (yi%256)/16; // 十位
- b = (yi%256)%16; // 個位
- c = (ra%256)/16; // 十位
- d = (ra%256)%16; // 個位
- e = (yi+1%256)/16; // 十位
- f = (yi+1%256)%16; // 個位
- g = (si%256)/16; // 十位
- h = (si%256)%16; // 個位
- a1 = (yi+2%256)/16; // 十位
- b1 = (yi+2%256)%16; // 個位
- c1 = (ra1%256)/16; // 十位
- d1 = (ra1%256)%16; // 個位
- e1 = (yi+3%256)/16; // 十位
- f1 = (yi+3%256)%16; // 個位
- g1 = (si1%256)/16; // 十位
- h1 = (si1%256)%16; // 個位
- write_1602com(yh);//指定顯示
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[a]); //
- write_1602dat(hex_table[b]); //
- write_1602dat(',');
- write_1602dat(hex_table[c]); //
- write_1602dat(hex_table[d]); //
- write_1602dat(' ');
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[e]); //
- write_1602dat(hex_table[f]); //
- write_1602dat(',');
- write_1602dat(hex_table[g]); //
- write_1602dat(hex_table[h]); //
-
- write_1602com(er);//指定顯
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[a1]); //
- write_1602dat(hex_table[b1]); //
- write_1602dat(',');
- write_1602dat(hex_table[c1]); //
- write_1602dat(hex_table[d1]); //
- write_1602dat(' ');
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[e1]); //
- write_1602dat(hex_table[f1]); //
- write_1602dat(',');
- write_1602dat(hex_table[g1]); //
- write_1602dat(hex_table[h1]); //
-
- }
- if(xianshi==2)
- {
- uchar a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1;
- a = (yi%256)/16; // 十位
- b = (yi%256)%16; // 個位
- c = (ra%256)/16; // 十位
- d = (ra%256)%16; // 個位
- e = (yi+1%256)/16; // 十位
- f = (yi+1%256)%16; // 個位
- g = (si%256)/16; // 十位
- h = (si%256)%16; // 個位
- a1 = (yi+2%256)/16; // 十位
- b1 = (yi+2%256)%16; // 個位
- c1 = (ra1%256)/16; // 十位
- d1 = (ra1%256)%16; // 個位
- e1 = (yi+3%256)/16; // 十位
- f1 = (yi+3%256)%16; // 個位
- g1 = (si1%256)/16; // 十位
- h1 = (si1%256)%16; // 個位
- write_1602com(yh);//指定顯示
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[a]); //
- write_1602dat(hex_table[b]); //
- write_1602dat(',');
- write_1602dat(hex_table[c]); //
- write_1602dat(hex_table[d]); //
- write_1602dat(' ');
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[e]); //
- write_1602dat(hex_table[f]); //
- write_1602dat(',');
- write_1602dat(hex_table[g]); //
- write_1602dat(hex_table[h]); //
-
- write_1602com(er);//指定顯
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[a1]); //
- write_1602dat(hex_table[b1]); //
- write_1602dat(',');
- write_1602dat(hex_table[c1]); //
- write_1602dat(hex_table[d1]); //
- write_1602dat(' ');
- write_1602dat('0');
- write_1602dat('x');
- write_1602dat(hex_table[e1]); //
- write_1602dat(hex_table[f1]); //
- write_1602dat(',');
- write_1602dat(hex_table[g1]); //
- write_1602dat(hex_table[h1]); //
-
-
- }
- }
- 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();
- }
- void NoAck() //發 ACK0
- {
- SDA=1;
- delay();
- SCL=1;
- delay();
- SCL=0;
- delay();
-
- }
-
- bit TestAck() //測試 ACK
- {
- bit ErrorBit;
- SDA=1;
- delay();
- SCL=1;
- delay();
- ErrorBit=SDA;
-
- delay();
- SCL=0;
- delay();
- return(ErrorBit);
- }
- 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 Write24c02(uchar ch,uchar address)//寫入一個字節到 24c02 中
- {
- Start();
- Write8Bit(WriteDeviceAddress);
- TestAck();
- Write8Bit(address);
- TestAck();
- Write8Bit(ch);
- TestAck();
- Stop();
- delay1(10);
- }
- //從 24c02 中讀出 8 個 bit
- uchar Read8Bit()
- {
- unsigned char temp,rbyte=0;
- for(temp=8;temp!=0;temp--)
- {
- SCL=1;
- rbyte=rbyte<<1;
- rbyte=rbyte|((unsigned char)(SDA));
- SCL=0;
- }
- return(rbyte);
- }
-
- uchar Read24c02(uchar address) //從 24c02 中讀出 1 個字節
- {
- uchar ch;
- Start();
- Write8Bit(WriteDeviceAddress);
- TestAck();
- Write8Bit(address);
- TestAck();
- Start();
- Write8Bit(ReadDviceAddress);
- TestAck();
- ch=Read8Bit();
- NoAck();
- Stop();
- return(ch);
- }
- void xie()
- {
- Write24c02(ra,yi);
- delay1(10);
- Write24c02(si,yi+1);
- delay1(10);
- Write24c02(ra1,yi+2);
- delay1(10);
- Write24c02(si1,yi+3);
- delay1(10);
- Stop();
- }
- void du()
- {
- ra=Read24c02(yi);
- delay1(20);
- si=Read24c02(yi+1);
- delay1(20);
- ra1=Read24c02(yi+2);
- delay1(20);
- si1=Read24c02(yi+3);
- delay1(20);
- Stop();
- }
- void set()
- {
- Start();
- Write8Bit(WriteDeviceAddress);
- TestAck();
- delay1(5);
- Stop();
- }
- void keyscan()
- {
-
- if(k2==0)
- {
- delay1(10);
- if(!k2)
- {
- delay1(10);
- while(!k2);
- key1n+=1;
- if(key1n>2)
- {
- key1n=1;
- }
- switch(key1n)
- {
- case 1:open=1; key3n=0;dsplaysw=0; write_1602com(0x0c);ra=0;si=0;ra1=0;si1=0;//關閉光標
- break;
- case 2:open=0;num=0;jishu=0; dsplaysw=0;xianshi=0;lcd_init(); key2n=0; key3n=0;
- break;
- }
- }
- }
- if(k1==0)
- {
- delay1(10);
- if(!k1)
- {
- delay1(10);
- while(!k1);
- key2n+=1;
- if(key2n>2)
- {
- key2n=1;
- }
- switch(key2n)
- {
- case 1: du();xianshi=1;key3n=0; dsplaysw=0; write_1602com(0x0c);//關閉光標
- break;
- case 2: dsplaysw=1;xianshi=2; write_1602com(yh+5);write_1602com(0x0f);key3n=1;
- break;
- }
- }
- }
-
- if(key2n==2)
- {
- if(k3==0)
- {
- delay1(50);
- if(!k3)
- {
- delay1(50);
- while(!k3);
- key3n+=1;
- if(key3n>5)
- {
- key3n=1;
- }
- switch(key3n)
- {
- case 1: write_1602com(yh+5); //設置按鍵按動一次秒位置顯示光標
- write_1602com(0x0f); //設置光標為閃爍
- break;
- case 2: write_1602com(yh+13);
- write_1602com(0x0f); //設置光標為閃爍
- break;
- case 3: write_1602com(er+5);
- write_1602com(0x0f); //設置光標為閃爍
- break;
- case 4: write_1602com(er+13);
- write_1602com(0x0f); //設置光標為閃爍
- break;
- case 5: write_1602com(0x0c);//關閉光標
- xie();
- xianshi=1;key2n=1;key3n=0; dsplaysw=0;
- break;
- }
- }
- }
- }
- }
- uint CodingsWitchPolling()
- {
- static uchar Aold,Bold; //兩個變量用來儲存上一次調用時編碼開關兩引腳的電平
- static uchar st=0; //用來儲存以前是否出現了兩個引腳都為高電平的狀態
- static uint tmp=0; // ***這3個均為靜態變量,以便保持上次結果***
-
- if(CodingsWitch_A&&CodingsWitch_B)
- st = 1;
- if(st) //如果st為1執行下面的步驟
- {
- if(CodingsWitch_A==0&&CodingsWitch_B==0) //如果兩引腳都為低執行下面
- {
- if(Bold) //為高說明編碼開關在向加大的方向轉
- {
- st = 0;
- if(yi==9999)yi=9999;
- if(ra>255)ra=0;
- if(si>255)si=0;
- if(ra1>255)ra1=0;
- if(si1>255)si1=0;
- else
- if(key2n==1){yi+=4;du();}
- if(key3n==1){ra+=1;write_1602com(0x0c);dsplay();write_1602com(yh+5);write_1602com(0x0f);}
- if(key3n==2){si+=1;write_1602com(0x0c);dsplay();write_1602com(yh+13);write_1602com(0x0f);}
- if(key3n==3){ra1+=1;write_1602com(0x0c);dsplay();write_1602com(er+5);write_1602com(0x0f);}
- if(key3n==4){si1+=1;write_1602com(0x0c);dsplay();write_1602com(er+13);write_1602com(0x0f);}
- }
- if(Aold) //為高說明編碼開關在向減小的方向轉
- {
- st = 0;
- if(yi==0)yi=0;
- if(ra<0)ra=0;
- if(si<0)si=0;
- if(ra1<0)ra1=0;
- if(si1<0)si1=0;
- else
- if(key2n==1){yi-=4;du();} //設返回值
- if(key3n==1){ra-=1;write_1602com(0x0c);dsplay();write_1602com(yh+5);write_1602com(0x0f);}
- if(key3n==2){si-=1;write_1602com(0x0c);dsplay();write_1602com(yh+13);write_1602com(0x0f);}
- if(key3n==3){ra1-=1;write_1602com(0x0c);dsplay();write_1602com(er+5);write_1602com(0x0f);}
- if(key3n==4){si1-=1;write_1602com(0x0c);dsplay();write_1602com(er+13);write_1602com(0x0f);}
- }
- }
-
- }
-
- Aold = CodingsWitch_A; //保持這次檢測的電平,以備下次調用比較用
- Bold = CodingsWitch_B; //
- return tmp; //返回計數值
- }
-
- void main()
- {
- lcd_init();
- Init_Timer0();
- while(1)
- {
- keyscan();
- if(dsplaysw==0){dsplay();}
- }
- }
- void Init_Timer0(void)
- {
- TMOD=0x01;
- ET0=1; //定時器中斷打開
- TR0=1; //定時器開關打開
- ET1=1; //定時器中斷打開
- TR1=1; //定時器開關打?
- EA=1; //總中斷打開
- }
- void Timer0_isr(void) interrupt 1
- {
-
- TH0=(65536-50000)/256; //重新賦值 2ms 62500
- TL0=(65536-50000)%256;
-
- if(open==1)
- {
- num++;
- if(num==3)
- {
- num=0;
- jishu++;
- set();
- if(jishu>255)
- {
- jishu=255;
- }
- }
-
- }
-
-
- }
-
- void Timer1_isr(void) interrupt 3
- {
- TH1=0xec;
- TL1=0xec;
- CodingsWitchPolling(); //調用編碼開關函數
-
- }
復制代碼
所有資料51hei提供下載:
i2c測地址.rar
(87.22 KB, 下載次數: 36)
2020-2-23 20:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|