# V0.1
编译通过且OLED正常显示
This commit is contained in:
273
Driver/iic.c
273
Driver/iic.c
@ -1,123 +1,206 @@
|
|||||||
#include "iic.h"
|
#include "iic.h"
|
||||||
|
|
||||||
|
|
||||||
// 延时函数(2us)
|
// 延时函数(2us)
|
||||||
void IIC_Delay(void) {
|
void
|
||||||
// 软件延时
|
IIC_Delay (void)
|
||||||
// _nop_();_nop_();_nop_();_nop_();_nop_();// 30个nop约1us@30MHz
|
{
|
||||||
// _nop_();_nop_();_nop_();..............
|
// 软件延时
|
||||||
|
// _nop_();_nop_();_nop_();_nop_();_nop_();// 30个nop约1us@30MHz
|
||||||
DelayUs(1);
|
// _nop_();_nop_();_nop_();..............
|
||||||
|
DelayUs (1);
|
||||||
}
|
}
|
||||||
void IIC_Init(void) {
|
void
|
||||||
// 配置P2.6和P2.7为开漏模式
|
IIC_Init (void)
|
||||||
P2M1 |= 0xC0; // 1100 0000
|
{
|
||||||
P2M0 |= 0xC0; // 开漏模式
|
// 配置P2.6和P2.7为开漏模式
|
||||||
SDA = 1;
|
P2M1 |= 0xC0; // 1100 0000
|
||||||
SCL = 1;
|
P2M0 |= 0xC0; // 开漏模式
|
||||||
|
SDA = 1;
|
||||||
|
SCL = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIC_Start(void) {
|
void
|
||||||
SDA = 1;
|
IIC_Start (void)
|
||||||
SCL = 1;
|
{
|
||||||
IIC_Delay();
|
SDA = 1;
|
||||||
SDA = 0;
|
SCL = 1;
|
||||||
IIC_Delay();
|
IIC_Delay ();
|
||||||
SCL = 0;
|
SDA = 0;
|
||||||
|
IIC_Delay ();
|
||||||
|
SCL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIC_Stop(void) {
|
void
|
||||||
SDA = 0;
|
IIC_Stop (void)
|
||||||
SCL = 1;
|
{
|
||||||
IIC_Delay();
|
SDA = 0;
|
||||||
SDA = 1;
|
SCL = 1;
|
||||||
IIC_Delay();
|
IIC_Delay ();
|
||||||
|
SDA = 1;
|
||||||
|
IIC_Delay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIC_SendByte(u8 dat) {
|
void
|
||||||
u8 i;
|
IIC_SendByte (u8 dat)
|
||||||
for(i=0; i<8; i++) {
|
{
|
||||||
SDA = (dat & 0x80) ? 1 : 0;
|
u8 i;
|
||||||
dat <<= 1;
|
for (i = 0; i < 8; i++)
|
||||||
IIC_Delay();
|
{
|
||||||
SCL = 1;
|
SDA = (dat & 0x80) ? 1 : 0;
|
||||||
IIC_Delay();
|
dat <<= 1;
|
||||||
SCL = 0;
|
IIC_Delay ();
|
||||||
|
SCL = 1;
|
||||||
|
IIC_Delay ();
|
||||||
|
SCL = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 IIC_RecvByte(void) {
|
u8
|
||||||
u8 i, dat = 0;
|
IIC_RecvByte (void)
|
||||||
SDA = 1; // 释放数据线
|
{
|
||||||
for(i=0; i<8; i++) {
|
u8 i, dat = 0;
|
||||||
dat <<= 1;
|
SDA = 1; // 释放数据线
|
||||||
SCL = 1;
|
for (i = 0; i < 8; i++)
|
||||||
IIC_Delay();
|
{
|
||||||
if(SDA) dat |= 0x01;
|
dat <<= 1;
|
||||||
SCL = 0;
|
SCL = 1;
|
||||||
IIC_Delay();
|
IIC_Delay ();
|
||||||
|
if (SDA)
|
||||||
|
dat |= 0x01;
|
||||||
|
SCL = 0;
|
||||||
|
IIC_Delay ();
|
||||||
}
|
}
|
||||||
return dat;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bit IIC_WaitAck(void) {
|
bit
|
||||||
SDA = 1; // 主机释放SDA
|
IIC_WaitAck (void)
|
||||||
IIC_Delay();
|
{
|
||||||
SCL = 1;
|
SDA = 1; // 主机释放SDA
|
||||||
IIC_Delay();
|
IIC_Delay ();
|
||||||
if(SDA) { // 检测SDA状态
|
SCL = 1;
|
||||||
SCL = 0;
|
IIC_Delay ();
|
||||||
return 0; // 无ACK
|
if (SDA)
|
||||||
} else {
|
{ // 检测SDA状态
|
||||||
SCL = 0;
|
SCL = 0;
|
||||||
return 1; // 收到ACK
|
return 0; // 无ACK
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCL = 0;
|
||||||
|
return 1; // 收到ACK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIC_SendAck(bit ack) {
|
void
|
||||||
SDA = ack ? 0 : 1;
|
IIC_SendAck (bit ack)
|
||||||
IIC_Delay();
|
{
|
||||||
SCL = 1;
|
SDA = ack ? 0 : 1;
|
||||||
IIC_Delay();
|
IIC_Delay ();
|
||||||
SCL = 0;
|
SCL = 1;
|
||||||
SDA = 1; // 释放SDA
|
IIC_Delay ();
|
||||||
|
SCL = 0;
|
||||||
|
SDA = 1; // 释放SDA
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I²C连续写入多个字节数据
|
* @brief I²C连续写入多个字节数据
|
||||||
* @param devAddr : 从机地址(7位地址,左对齐)
|
* @param devAddr : 从机地址(7位地址,左对齐)
|
||||||
* @param regAddr : 寄存器地址
|
* @param regAddr : 寄存器地址
|
||||||
* @param pData : 待写入数据缓冲区
|
* @param pData : 待写入数据缓冲区
|
||||||
* @param len : 数据长度
|
* @param len : 数据长度
|
||||||
* @retval 写入状态:1-成功,0-失败
|
* @retval 写入状态:1-成功,0-失败
|
||||||
*/
|
*/
|
||||||
bit IIC_WriteBytes(u8 devAddr, u8 regAddr, u8 *pData, u8 len) {
|
bit
|
||||||
IIC_Start(); // 启动I²C通信[6](@ref)
|
IIC_WriteBytes (u8 devAddr, u8 regAddr, u8 *pData, u8 len)
|
||||||
|
{
|
||||||
// 发送设备地址(写模式)
|
IIC_Start (); // 启动I²C通信[6](@ref)
|
||||||
IIC_SendByte(devAddr & 0xFE); // 7位地址+写位(0)
|
|
||||||
if (!IIC_WaitAck()) { // 检测从机应答
|
// 发送设备地址(写模式)
|
||||||
IIC_Stop();
|
IIC_SendByte (devAddr & 0xFE); // 7位地址+写位(0)
|
||||||
return 0; // 无应答则终止[2](@ref)
|
if (!IIC_WaitAck ())
|
||||||
|
{ // 检测从机应答
|
||||||
|
IIC_Stop ();
|
||||||
|
return 0; // 无应答则终止[2](@ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送寄存器地址
|
// 发送寄存器地址
|
||||||
IIC_SendByte(regAddr);
|
IIC_SendByte (regAddr);
|
||||||
if (!IIC_WaitAck()) {
|
if (!IIC_WaitAck ())
|
||||||
IIC_Stop();
|
{
|
||||||
return 0; // 寄存器地址无应答
|
IIC_Stop ();
|
||||||
|
return 0; // 寄存器地址无应答
|
||||||
}
|
}
|
||||||
|
|
||||||
// 循环发送数据字节
|
// 循环发送数据字节
|
||||||
while (len--) {
|
while (len--)
|
||||||
IIC_SendByte(*pData++); // 发送当前字节
|
{
|
||||||
if (!IIC_WaitAck()) { // 检测数据应答
|
IIC_SendByte (*pData++); // 发送当前字节
|
||||||
IIC_Stop();
|
if (!IIC_WaitAck ())
|
||||||
return 0; // 数据写入失败
|
{ // 检测数据应答
|
||||||
|
IIC_Stop ();
|
||||||
|
return 0; // 数据写入失败
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IIC_Stop(); // 结束通信[6](@ref)
|
IIC_Stop (); // 结束通信[6](@ref)
|
||||||
return 1; // 写入成功
|
return 1; // 写入成功
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I²C连续读取多个字节数据
|
||||||
|
* @param devAddr : 从机地址(7位地址,左对齐)
|
||||||
|
* @param regAddr : 寄存器地址
|
||||||
|
* @param pData : 接收数据缓冲区
|
||||||
|
* @param len : 数据长度
|
||||||
|
* @retval 读取状态:1-成功,0-失败
|
||||||
|
*/
|
||||||
|
bit
|
||||||
|
IIC_ReadBytes (u8 devAddr, u8 regAddr, u8 *pData, u8 len)
|
||||||
|
{
|
||||||
|
IIC_Start (); // 启动I²C通信
|
||||||
|
|
||||||
|
// 发送设备地址(写模式)
|
||||||
|
IIC_SendByte (devAddr & 0xFE); // 7位地址+写位(0)
|
||||||
|
if (!IIC_WaitAck ())
|
||||||
|
{ // 检测从机应答
|
||||||
|
IIC_Stop ();
|
||||||
|
return 0; // 无应答则终止
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送寄存器地址
|
||||||
|
IIC_SendByte (regAddr);
|
||||||
|
if (!IIC_WaitAck ())
|
||||||
|
{
|
||||||
|
IIC_Stop ();
|
||||||
|
return 0; // 寄存器地址无应答
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新启动I²C通信(重复启动)
|
||||||
|
IIC_Start ();
|
||||||
|
|
||||||
|
// 发送设备地址(读模式)
|
||||||
|
IIC_SendByte (devAddr | 0x01); // 7位地址+读位(1)
|
||||||
|
if (!IIC_WaitAck ())
|
||||||
|
{ // 检测从机应答
|
||||||
|
IIC_Stop ();
|
||||||
|
return 0; // 无应答则终止
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环读取数据字节
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
*pData++ = IIC_RecvByte (); // 接收当前字节
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
IIC_SendAck (1); // 发送ACK
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IIC_SendAck (0); // 发送NACK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IIC_Stop (); // 结束通信
|
||||||
|
return 1; // 读取成功
|
||||||
|
}
|
@ -21,12 +21,12 @@ void INA226_WriteReg(uint8_t reg, uint16_t value) {
|
|||||||
uint8_t data_t[2];
|
uint8_t data_t[2];
|
||||||
data_t[0] = (uint8_t)(value >> 8);
|
data_t[0] = (uint8_t)(value >> 8);
|
||||||
data_t[1] = (uint8_t)(value & 0xFF);
|
data_t[1] = (uint8_t)(value & 0xFF);
|
||||||
I2C_WriteBytes(INA226_ADDR, reg, data_t, 2); // 需适配您的I2C驱动
|
IIC_WriteBytes(INA226_ADDR, reg, data_t, 2); // 需适配您的I2C驱动
|
||||||
}
|
}
|
||||||
// 寄存器读取函数
|
// 寄存器读取函数
|
||||||
uint16_t INA226_ReadReg(uint8_t reg) {
|
uint16_t INA226_ReadReg(uint8_t reg) {
|
||||||
uint8_t data_t[2];
|
uint8_t data_t[2];
|
||||||
I2C_ReadBytes(INA226_ADDR, reg, data_t, 2); // 需适配您的I2C驱动
|
IIC_ReadBytes(INA226_ADDR, reg, data_t, 2); // 需适配您的I2C驱动
|
||||||
return (data_t[0] << 8) | data_t[1];
|
return (data_t[0] << 8) | data_t[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user