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; }
/**************************实现函数******************************************** *函数原型: 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; }
/* 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++; } }
/**************************实现函数******************************************** *函数原型: 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; }
//读取3个轴的数据 //x,y,z:读取到的数据 void ADXL345_RD_XYZ(short *x,short *y,short *z) { u8 buf[6]; u8 i; IIC_Start(); IIC_Send_Byte(ADXL_WRITE); //发送写器件指令 IIC_Wait_Ack(); IIC_Send_Byte(0x32); //发送寄存器地址(数据缓存的起始地址为0X32) IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(ADXL_READ); //发送读器件指令 IIC_Wait_Ack(); for(i=0;i<6;i++) { if(i==5)buf[i]=IIC_Read_Byte(0);//读取一个字节,不继续再读,发送NACK else buf[i]=IIC_Read_Byte(1); //读取一个字节,继续读,发送ACK } IIC_Stop(); //产生一个停止条件 *x=(short)(((u16)buf[1]<<8)+buf[0]); *y=(short)(((u16)buf[3]<<8)+buf[2]); *z=(short)(((u16)buf[5]<<8)+buf[4]); }
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; }
/*********************************** 函数名: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; }
//读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; //返回读到的值 }
//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; }
//IIC连续读 //addr:器件地址 //reg:要读取的寄存器地址 //len:要读取的长度 //buf:读取到的数据存储区 //返回值:0,正常 // 其他,错误代码 uint8_t MPU_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf) { IIC_Start(); IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 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);//读数据,发送nACK else *buf=IIC_Read_Byte(1); //读数据,发送ACK len--; buf++; } IIC_Stop(); //产生一个停止条件 return 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; }
/**************************实现函数******************************************** *函数原型: 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 Get_Accel_Data(u8 reg) 说明:得到MPU6050加速度计数据 入口:u8 reg 寄存器地址 出口:无 备注:无 ***********************************/ void Get_Accel_Data(u8 reg) { u8 H1, L1; u8 H2, L2; u8 H3, L3; IIC_Start(); IIC_Send_Byte(MPU6050_DEVICE); // 发送器件地址+写信号 IIC_Send_Byte(reg); // 需要读取的寄存器地址 IIC_Start(); IIC_Send_Byte(MPU6050_DEVICE + 1); // 发送器件地址+读信号 H1 = IIC_Read_Byte(1); // 读取数据产生应答 L1 = IIC_Read_Byte(1); // 按照地址顺序从低往高读取 H2 = IIC_Read_Byte(1); L2 = IIC_Read_Byte(1); H3 = IIC_Read_Byte(1); L3 = IIC_Read_Byte(0); IIC_Stop(); g_MPU6050Data.accel_x = (H1 << 8) + L1; g_MPU6050Data.accel_y = (H2 << 8) + L2; g_MPU6050Data.accel_z = (H3 << 8) + L3; }