1.I2C协议怎么写
void delay_scl() { unsigned data i=10; do {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } while(--i); } void delay(unsigned char data k)//精确延时k*0.1us { unsigned char data i=250; do{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}//执行一个nop为1个时钟周期 while(--i);} while(--k);//执行一个while为2个时钟周期 } void i2c_init() //I2C的初始化:SDA和SCL都为高电平 { sda=1; delay_scl(); scl=1; delay_scl(); } void i2c_start() //开始信号 { i2c_init(); sda=0; delay_scl(); } void i2c_stop() //停止信号 { sda=0; delay_scl(); scl=1; delay_scl(); sda=1; delay_scl(); } void i2c_response() //应答信号 { unsigned char xdata i; scl=1; delay_scl(); while((sda==1)&&(i<250))i++; scl=0; delay_scl(); } void i2cwrite_byte(unsigned char data dat) //写1个字节 {unsigned char xdata i,temp; temp=dat; for(i=0;i<8;i++) { temp=temp<<1; scl=0; delay_scl(); sda=CY; delay_scl(); scl=1; delay_scl(); } scl=0; delay_scl(); sda=1; delay_scl(); } unsigned char i2cread_byte() //读1个字节 { unsigned char xdata i,k; scl=0; delay_scl(); sda=1; delay_scl(); for(i=0;i<8;i++) { scl=1; delay_scl(); k=(k<<1)|sda; scl=0; delay_scl(); } return k; } void i2cwrite_add(unsigned char data address,unsigned char data dat) //写数据,1个字节地址位,1个字节数据 { i2c_start(); i2cwrite_byte(0xEE); // 16进制Oxa0转成8bit二进制数:前7位是设备号,末位"0"表示向设备写入。
i2c_response(); i2cwrite_byte(address); //写地址 i2c_response(); i2cwrite_byte(dat); //写数据 i2c_response(); i2c_stop(); delay(100); //收到stop命令后,需twr时间来写数据,此期间不接收任何信息 } unsigned char I2Cread_add(unsigned char data address) //读数据,1个字节地址位,函数返回数据值 { unsigned char xdata dat; i2c_start(); i2cwrite_byte(0xEE); //16进制Oxa0转成8bit二进制数:前7位是设备号,末位"0"表示向设备写入。 i2c_response(); i2cwrite_byte(address); //向设备写入需要查找的地址(移动设备内指针) i2c_response(); i2c_start(); //刷新,再次查找设备 i2cwrite_byte(0xEF); // 16进制Oxa0转成8bit二进制数:前7位是设备号,末位"1"表示从设备读取。
i2c_response(); dat=i2cread_byte(); //读取数据 i2c_stop(); //读完后主机返回"非应答"(高电平),并直接发出终止信号 delay(10); return dat; }。
2.I2C总线协议中的 应答函数,读写函数中,SDA和SCL到底该怎么判断
应答函数:
1. "ACK" is always to be responded by the i2c master or slaver which receving the current byte.
(1) current byte : slave address / word address / data
(2) ACK bit state : SCL drive by master
SDA drive by the i2c master or slaver which receving the current byte
(3) ACK : SDA=0 during SCL high cycle , No ACK : SDA=high-Z during SCL high cycle
2. Only need to repond the "No ACK" at last byte of read access by i2c master.
读写函数:
1. SCL always drive by master when either write access or read access
2. SDA drive by master when slave address , master wirte data byte (not include ACK bit)
SDA drive by slaver when master read/slaver write data byte (not include ACK bit)
3.c51单片机I2c总线的读写编程步骤
你说的是IO模拟i2c吧,这个你参考下#pragma ot(6,SIZE)#define ERRORCOUNT 10 enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256}; enum eepromtype EepromType;/****************************** I2C总线 ******************************/ bit RW24XX(uchar *DataBuff,uchar ByteQuantity,uint Address,uchar ControlByte,enum eepromtype EepromType) { void Delay(uchar DelayCount); void IICStart(void); void IICStop(void); bit IICRecAck(void); void IICNoAck(void); void IICAck(void); uchar IICReceiveByte(void); void IICSendByte(uchar sendbyte); uchar data j,i = ERRORCOUNT; bit errorflag = 1; while (i--) { IICStart(); IICSendByte(ControlByte & 0xfe); if (IICRecAck()) continue; if (EepromType > M2416) { IICSendByte((uchar)(Address >> 8)); if (IICRecAck()) continue; } IICSendByte((uchar)Address); if (IICRecAck()) continue; if (!(ControlByte & 0x01)) { j = ByteQuantity; errorflag = 0; while (j--) { IICSendByte(*DataBuff++); if(!IICRecAck()) continue; errorflag = 1; break; } if (errorflag==1) continue; break; } else { IICStart(); IICSendByte(ControlByte); if (IICRecAck()) continue; while (--ByteQuantity) { *DataBuff++ = IICReceiveByte(); IICAck(); } *DataBuff = IICReceiveByte(); //read last byte data IICNoAck(); errorflag = 0; break; } } IICStop(); if (!(ControlByte & 0x01)) { Delay(255); Delay(255); Delay(255); Delay(255); } return(errorflag); }/***************** 启动总线 ********************/ void IICStart(void) { scl = 0; sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda = 0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; sda = 1; }/***************** 停止IIC总线 ****************/ void IICStop(void) { scl = 0; sda = 0; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; }/************** 检查应答位 *******************/ bit IICRecAck(void) { scl = 0; sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); CY = sda; //因为返回值总是放在CY中的 scl = 0; return(CY); }/*************** 对IIC总线产生应答 *******************/ void IICACK(void) { sda = 0; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; _nop_(); _nop_(); sda = 1; }/***************** 不对IIC总线产生应答 ***************/ void IICNoAck(void) { sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; }/******************* 向IIC总线写数据 *********************/ void IICSendByte(uchar sendbyte) { uchar data j = 8; for (;j > 0;j--) { scl = 0; sendbyte <<= 1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7; sda = CY; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } scl = 0; }/***************** 从IIC总线上读数据子程序 ******************/ uchar IICReceiveByte(void) { register receivebyte,i = 8; scl = 0; while (i--) { scl = 1; receivebyte = (receivebyte << 1) | sda; scl = 0; } return(receivebyte); }/*************** 一个简单延时程序 ******************/ void Delay(uchar DelayCount) { while(DelayCount--); } void Delay_Msec(uchar t) { uchar i; while (t > 0) { for (i = 0;i < 200;i++) { WDT = 1; _nop_(); _nop_(); _nop_(); _nop_(); } t--; } }/*************** 24C256读一个字节 *****************/ uchar Rd_24c256(uint beginbyte) { uchar data result; uchar i; EA = 0; i = RW24XX(&result,1,beginbyte,rd_24c256,M24256); EA = 1; return(result); }/*************** 24C256写一个字节 ***************/ void Wr_24c256(uint address,uchar datum) { uchar i; EA = 0; i = RW24XX(&datum,1,address,wr_24c256,M24256); Delay_Msec(10); EA = 1; }。
4.c51单片机I2c总线的读写编程步骤
你说的是IO模拟i2c吧,这个你参考下#pragma ot(6,SIZE)#define ERRORCOUNT 10enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};enum eepromtype EepromType;/****************************** I2C总线 ******************************/bit RW24XX(uchar *DataBuff,uchar ByteQuantity,uint Address,uchar ControlByte,enum eepromtype EepromType){ void Delay(uchar DelayCount); void IICStart(void); void IICStop(void); bit IICRecAck(void); void IICNoAck(void); void IICAck(void); uchar IICReceiveByte(void); void IICSendByte(uchar sendbyte); uchar data j,i = ERRORCOUNT; bit errorflag = 1; while (i--) { IICStart(); IICSendByte(ControlByte & 0xfe); if (IICRecAck()) continue; if (EepromType > M2416) { IICSendByte((uchar)(Address >> 8)); if (IICRecAck()) continue; } IICSendByte((uchar)Address); if (IICRecAck()) continue; if (!(ControlByte & 0x01)) { j = ByteQuantity; errorflag = 0; while (j--) { IICSendByte(*DataBuff++); if(!IICRecAck()) continue; errorflag = 1; break; } if (errorflag==1) continue; break; } else { IICStart(); IICSendByte(ControlByte); if (IICRecAck()) continue; while (--ByteQuantity) { *DataBuff++ = IICReceiveByte(); IICAck(); } *DataBuff = IICReceiveByte(); //read last byte data IICNoAck(); errorflag = 0; break; } } IICStop(); if (!(ControlByte & 0x01)) { Delay(255); Delay(255); Delay(255); Delay(255); } return(errorflag);}/***************** 启动总线 ********************/void IICStart(void){ scl = 0; sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda = 0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; sda = 1;}/***************** 停止IIC总线 ****************/void IICStop(void){ scl = 0; sda = 0; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0;}/************** 检查应答位 *******************/bit IICRecAck(void){ scl = 0; sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); CY = sda; //因为返回值总是放在CY中的 scl = 0; return(CY);}/*************** 对IIC总线产生应答 *******************/void IICACK(void){ sda = 0; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0; _nop_(); _nop_(); sda = 1;}/***************** 不对IIC总线产生应答 ***************/void IICNoAck(void){ sda = 1; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); scl = 0;}/******************* 向IIC总线写数据 *********************/void IICSendByte(uchar sendbyte){ uchar data j = 8; for (;j > 0;j--) { scl = 0; sendbyte <<= 1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7; sda = CY; scl = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } scl = 0;}/***************** 从IIC总线上读数据子程序 ******************/uchar IICReceiveByte(void){ register receivebyte,i = 8; scl = 0; while (i--) { scl = 1; receivebyte = (receivebyte << 1) | sda; scl = 0; } return(receivebyte);}/*************** 一个简单延时程序 ******************/void Delay(uchar DelayCount){ while(DelayCount--);}void Delay_Msec(uchar t){ uchar i; while (t > 0) { for (i = 0;i < 200;i++) { WDT = 1; _nop_(); _nop_(); _nop_(); _nop_(); } t--; }}/*************** 24C256读一个字节 *****************/uchar Rd_24c256(uint beginbyte){ uchar data result; uchar i; EA = 0; i = RW24XX(&result,1,beginbyte,rd_24c256,M24256); EA = 1; return(result);}/*************** 24C256写一个字节 ***************/void Wr_24c256(uint address,uchar datum){ uchar i; EA = 0; i = RW24XX(&datum,1,address,wr_24c256,M24256); Delay_Msec(10); EA = 1;}。
5.怎么从I2C总线读数据
i2c有其协议的,我当时从不会到掌握其协议用了一阵子,就是狂读协议和例程 我把当时用非斯卡尔单片机读i2c mems传感器的历程写在下面#include
转载请注明出处育才学习网 » i2c读写函数怎么写(I2C协议怎么写)