还在为找不到I2C设备的地址而烦恼??
别慌,我带着代码走来了
按下按键,开始从0x01开始测试器件地址,一直到0xff结束。
查询到正确地址后,蜂鸣器叫2声,串口打印地址码,不再继续查询。
地址码输出至P1,在没有显示屏和不方便使用串口监视的情况下可通过LED状态读出地址。
初始版本没有增加地址码验证(验证的话就是用这个地址去读写数据显示出来就行)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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提供下载:
I2C地址查询.zip
(94.15 KB, 下载次数: 28)
|