为何PIC32与ESP32S3进行I2C通信时无法获取ACK位?
PIC32MK与ESP32S3 I2C通信ACK问题排查
我正在开发一个项目,使用PIC32MK1024MCM064作为I2C主机,与ESP32S3从机和PCF8574 IO扩展器(驱动16x2 LCD)通信。目前PIC32与PCF8574通信完全正常,LCD工作完美,但和ESP32S3通信时遇到ACK位问题——推测是PIC32未释放SDA线,导致ESP32S3无法拉低SDA发送ACK。
已确认的信息:
- 使用5.1k上拉电阻
- I2C速率为标准100Kbit/s,实际测得95-97Kbit/s,在可接受范围内
- 接线和设备地址均正确
- ESP32S3从机代码在两台ESP32S3(主从模式)测试时能正常收到带ACK的数据包
现在不同MCU间通信无法获取ACK,怀疑是配置问题(比如时钟匹配或其他未知参数),求排查建议。
主程序代码(main.c)
#include <xc.h> #include "configurations_bits.h" #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <stdlib.h> #include "stdio.h" #include <sys/attribs.h> #include "delay.h" #include "inter_integrated_circuit_protocol.h" #define ESP32 (0B1100000) //Write address #define LCD (0B1000000) //Write address uint8_t Number = 0x71; //Random value int main(void) { ANSELA = 0x00000000; ANSELB = 0x00000000; ANSELC = 0x00000000; ANSELE = 0x00000000; ANSELG = 0x00000000; TRISCbits.TRISC11 = 0b1; //RC11 PIN_24 ADC pin for battery TRISAbits.TRISA1 = 0b1; //RA1 PIN_14 Particle detection TRISCbits.TRISC7 = 0b1; //RC7 PIN_51 First GUI button TRISCbits.TRISC8 = 0b1; //RC8 PIN_52 Second GUI button TRISEbits.TRISE15 = 0b1; //RE15 PIN_30 Third GUI button TRISEbits.TRISE14 = 0b1; //RE14 PIN_29 Fourth GUI button TRISDbits.TRISD5 = 0b1; //RD5 PIN_53 Encoder channel A TRISDbits.TRISD6 = 0b1; //RD5 PIN_54 Encoder channel B TRISGbits.TRISG6 = 0b1; //RG6 PIN_4 ESP32 -> PIC32 communication TRISAbits.TRISA11 = 0b1; //RA11 PIN_12 ESP32 -> PIC32 communication TRISAbits.TRISA12 = 0b1; //RA12 PIN_11 ESP32 -> PIC32 communication TRISAbits.TRISA0 = 0b1; //RA0 PIN_13 UART RX Inter_Integrated_Circuit_Setup (); Inter_Integrated_Circuit_Enable (); //First I2C operation writing something to PCF8574 IO expander (I am getting ACK) Inter_Integrated_Circuit_Start(); Inter_Integrated_Circuit_Write(LCD); Inter_Integrated_Circuit_Write(Number); Inter_Integrated_Circuit_Stop(); //Second I2C operation writing something to ESP32S3 (I am getting NACK) Inter_Integrated_Circuit_Start(); Inter_Integrated_Circuit_Write(ESP32); Inter_Integrated_Circuit_Write(Number); Inter_Integrated_Circuit_Stop(); while (true){ } return (EXIT_FAILURE);}
I2C头文件(inter_integrated_circuit_protocol.h)
//************************************************************************** // INTER INTEGRATED CIRCUIT PROTOCOL HEADER FILE //************************************************************************** void Inter_Integrated_Circuit_Setup (void); void Inter_Integrated_Circuit_Enable (void); void Inter_Integrated_Circuit_Disable (void); void Inter_Integrated_Circuit_State (void); void Inter_Integrated_Circuit_Start (void); void Inter_Integrated_Circuit_Stop (void); void Inter_Integrated_Circuit_Repeated_Start (void); void Inter_Integrated_Circuit_Write (uint8_t I2C_data); uint8_t Inter_Integrated_Circuit_Read (void);
I2C源文件(inter_integrated_circuit_protocol.c)
//************************************************************************** // INTER INTEGRATED CIRCUIT PROTOCOL SOURCE FILE //************************************************************************** #include <xc.h> #include <stdint.h> #include "inter_integrated_circuit_protocol.h" #include "delay.h" void Inter_Integrated_Circuit_Setup (void){ I2C1BRG = 0xEC; I2C1CON = 0x00000000; I2C1CONbits.SDAHT = 0b0; I2C1CONbits.SIDL = 0b0; I2C1CONbits.SCLREL = 0b1; I2C1CONbits.STREN = 0b0; I2C1CONbits.DISSLW = 0b1; I2C1CONbits.SMEN = 0b0; } void Inter_Integrated_Circuit_Enable (void){ I2C1CONbits.ON = 0b1; } void Inter_Integrated_Circuit_Disable (void){ I2C1CONbits.ON = 0b0; } void Inter_Integrated_Circuit_State (void){ while( (I2C1CON & 0x0000001F) || (I2C1STAT & 0x00000004) ); } void Inter_Integrated_Circuit_Start (void){ Inter_Integrated_Circuit_State (); I2C1CONbits.SEN = 0b1; } void Inter_Integrated_Circuit_Stop (void){ Inter_Integrated_Circuit_State (); I2C1CONbits.PEN = 0b1; } void Inter_Integrated_Circuit_Repeated_Start (void){ Inter_Integrated_Circuit_State (); I2C1CONbits.RSEN = 0b1; } void Inter_Integrated_Circuit_Write (uint8_t I2C_data){ Inter_Integrated_Circuit_State (); while(I2C1STATbits.TBF != 0); while(I2C1STATbits.TRSTAT != 0); I2C1TRN = I2C_data; } uint8_t Inter_Integrated_Circuit_Read (void){ uint8_t I2C_data = 0; Inter_Integrated_Circuit_State (); I2C1CONbits.RCEN = 0b1; while(I2C1STATbits.RBF != 0); I2C_data = (I2C1RCV & 0x000000FF); I2C1CONbits.ACKEN = 0b1; return (I2C_data); }
内容的提问来源于stack exchange,提问作者Vilius Žalėnas
相关产品推荐
相关产品推荐

