STC作为主机轮询扫描I2C设备,确认ICN6211工作状态。

This commit is contained in:
2026-04-10 19:42:22 +08:00
commit 5953218598
19 changed files with 6783 additions and 0 deletions

238
I2CM_refer/main.c Normal file
View File

@ -0,0 +1,238 @@
#include "reg51.h"
#include "intrins.h"
// 定义I2C相关寄存器
sfr P_SW2 = 0xba;
#define I2CCFG (*(unsigned char volatile xdata *)0xfe80)
#define I2CMSCR (*(unsigned char volatile xdata *)0xfe81)
#define I2CMSST (*(unsigned char volatile xdata *)0xfe82)
#define I2CSLCR (*(unsigned char volatile xdata *)0xfe83)
#define I2CSLST (*(unsigned char volatile xdata *)0xfe84)
#define I2CSLADR (*(unsigned char volatile xdata *)0xfe85)
#define I2CTXD (*(unsigned char volatile xdata *)0xfe86)
#define I2CRXD (*(unsigned char volatile xdata *)0xfe87)
// 定义端口模式寄存器
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
// 定义I2C引脚
sbit SDA = P1^4;
sbit SCL = P1^5;
// 定义LED引脚
sbit LED = P1^2;
// 全局变量
bit busy; // I2C忙碌标志
/**
* @brief I2C中断服务函数
* @note 中断号24用于处理I2C通信完成事件
*/
void I2C_Isr() interrupt 24
{
_push_(P_SW2);
P_SW2 |= 0x80; // 访问扩展寄存器
if (I2CMSST & 0x40) // 检查中断标志
{
I2CMSST &= ~0x40; // 清除中断标志
busy = 0; // 清除忙碌标志
}
_pop_(P_SW2);
}
/**
* @brief 等待I2C操作完成
*/
void I2C_Wait()
{
while(!(I2CMSST & 0x40));
I2CMSST &= ~0x40; // 清除中断标志
}
/**
* @brief 发送I2C起始信号
*/
void I2C_Start()
{
busy = 1;
I2CMSCR = 0x81; // 发送START命令
while (busy); // 等待操作完成
}
/**
* @brief 发送I2C数据
* @param dat 要发送的数据
*/
void I2C_SendData(unsigned char dat)
{
I2CTXD = dat; // 写数据到数据缓冲区
busy = 1;
I2CMSCR = 0x82; // 发送SEND命令
while (busy); // 等待操作完成
}
/**
* @brief 接收I2C应答信号
*/
void I2C_RecvACK()
{
busy = 1;
I2CMSCR = 0x83; // 发送读ACK命令
while (busy); // 等待操作完成
}
char I2C_RecvData()
{
busy = 1;
I2CMSCR = 0x84; // 发送读数据命令
while (busy); // 等待操作完成
return I2CRXD; // 返回接收数据
}
void I2C_SendACK()
{
I2CMSST = 0x00; //设置ACK信号
I2CMSCR = 0x05; // 发送ACK命令
I2C_Wait(); // 等待操作完成
}
void I2C_SendNAK()
{
I2CMSST = 0x01; //设置NACK信号
I2CMSCR = 0x05; // 发送NACK命令
I2C_Wait(); // 等待操作完成
}
/**
* @brief 发送I2C停止信号
*/
void I2C_Stop()
{
I2CMSCR = 0x06; // 发送STOP命令
I2C_Wait(); // 等待操作完成
}
// /**
// * @brief 延时函数
// * @param ms 延时毫秒数
// */
// void Delay_ms(unsigned int ms) //@24.000MHz
// {
// unsigned int i, j;
// for (i = 0; i < ms; i++)
// {
// for (j = 0; j < 3500; j++);
// }
// }
// void Delay10us(void) //@24.000MHz
// {
// unsigned char data i;
// i = 78;
// while (--i);
// }
/**
* @brief 延时函数
* @param ms 延时毫秒数
*/
void Delay_ms(unsigned int ms) //@11.0592MHz
{
unsigned int i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 1550; j++);
}
}
void Delay10us(void) //@11.0592MHz
{
unsigned char data i;
i = 35;
while (--i);
}
/**
* @brief I2C初始化函数
* @note 配置P1.4为SDAP1.5为SCL设置100k通信速率
*/
void I2C_Init()
{
// 配置端口模式
P1M0 = 0x04; // P1.2设置为推挽输出P1.4和P1.5保持准双向口
P1M1 = 0x00;
// 访问扩展寄存器
P_SW2 = 0x80;
// 配置I2C通信速率为50kHz
// 系统时钟11.059MHz
// MSSPEED = (1105900/100000/2 -4)/2 = 25
I2CCFG = 0xe0 | 0x10; // 0xe0使能I2C主机模式0x10设置MSSPEED=25
// 初始化I2C状态
I2CMSST = 0x00;
// 启用全局中断·
EA = 1;
}
/**
* @brief 向指定设备的指定寄存器发送I2C数据
* @param devAddr 设备地址
* @param regAddr 寄存器地址
* @param dat 要发送的数据
*/
void I2C_SendToRegister(unsigned char devAddr, unsigned char regAddr, unsigned char dat)
{
I2C_Start(); // 发送起始信号
I2C_SendData(devAddr); // 发送设备地址+写命令
I2C_RecvACK(); // 接收应答
I2C_SendData(regAddr); // 发送寄存器地址
I2C_RecvACK(); // 接收应答
I2C_SendData(dat); // 发送数据
I2C_RecvACK(); // 接收应答
I2C_Stop(); // 发送停止信号
}
/**
* @brief 主函数
*/
void main()
{
// 初始化数据变量用于0x96寄存器的数据递增
unsigned char reg96_data = 0;
// 初始化I2C
I2C_Init();
// 点亮LED保持常亮
LED = 0; // 推挽输出低电平点亮LED
// 主循环
while (1)
{
// 向设备0x8A的三个不同寄存器发送数据
// 发送到寄存器0x94数据0x03
I2C_SendToRegister(0x8A, 0x94, 0x03);
Delay10us(); // 延时10us
// 发送到寄存器0x95数据0x17
I2C_SendToRegister(0x8A, 0x95, 0x17);
Delay10us(); // 延时10us
// 发送到寄存器0x96数据递增
I2C_SendToRegister(0x8A, 0x96, reg96_data);
// 数据递增5达到255后重置为0
reg96_data += 5;
if (reg96_data > 0xFF)
{
reg96_data = 0;
}
Delay_ms(1000); // 延时1秒
}
}