请问在AI8G1K08中,主频是6M时,传输I2C一直会卡着
本帖最后由 DebugLab 于 2024-11-21 13:50 编辑我使用软件I2C可以,但是查硬件I2C一直没找到问题,这里咨询一下,谢谢大家
按顺序核心代码如下:
P3PU = 0x0d; // P30(RxD),P32(SCL),P33(SDA)上拉
P3M0 = 0x0f; // 设置P30,P31(TxD)准双向,P32,P33开漏输出
P3M1 = 0x03; // 设置P30,P31(TxD)准双向,P32,P33开漏输出下面是我抄的官方库并进行函数名修改,其他什么也没动:
uint8_t i2cGetMsBusyStatus(void) {
return (I2CMSST & 0x80);
}
void i2cWait() {
while (!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}
void i2cStart() {
I2CMSCR = 0x01;// 发送START命令
i2cWait();
}
void i2cSendData(char dat) {
I2CTXD = dat; // 写数据到数据缓冲区
I2CMSCR = 0x02;// 发送SEND命令
i2cWait();
}
void i2cRecvACK() {
I2CMSCR = 0x03;// 发送读ACK命令
i2cWait();
}
char i2cRecvData() {
I2CMSCR = 0x04;// 发送RECV命令
i2cWait();
return I2CRXD;
}
void i2cSendACK() {
I2CMSST = 0x00;// 设置ACK信号
I2CMSCR = 0x05;// 发送ACK命令
i2cWait();
}
void i2cSendNAK() {
I2CMSST = 0x01;// 设置NAK信号
I2CMSCR = 0x05;// 发送ACK命令
i2cWait();
}
void i2cStop() {
I2CMSCR = 0x06;// 发送STOP命令
i2cWait();
}
void i2cSendCmdData(uint8_t cmd, uint8_t dat) {
I2CTXD = dat; // 写数据到数据缓冲区
I2CMSCR = cmd;// 设置命令
i2cWait();
}
void i2cWriteNbyte(uint8_t dev_addr, uint8_t mem_addr, uint8_t *p, uint8_t number) {
i2cStart(); // 发送起始命令
i2cSendData(dev_addr);// 发送设备地址+写命令
i2cRecvACK();
i2cSendData(mem_addr);// 发送存储地址
i2cRecvACK();
do {
i2cSendData(*p++);
i2cRecvACK();
} while (--number);
i2cStop();// 发送停止命令
}
void i2cReadNbyte(uint8_t dev_addr, uint8_t mem_addr, uint8_t *p, uint8_t number) {
i2cStart(); // 发送起始命令
i2cSendData(dev_addr);// 发送设备地址+写命令
i2cRecvACK();
i2cSendData(mem_addr);// 发送存储地址
i2cRecvACK();
i2cStart(); // 发送起始命令
i2cSendData(dev_addr | 1);// 发送设备地址+读命令
i2cRecvACK();
do {
*p = i2cRecvData();
p++;
if (number != 1) i2cSendACK();// send ACK
} while (--number);
i2cSendNAK();// send no ACK
i2cStop(); // 发送停止命令
}
之后我在初始化的基础上调用了i2cReadNbyte或i2cWriteNbyte会导致系统卡死,不知道什么原因。
EAXFR呢 我现在增加了这个寄存器,发现依然有问题:
P_SW2 |= 0x80;// 开启访问xsfr扩展寄存器
/* 配置GPIO初始化 */
P3PU = 0x0d;// P30(RxD),P32(SCL),P33(SDA)上拉
P3M0 = 0x0f;// 设置P30,P31(TxD)准双向,P32,P33开漏输出
P3M1 = 0x03;// 设置P30,P31(TxD)准双向,P32,P33开漏输出
P_SW2 |= 0x30;// I2C: I2CSCL(P3.2), I2CSDA(P3.3)
I2CCFG |= 0x40; /* 1: 设为主机 */
I2CMSST = 0x00; /* 清除I2C主机状态寄存器 */
/* 在使用6M主频时,如果该Speed设为2时,速率为375K频率,无法为400K频率 */
I2CCFG = (I2CCFG & ~0x3f) | (2 & 0x3f);
I2CMSAUX &= ~0x01;// 禁止自动发送
I2CMSCR &= ~0x80; // 关闭中断模式
I2CCFG |= 0x80; // 使能I2C功能
这样初始化依然会死机。
测试通过的程序:
DebugLab 发表于 2024-11-21 15:14
测试通过的程序:
下载时设置时钟为11.0592M,硬件I2C超频到921.6K,可按你需要修改 wsr2580 发表于 2024-11-21 14:56
我现在增加了这个寄存器,发现依然有问题:
P_SW2 |= 0x80;// 开启访问xsfr扩展寄存器
/* 配置GP ...
/ 8
邮箱 发表于 2024-11-21 15:17
/ 8
您好,我按您推荐的设置,现在不会死机了,但发现居然会影响其他GPIO的中断,感觉到很奇怪。
我把核心的代码给您看看,您参考一下:
// 开启访问xsfr扩展寄存器
P_SW2 |= 0x80;
/* 配置GPIO初始化 */
P3PU = 0x0d;// P30(RxD),P32(SCL),P33(SDA)上拉
/* 设置P30,P31(TxD)准双向,P32,P33开漏输出,其余高阻 */
P3M0 = 0x0c;// 设置P30,P31(TxD)准双向,P32,P33开漏输出
P3M1 = 0xfc;// 设置P30,P31(TxD)准双向,P32,P33开漏输出
P5PU = 0x20;// P55(KEY)上拉
P_SW2 |= 0x30;// I2C: I2CSCL(P3.2), I2CSDA(P3.3)
I2CCFG |= 0x40; /* 1: 设为主机 */
I2CMSST = 0x00; /* 清除I2C主机状态寄存器 */
/* 在使用6M主频时,如果该Speed设为8时,速率为频率;无法为400K频率 */
I2CCFG = (I2CCFG & ~0x3f) | (8 & 0x3f);
I2CMSAUX &= ~0x01;// 禁止自动发送
I2CMSCR &= ~0x80; // 关闭中断模式
I2CCFG |= 0x80; // 使能I2C功能
下面是具体的API程序:
uint8_t i2cGetMsBusyStatus(void) {
return (I2CMSST & 0x80);
}
void i2cWait() {
while (!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}
void i2cStart() {
I2CMSCR = 0x01;// 发送START命令
i2cWait();
}
void i2cSendData(char dat) {
I2CTXD = dat; // 写数据到数据缓冲区
I2CMSCR = 0x02;// 发送SEND命令
i2cWait();
}
void i2cRecvACK() {
I2CMSCR = 0x03;// 发送读ACK命令
i2cWait();
}
char i2cRecvData() {
I2CMSCR = 0x04;// 发送RECV命令
i2cWait();
return I2CRXD;
}
void i2cSendACK() {
I2CMSST = 0x00;// 设置ACK信号
I2CMSCR = 0x05;// 发送ACK命令
i2cWait();
}
void i2cSendNAK() {
I2CMSST = 0x01;// 设置NAK信号
I2CMSCR = 0x05;// 发送ACK命令
i2cWait();
}
void i2cStop() {
I2CMSCR = 0x06;// 发送STOP命令
i2cWait();
}
void i2cSendCmdData(uint8_t cmd, uint8_t dat) {
I2CTXD = dat; // 写数据到数据缓冲区
I2CMSCR = cmd;// 设置命令
i2cWait();
}
void i2cWriteNbyte(uint8_t dev_addr, uint8_t mem_addr, uint8_t *p, uint8_t number) {
i2cStart(); // 发送起始命令
i2cSendData(dev_addr);// 发送设备地址+写命令
i2cRecvACK();
i2cSendData(mem_addr);// 发送存储地址
i2cRecvACK();
do {
i2cSendData(*p++);
i2cRecvACK();
} while (--number);
i2cStop();// 发送停止命令
}
void i2cReadNbyte(uint8_t dev_addr, uint8_t mem_addr, uint8_t *p, uint8_t number) {
i2cStart(); // 发送起始命令
i2cSendData(dev_addr);// 发送设备地址+写命令
i2cRecvACK();
i2cSendData(mem_addr);// 发送存储地址
i2cRecvACK();
i2cStart(); // 发送起始命令
i2cSendData(dev_addr | 1);// 发送设备地址+读命令
i2cRecvACK();
do {
*p = i2cRecvData();
p++;
if (number != 1) i2cSendACK();// send ACK
} while (--number);
i2cSendNAK();// send no ACK
i2cStop(); // 发送停止命令
}
DebugLab 发表于 2024-11-21 15:14
测试通过的程序:
您这个使用的是中断模式,我这里是想要轮询模式,不过我先烧录您的功能试试,谢谢 wsr2580 发表于 2024-11-21 20:46
您这个使用的是中断模式,我这里是想要轮询模式,不过我先烧录您的功能试试,谢谢 ...
中断方式和查询方式的体验是差不多的。 晓飛飛 发表于 2024-11-21 21:39
中断方式和查询方式的体验是差不多的。
您这个中断方式实测修改为6M可以,但是我不知道我的查询方式为什么和您的按理是一样的,但是却有异常
页:
[1]
2