51单片机之I^2C总线
2016-11-23 来源:eefocus
I^2C总线的SDA与CLK都是线与关系.
为了避免混乱I^2C总线要通过总线仲裁决定总线由哪一台主机控制
I^2C总线的数据位的有效性:时钟信号为高电平期间
数据线上的数据必须保持稳定,只有在时钟信号为低电平时,
数据线上的数据才可以变化.
图片
I^2C总线的起始信号与终止信号,每一字节必须是8位长度
发完还有一位应答位,所以一共会有9位.
在编写程序时,只要严格按照时序图来,万事OK,下面是我写的一示例程序,功能是先向2402芯片写入一字节数据,然后再将其读出,显示到数码管
#include#define uint unsigned int #define uchar unsigned char sbit scl = P1^6; sbit sda = P1^7; uchar code table[]={0x7e,0x0c,0xb6,0x9e,0xcc,0xda,0xfa,0x0e,0xfe,0xde}; sbit sda0 = P1^0; sbit clk = P1^1; sbit dig1 = P1^2; sbit dig2 = P1^3; sbit dig3 = P1^4; sbit dig4 = P1^ 5; void delay(uint); /** 初始化IIC,将i^2C总线的电平拉高 **/ void init() { sda = 1; scl = 1; delay(1); } /** 向IIC写入一个字节 **/ void write_byte(uchar b) { uchar i,temp; temp = b; scl = 0; for(i=0;i<8;i++) { temp <<= 1; sda = CY; delay(1); scl = 1; delay(1); scl = 0; } delay(1); scl = 0; sda = 1; } /** 从IIC读出一字节数据 **/ uchar read_byte() { uchar i,temp; scl = 0; sda = 1; delay(1); for(i=0;i<8;i++) { delay(1); temp <<= 1; scl = 1; delay(1); temp |= sda; delay(1); scl = 0; } delay(1); scl = 0; sda = 1; return temp; } /** IIC的开始信号 **/ void start() { sda = 1; delay(1); scl = 1; delay(1); sda = 0; delay(1); sda = 1; scl = 0; } /** IIC的停止信号 **/ void stop() { sda = 0; delay(1); scl = 1; delay(1); sda = 1; scl = 0; delay(1); } /** IIC的应答函数 **/ void response() { uchar temp = 0; sda = 1; scl = 0; delay(1); while(sda && temp<250) temp ++; scl = 1; delay(1); scl = 0; delay(1); sda = 1; } //延迟函数 void delay(uint u) { uint x,y; for(x=u;x>0;x--) for(y=110;y>0;y--); } /** 向数据码管写入一个字节数据 **/ void write(uchar u) { uchar i; for(i=0;i<8;i++) { clk = 1; sda0 = u&0x80; clk = 0; u = u<<1; } } /** 显示一个3位的整数 **/ void display(uchar num) { uchar bai,shi,ge; bai = num/100; shi = num%100/10; ge = num%10; /* 显示个位 */ dig4 = 0; write(table[ge]); delay(10); dig4 = 1; /* 显示十位 */ dig3 = 0; write(table[shi]); delay(10); dig3 = 1; /* 显示百位 */ dig2 = 0; write(table[bai]); delay(10); dig2 = 1; } /** 向2402芯片指定地址写入一字节数据 **/ void write2402(uchar add,uchar u) { start(); write_byte(0xa0); response(); write_byte(add); response(); write_byte(u); response(); stop(); } /** 从2402芯片指定地址读出一字节数据 **/ uchar read2402(uchar add) { uchar result; start(); write_byte(0xa0); response(); write_byte(add); response(); start(); write_byte(0xa1); response(); result = read_byte(); stop(); return result; } void main() { uchar result; init(); write2402(5,159); delay(20); result = read2402(5); while(1) display(result); }
上一篇:MCS-51单片机之液晶显示
相关文章