uint8 hw_iic_write1(int MoudleNum,uint8 DeviceAddr, uint8 AccessAddr, uint8 Data) { //获取i2c模块基址 I2C_MemMapPtr num = hw_i2c_get_base_address(MoudleNum); I2C_C1_REG(num) |= 0x10; //TX = 1,MCU设置为发送模式 hw_send_signal('S',MoudleNum); //发送开始信号 I2C_D_REG(num) = DeviceAddr & 0xfe; //发送设备地址,并通知从机接收数据 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 return 1; //没有传送成功,写一个字节失败 if (hw_wait('A',MoudleNum)) //等待从机应答信号 return 1; //没有等到应答信号,写一个字节失败 I2C_D_REG(num) = AccessAddr; //发送访问地址 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 return 1; //没有传送成功,写一个字节失败 if (hw_wait('A',MoudleNum)) //等待从机应答信号 return 1; //没有等到应答信号,写一个字节失败 I2C_D_REG(num) = Data; //写数据 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 return 1; //没有传送成功,写一个字节失败 if (hw_wait('A',MoudleNum)) //等待从机应答信号 return 1; //没有等到应答信号,写一个字节失败 hw_send_signal('O',MoudleNum); //发送停止信号 return 0; }
/*! * @brief 读取I2C设备指定地址寄存器的数据 * @param I2Cn_e I2C模块(I2C0、I2C1) * @param SlaveID 从机地址(7位地址) * @param reg 从机寄存器地址 * @return 读取的寄存器值 * @since v5.0 * Sample usage: uint8 value = i2c_read_reg(I2C0, 0x1D, 1); */ uint8 i2c_read_reg(I2Cn_e i2cn, uint8 SlaveID, uint8 reg) { //先写入寄存器地址,再读取数据,因此此过程是 I2C 的复合格式,改变数据方向时需要重新启动 uint8 result; ASSERT((SlaveID & 0x80) == 0); //断言,我们要求的7位地址的值仅仅是7bit,不是通信时要求的高7位 //有些手册,给出的7位地址指的是8bit里的高7位 //有些手册,给出的7位地址指的是7bit //请自行确认,可以尝试是否通信正常来确认 i2c_Start(i2cn); //发送启动信号 i2c_write_byte(i2cn, ( SlaveID << 1 ) | MWSR); //发送从机地址和写位 i2c_write_byte(i2cn, reg); //发送从机里的寄存器地址 i2c_RepeatedStart(i2cn); //复合格式,发送重新启动信号 i2c_write_byte(i2cn, ( SlaveID << 1) | MRSW ); //发送从机地址和读位 i2c_PutinRxMode(i2cn); //进入接收模式(不应答,只接收一个字节) result = I2C_D_REG(I2CN[i2cn]); //虚假读取一次,启动接收数据 i2c_Wait(i2cn); //等待接收完成 i2c_Stop(i2cn); //发送停止信号 result = I2C_D_REG(I2CN[i2cn]); //读取数据 Pause(); //必须延时一下,否则出错 return result; }
uint8_t my_i2c_read_nbytes(I2Cn_e i2cn, uint8_t addr, uint8_t reg, int length, uint8_t * pdata) { int i = 0; uint8_t dump; i2c_Start(i2cn); if(!my_i2c_write_byte(i2cn, ( addr << 1 ) | MWSR)) { return 0; } if(!my_i2c_write_byte(i2cn, reg)) { return 0; } i2c_RepeatedStart(i2cn); if(!my_i2c_write_byte(i2cn, ( addr << 1 ) | MRSW)) { return 0; } i2c_EnterRxMode(i2cn); dump = I2C_D_REG(I2C0_BASE_PTR); if(!my_i2c_Wait(i2cn)) { return 0; } for(i = 0; i < length; i++) { if(i == length - 1) { i2c_PutinRxMode(i2cn); *(pdata + i) = I2C_D_REG(I2C0_BASE_PTR); } else { *(pdata + i) = I2C_D_REG(I2C0_BASE_PTR); } if(!my_i2c_Wait(i2cn)) { return 0; } } i2c_Stop(i2cn); return 1; }
//============================================================================ //函数名称:hw_iic_read1 //功能概要:从从机读1个字节数据 //参数说明: MoudleNum:模块号 // DeviceAddr:设备地址 // AccessAddr:访问地址 // Data:带回收到的一个字节数据 //函数返回:为0,成功读一个字节;为1,读一个字节失败 //函数说明: 内部调用 hw_send_signal,hw_wait //============================================================================ uint8 hw_iic_read1(int MoudleNum,uint8 DeviceAddr, uint8 AccessAddr, uint8 *Data) { //获取i2c模块基址 I2C_MemMapPtr num = hw_i2c_get_base_address(MoudleNum); I2C_C1_REG(num) |= 0x10; //TX = 1,MCU设置为发送模式 hw_send_signal('S',MoudleNum); //发送开始信号 I2C_D_REG(num) = DeviceAddr & 0xfe; //发送设备地址,并通知从机接收数据 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 { return 1; //没有传送成功,读一个字节失败 } if (hw_wait('A',MoudleNum)) //等待从机应答信号 { return 1; //没有等到应答信号,读一个字节失败 } I2C_D_REG(num) = AccessAddr; //发送访问地址 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 { return 1; //没有传送成功,读一个字节失败 } if (hw_wait('A',MoudleNum)) //等待从机应答信号 { return 1; //没有等到应答信号,读一个字节失败 } I2C_C1_REG(num) |= 0x04;//当MCU在主机模 式下,向该位写1将产生一个重新开始信号 I2C_D_REG(num) = DeviceAddr | 0x01; //通知从机改为发送数据 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 { return 1; //没有传送成功,读一个字节失败 } if (hw_wait('A',MoudleNum)) //等待从机应答信号 { return 1; //没有等到应答信号,读一个字节失败 } I2C_C1_REG(num) &= 0xef; //TX = 0,MCU设置为接收模式 *Data = I2C_D_REG(num); //读出IIC1D,准备接收数据 if (hw_wait('T',MoudleNum)) //等待一个字节数据传送完成 { return 1; //没有传送成功,读一个字节失败 } hw_send_signal('O',MoudleNum); //发送停止信号 *Data = I2C_D_REG(num); //读出接收到的一个数据 return 0; //正确接收到一个字节数据 }
uint8_t my_i2c_write_byte(I2Cn_e I2Cn, uint8 data) { I2C_D_REG(I2C0_BASE_PTR) = data; if(!my_i2c_Wait(I2Cn)) { return 0; } return 1; }
/************************************************************************* * 野火嵌入式开发工作室 * * 函数名称:I2C_ReadAddr * 功能说明:读取I2C设备指定地址寄存器的数据 * 参数说明:I2Cn 模块号(I2C0、I2C1) * SlaveID 7位从机地址 * Addr 从机的寄存器地址 * 函数返回:从机寄存器的数据 * 修改时间:2012-1-20 * 备 注: *************************************************************************/ u8 I2C_ReadAddr(I2Cn i2cn, u8 SlaveID, u8 Addr) { u8 result; /* Send Slave Address */ I2C_StartTransmission (i2cn, SlaveID, MWSR); i2c_Wait(i2cn); /* Write Register Address */ i2c_write_byte(i2cn, Addr); i2c_Wait(i2cn); /* Do a repeated start */ i2c_RepeatedStart(i2cn); /* Send Slave Address */ i2c_write_byte(i2cn, ( SlaveID << 1) | MRSW ); i2c_Wait(i2cn); /* Put in Rx Mode */ i2c_PutinRxMode(i2cn); /* Turn off ACK since this is second to last byte being read*/ i2c_DisableAck(i2cn); //不应答 /* Dummy read 虚假读取*/ result = I2C_D_REG(I2Cx[i2cn]); i2c_Wait(i2cn); /* Send stop since about to read last byte */ i2c_Stop(i2cn); /* Read byte */ result = I2C_D_REG(I2Cx[i2cn]); return result; }
uint8 LPLD_I2C_Read(I2Cx i2cx) { uint8 temp; temp = I2C_D_REG(I2Cx_Ptr[i2cx]); return temp; }
/* * LPLD_I2C_Write * I2C发送一个字节数据给目的地址设备 * * 参数: * i2cx--选择I2C模块号 * |__I2C0 --I2C0号模块 * |__I2C1 --I2C1号模块 * data8--要发送的字节数据 * */ void LPLD_I2C_Write(I2Cx i2cx, uint8 data8) { I2C_D_REG(I2Cx_Ptr[i2cx]) = data8; }