/****************************************************************************** 函数(模块)名称:unsigned char IIC_Page_Write(unsigned char W_addr, unsigned char *WriteData_Addr, unsigned char WriteData_Cnt) 功能: IIC页写 输入参数: 要写的地址,要写的数据指针,要写的字节数 输出参数: 1 写成功 0 写失败 其它说明: 要写的字节数,不能大于当前写字节地址到当前页最大地址之差。 *******************************************************************************/ unsigned char IIC_Page_Write(unsigned char W_addr,unsigned char *WriteData_Addr, unsigned char WriteData_Cnt) { unsigned char try_time=define_try_time; //用来定义出现通讯错误时尝试的错误 while(1) { if(!try_time--) //用来防止因硬件错误或其它原因程序进入死循环 { return 0; } IIC_Start(); //步骤1:主机产生一个启动信号 IIC_Send_Byte(Slave_Addres&(~BIT0)); //步骤2:主机发送从机地址及读写位 if(ReadAck()) continue; //步骤3:主机接收从机应答;没有应答,忽略下面语句,重新开始 //应答,则开始发送地址 IIC_Send_Byte(W_addr); //步骤4:主机发送读写地址 if(ReadAck()) continue; //步骤5:主机接收从机应答 没有应答,忽略下面语句,重新开始 while(WriteData_Cnt--) { IIC_Send_Byte(*(WriteData_Addr++)); if(!ReadAck()) continue; //收到应答(0),则继续发送数据 return 0; //没收到应答,错误返回 } break; } IIC_Stop(); //步骤8:主机发送停止信号,启动写周期 Delay(5000); //需要延时一段时间,等待写周期完成 return 1; }
/****************************************************************************** 函数(模块)名称:unsigned char IIC_Single_Write(unsigned char W_addr,unsigned char Date_byte) 功能: IIC总线单字节写 输入参数: 要写的地址,要写的数据 输出参数: 1 写成功 0 写失败 其它说明: *******************************************************************************/ unsigned char IIC_Single_Write(unsigned char W_addr,unsigned char Date_byte) { unsigned char try_time=define_try_time; //用来定义出现通讯错误时尝试的错误 while(1) { if(!try_time--) //用来防止因硬件错误或其它原因程序进入死循环 { return 0; } IIC_Start(); //步骤1:主机产生一个启动信号 IIC_Send_Byte(Slave_Addres&(~BIT0)); //步骤2:主机发送从机地址及读写位 if(ReadAck()) continue; //步骤3:主机接收从机应答;没有应答,忽略下面语句,重新开始 //应答,则开始发送地址 IIC_Send_Byte(W_addr); //步骤4:主机发送读写地址 if(ReadAck()) continue; //步骤5:主机接收从机应答 没有应答,忽略下面语句,重新开始 IIC_Send_Byte(Date_byte); //步骤6:主机发送数据 //应答,则开始发送要写入的数据 if(ReadAck()) //步骤7:机接收从机应答 continue; //没有应答,忽略下面语句,重新开始 break; //应答,则跳出循环 } IIC_Stop(); //步骤8:主机发送停止信号,启动写周期 Delay(5000); //需要延时一段时间,等待写周期完成 return 1; }
u8 IIC1_MultWrite(u8 slaveAddr, u8* pBuffer, u8 wrtieAddr, u16 NumByteToWrite) { IIC_Start(); //起始信号 IIC_Send_Byte(slaveAddr); //发送设备地址+写信号 if(FALSE==IIC_Wait_Ack()) { IIC_Stop(); //发送停止信号 return 1; } IIC_Send_Byte(wrtieAddr); //内部寄存器地址 IIC_Wait_Ack(); while(NumByteToWrite) { IIC_Send_Byte(*pBuffer); //内部寄存器数据 if(FALSE==IIC_Wait_Ack()) { IIC_Stop(); //发送停止信号 return 1; } pBuffer++; NumByteToWrite--; } IIC_Stop(); //发送停止信号 return 0; }
/****************************************************************************** 函数(模块)名称:unsigned char IIC_Single_Read(unsigned int R_addr,unsigned char *R_word) 功能: 单次读/随机读 输入参数: 要读的数据地址,输出数据保存的字节指针 输出参数: 1 读成功 0 读失败 其它说明: *******************************************************************************/ unsigned char IIC_Single_Read(unsigned char R_addr,unsigned char *R_word) { unsigned char try_time=define_try_time; //用来定义出现通讯错误时尝试的错误 while(1) { if(!try_time--) //用来防止因硬件错误或其它原因程序进入死循环 { return 0; } IIC_Start(); //步骤1:产生一个启动信号 IIC_Send_Byte(Slave_Addres&(~BIT0)); //步骤2:发送控制命令 if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 //应答,则开始发送地址 IIC_Send_Byte(R_addr); if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 //应答,则开始发送启动信号 IIC_Start(); //启动信号 IIC_Send_Byte(Slave_Addres|BIT0); //发送控制命令 if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 break; //应答,则跳出循环,开始接收数据 } *R_word=IIC_Receive_Byte(); //从总线上接收一个字节数据 WriteAck(1); //发送 非应答信号 IIC_Stop(); //发送停止信号 return 1; }
/**************************实现函数******************************************** *函数原型: bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data) *功 能: *******************************************************************************/ int i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf) { if (!IIC_Start()) return 1; IIC_Send_Byte(addr << 1); if (!IIC_Wait_Ack()) { IIC_Stop(); return 1; } IIC_Send_Byte(reg); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte((addr << 1)+1); IIC_Wait_Ack(); while (len) { if (len == 1) *buf = IIC_Read_Byte(0); else *buf = IIC_Read_Byte(1); buf++; len--; } IIC_Stop(); return 0; }
uint8_t IIC_Read_Bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data) { uint8_t count = 0; uint8_t temp; IIC_Start(); IIC_Send_Byte(dev); IIC_Wait_Ack(); IIC_Send_Byte(reg); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(dev + 1); IIC_Wait_Ack(); for(count = 0; count < length; count++) { if(count != (length - 1) ) temp = IIC_Receive_Byte(1); else temp = IIC_Receive_Byte(0); data[count] = temp; } IIC_Stop(); return count; }
//IIC写一个字节 //reg:寄存器地址 //data:数据 //返回值:0,正常 // 其他,错误代码 u8 MPU_Write_Byte(u8 reg,u8 data) { IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { printf("in MPU_Write_Byte: failed at 1,reg=%X,data=%X\n",reg,data); IIC_Stop(); return 1; } IIC_Send_Byte(reg); //写寄存器地址 if(IIC_Wait_Ack()){ printf("in MPU_Write_Byte: failed at 2,reg=%X,data=%X\n",reg,data); IIC_Stop(); return 1; } //等待应答 IIC_Send_Byte(data);//发送数据 if(IIC_Wait_Ack()) //等待ACK { printf("in MPU_Write_Byte: failed at 3,reg=%X,data=%X\n",reg,data); IIC_Stop(); return 1; } IIC_Stop(); return 0; }
void SetUpADS1110(unsigned char x) { IIC_Start(); IIC_Send_Byte(ADS1110_ADDR & 0xFE); IIC_Send_Byte(x); IIC_Stop(); }
u8 IIC1_MultRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead) { IIC_Start(); //起始信号 IIC_Send_Byte(slaveAddr); //发送写器件指令 if(FALSE==IIC_Wait_Ack()) { IIC_Stop(); //发送停止信号 return 1; } IIC_Send_Byte(readAddr); //发送寄存器地址 IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(slaveAddr+1); //发送读器件指令 IIC_Wait_Ack(); /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { *pBuffer=IIC_Read_Byte(0); //读出寄存器数据不继续再读,发送NACK } else { *pBuffer=IIC_Read_Byte(1); //读出寄存器数据继续读,发送ACK pBuffer++; /* Point to the next location where the byte read will be saved */ } /* Decrement the read bytes counter */ NumByteToRead--; } IIC_Stop(); //停止信号 return 0; }
/*********************************************** 函数名:void MPU6050_WirteByte(u8 reg, u8 data) 说明:MPU6050单次写字节 入口:u8 reg 寄存器地址 u8 data 需要写入的字节 出口:无 备注:无 ***********************************************/ void MPU6050_WirteByte(u8 reg, u8 data) { IIC_Start(); IIC_Send_Byte(MPU6050_DEVICE); // 发送器件地址+写信号 IIC_Send_Byte(reg); // 寄存器地址 IIC_Send_Byte(data); // 需要写入的数据 IIC_Stop(); }
//写ADXL345寄存器 //addr:寄存器地址 //val:要写入的值 //返回值:无 void ADXL345_WR_Reg(u8 addr,u8 val) { IIC_Start(); IIC_Send_Byte(ADXL_WRITE); //发送写器件指令 IIC_Wait_Ack(); IIC_Send_Byte(addr); //发送寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte(val); //发送值 IIC_Wait_Ack(); IIC_Stop(); //产生一个停止条件 }
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data) { IIC_Start(); IIC_Send_Byte(daddr);//器件地址+写信号 IIC_Wait_Ack(); IIC_Send_Byte(addr);//寄存器 IIC_Wait_Ack(); IIC_Send_Byte(data);//数据 IIC_Wait_Ack(); IIC_Stop(); }
bool IIC1_WriteByte(u8 slaveAddr,u8 REG_Address,u8 REG_data) { bool retval; IIC_Start(); //起始信号 IIC_Send_Byte(slaveAddr); //发送设备地址+写信号 retval=IIC_Wait_Ack(); IIC_Send_Byte(REG_Address); //内部寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte(REG_data); //内部寄存器数据 IIC_Wait_Ack(); IIC_Stop(); //发送停止信号 return retval; }
//WM8978写寄存器 //reg:寄存器地址 //val:要写入寄存器的值 //返回值:0,成功; // 其他,错误代码 u8 WM8978_Write_Reg(u8 reg,u16 val) { IIC_Start(); IIC_Send_Byte((WM8978_ADDR<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack())return 1; //等待应答(成功?/失败?) IIC_Send_Byte((reg<<1)|((val>>8)&0X01));//写寄存器地址+数据的最高位 if(IIC_Wait_Ack())return 2; //等待应答(成功?/失败?) IIC_Send_Byte(val&0XFF); //发送数据 if(IIC_Wait_Ack())return 3; //等待应答(成功?/失败?) IIC_Stop(); WM8978_REGVAL_TBL[reg]=val; //保存寄存器值到本地 return 0; }
/*********************************** 函数名:u8 MPU6050_ReadByte(u8 reg) 说明:MPU6050单次读字节 入口:u8 reg 寄存器地址 出口:u8 读取到的字节 备注:无 ************************************/ u8 MPU6050_ReadByte(u8 reg) { u8 tmp; IIC_Start(); IIC_Send_Byte(MPU6050_DEVICE); // 发送器件地址+写信号 IIC_Send_Byte(reg); // 需要读取的寄存器地址 IIC_Start(); IIC_Send_Byte(MPU6050_DEVICE + 1); // 发送器件地址+读信号 tmp = IIC_Read_Byte(0); // 读取数据不产生应答 IIC_Stop(); return tmp; }
u8 IIC1_ReadByte(u8 slaveAddr, u8 readAddr) { u8 REG_data; IIC_Start(); //起始信号 IIC_Send_Byte(slaveAddr); //发送设备地址+写信号 IIC_Wait_Ack(); IIC_Send_Byte(readAddr); //发送存储单元地址,从0开始 IIC_Wait_Ack(); //必须要有 IIC_Start(); //起始信号 IIC_Send_Byte(slaveAddr+1); //发送设备地址+读信号 IIC_Wait_Ack(); REG_data=IIC_Read_Byte(0); //读出寄存器数据不继续再读,发送NACK return REG_data; }
//IIC读一个字节 //reg:寄存器地址 //返回值:读到的数据 uint8_t MPU_Read_Byte(uint8_t reg) { uint8_t res; IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令 IIC_Wait_Ack(); //等待应答 res=IIC_Read_Byte(0);//读取数据,发送nACK IIC_Stop(); //产生一个停止条件 return res; }
//读ADXL345寄存器 //addr:寄存器地址 //返回值:读到的值 u8 ADXL345_RD_Reg(u8 addr) { u8 temp=0; IIC_Start(); IIC_Send_Byte(ADXL_WRITE); //发送写器件指令 temp=IIC_Wait_Ack(); IIC_Send_Byte(addr); //发送寄存器地址 temp=IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(ADXL_READ); //发送读器件指令 temp=IIC_Wait_Ack(); temp=IIC_Read_Byte(0); //读取一个字节,不继续再读,发送NAK IIC_Stop(); //产生一个停止条件 return temp; //返回读到的值 }
/**************************实现函数******************************************** *函数原型: u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data) *功 能: 将多个字节写入指定设备 指定寄存器 输入 dev 目标设备地址 reg 寄存器地址 length 要写的字节数 *data 将要写的数据的首地址 返回 返回是否成功 *******************************************************************************/ u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data){ u8 count = 0; IIC_Start(); IIC_Send_Byte(dev); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(reg); //发送地址 IIC_Wait_Ack(); for(count=0;count<length;count++){ IIC_Send_Byte(data[count]); IIC_Wait_Ack(); } IIC_Stop();//产生一个停止条件 return 1; //status == 0; }
/**************************实现函数******************************************** *函数原型: uint8_t IIC_Write_Bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data) *功 能: 将多个字节写入指定设备 指定寄存器 *输入 dev 目标设备地址 * reg 寄存器地址 * length 要写的字节数 * *data 将要写的数据的首地址 *返回 返回是否成功 *******************************************************************************/ uint8_t IIC_Write_Bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data) { uint8_t count = 0; IIC_Start(); IIC_Send_Byte(dev); IIC_Wait_Ack(); IIC_Send_Byte(reg); IIC_Wait_Ack(); for(count = 0; count < length; count++) { IIC_Send_Byte(data[count]); IIC_Wait_Ack(); } IIC_Stop(); return 1; //status == 0; }
u8 IIC_Read_One_Byte(u8 daddr,u8 addr) { u8 temp; IIC_Start(); IIC_Send_Byte(daddr);//器件地址+写信号 IIC_Wait_Ack(); IIC_Send_Byte(addr);//寄存器 IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(daddr+1);//器件地址+读信号 IIC_Wait_Ack(); temp = IIC_Read_Byte(0); IIC_Stop(); return temp; }
/** * @Function u8 AT24CXX_ReadOneByte(u16 ReadAddr); * @description 在AT24CXX指定地址读出一个数据 * @Input u16 ReadAddr:开始读数的地址 * @Return u8 读到的数据 */ u8 AT24CXX_ReadOneByte(u16 ReadAddr) { u8 temp=0; IIC_Start(); if(EE_TYPE>AT24C16) { IIC_Send_Byte(0XA0); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr>>8); //发送高地址 }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
/**************************实现函数******************************************** *函数原型: unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr) *功 能: 读取指定设备 指定寄存器的一个值 输入 I2C_Addr 目标设备地址 addr 寄存器地址 返回 读出来的值 *******************************************************************************/ unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr) { unsigned char res=0; IIC_Start(); IIC_Send_Byte(I2C_Addr); //发送写命令 res++; IIC_Wait_Ack(); IIC_Send_Byte(addr); res++; //发送地址 IIC_Wait_Ack(); //IIC_Stop();//产生一个停止条件 IIC_Start(); IIC_Send_Byte(I2C_Addr+1); res++; //进入接收模式 IIC_Wait_Ack(); res=IIC_Read_Byte(0); IIC_Stop();//产生一个停止条件 return res; }
/* void Read_16bit_Register(unsigned char command_H, unsigned char command_L, unsigned char *RegisterData) { unsigned char buffer[2]; IIC_Start(); IIC_Send_Byte(Command_W); IIC_Wait_Ack(); IIC_Send_Byte(command_H); IIC_Wait_Ack(); IIC_Send_Byte(command_L); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(Command_R); IIC_Wait_Ack(); //delay_ms(WaitTime); IIC_Read_Byte(1,&buffer[0]); IIC_Read_Byte(0,&buffer[1]); IIC_Stop(); *RegisterData = buffer[0]; RegisterData++; *RegisterData = buffer[1]; } */ void Read_Register(unsigned char command_H, unsigned char command_L, unsigned char *RegisterData,unsigned char x_Bit) { unsigned char buffer[4]; unsigned char count; IIC_Start(); IIC_Send_Byte(Command_W); IIC_Wait_Ack(); IIC_Send_Byte(command_H); IIC_Wait_Ack(); IIC_Send_Byte(command_L); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(Command_R); IIC_Wait_Ack(); //delay_ms(WaitTime); count = x_Bit; for(unsigned char i = 0; i < x_Bit; i++) { count--; if(count == 0) IIC_Read_Byte(0,&buffer[i]); else IIC_Read_Byte(1,&buffer[i]); } IIC_Stop(); for(unsigned char i = 0; i < x_Bit; i++) { *RegisterData = buffer[i]; RegisterData++; } }
/********************************************************************************************************* ** Function name: AT24CXX_ReadOneByte ** Descriptions: 在AT24CXX指定地址读出一个数据 ** input parameters: ReadAddr:开始读数的地址 ** output parameters: ** Returned value: 读到的数据 *********************************************************************************************************/ uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr) { uint8_t temp=0; IIC_Start(); if(EE_TYPE>AT24C16) { IIC_Send_Byte(0XA0); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr>>8);//发送高地址 }
/**************************实现函数******************************************** *函数原型: u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data) *功 能: 读取指定设备 指定寄存器的 length个值 输入 dev 目标设备地址 reg 寄存器地址 length 要读的字节数 *data 读出的数据将要存放的指针 返回 读出来的字节数量 *******************************************************************************/ u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){ u8 count = 0; IIC_Start(); IIC_Send_Byte(dev); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(reg); //发送地址 IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(dev+1); //进入接收模式 IIC_Wait_Ack(); for(count=0;count<length;count++){ if(count!=length-1)data[count]=IIC_Read_Byte(1); //带ACK的读数据 else data[count]=IIC_Read_Byte(0); //最后一个字节NACK } IIC_Stop();//产生一个停止条件 return count; }
//IIC写一个字节 //reg:寄存器地址 //data:数据 //返回值:0,正常 // 其他,错误代码 uint8_t MPU_Write_Byte(uint8_t reg,uint8_t data) { IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { IIC_Stop(); return 1; } IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(data);//发送数据 if(IIC_Wait_Ack()) //等待ACK { IIC_Stop(); return 1; } IIC_Stop(); return 0; }
/*............................................................................. @Name : AT24Cxx_ReadOneByte @Param : u16 ReadAddr ��ʼ��ȡ�ĵ�ַ @return : u8 ��ȡ�������� @Info : ��AT24Cxxָ����ַ��ȡһ������ .............................................................................*/ u8 AT24Cxx_ReadOneByte(u16 ReadAddr) { u8 temp = 0; IIC_Start(); if(EE_TYPE>AT24C16) { IIC_Send_Byte(0xA0); //����дָ��,ǰ4bit�̶�Ϊ1010 ����3bitΪ A2 A1 A0 Ӳ������, //(ϵͳ���ɽ�8���豸2^3=8) ���1bit������д 1 �� 0 д //0xA0 = 1010 000 0д IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr>>8); //���ߵ�ַ }else
/**************************实现函数******************************************** *函数原型: bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data) *功 能: *******************************************************************************/ int i2cWrite(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *data) { int i; if (!IIC_Start()) return 1; IIC_Send_Byte(addr << 1 ); if (!IIC_Wait_Ack()) { IIC_Stop(); return 1; } IIC_Send_Byte(reg); IIC_Wait_Ack(); for (i = 0; i < len; i++) { IIC_Send_Byte(data[i]); if (!IIC_Wait_Ack()) { IIC_Stop(); return 0; } } IIC_Stop(); return 0; }
/****************************************************************************** 函数(模块)名称:unsigned char IIC_Multi_read(unsigned int R_addr,unsigned char *Save_addr, unsigned int R_lent) 功能: 连续读 输入参数: 读起始地址,数据保存指针,读长度 输出参数: 1 读成功 0 读失败 其它说明: *******************************************************************************/ unsigned char IIC_Multi_read(unsigned char R_addr,unsigned char *Save_addr, unsigned int R_lent) { unsigned char try_time=define_try_time; //用来定义出现通讯错误时尝试的错误 while(1) { if(!try_time--) //用来防止因硬件错误或其它原因程序进入死循环 { return 0; } IIC_Start(); //步骤1:产生一个启动信号 IIC_Send_Byte(Slave_Addres&(~BIT0)); //步骤2:发送控制命令 if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 //应答,则开始发送地址 IIC_Send_Byte(R_addr); if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 //应答,则开始发送启动信号 IIC_Start(); //启动信号 IIC_Send_Byte(Slave_Addres|BIT0); //发送控制命令 if(ReadAck()) continue; //没有应答,忽略下面语句,重新开始 break; //应答,则跳出循环,开始接收数据 } while(R_lent--) { *Save_addr++=IIC_Receive_Byte(); //从总线上接收一个字节数据 if(R_lent==0) { WriteAck(1); //发送 非应答信号 IIC_Stop(); //发送停止信号 break; } WriteAck(0); //发送应答信号 } return 1; }