编译通过且OLED正常显示
This commit is contained in:
jxh
2025-03-18 22:14:15 +08:00
parent 17afca8f17
commit 65614ace50
2 changed files with 180 additions and 97 deletions

View File

@ -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; // 读取成功
}

View File

@ -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];
} }