我正在做一个涉及通过 I2C 进行上述 PIC 和 ESP32S3 通信的项目,当 PIC 是主机时,ESP 是从机。我已经完成了 master write 场景,它没有问题。但现在我想做一个主读,问题是在从发送一个数据字节后,PIC 不会发送任何 ACK/NACK 位。我的朋友正在为 ESP32 编写代码,他编写了一个测试代码,将准确的数据字节放入我们在逻辑分析仪中看到的 I2C 缓冲区,而且 ESP32 在其地址后发送正确的 ACK 位,因此不太可能有任何ESP32 的问题。然而,测试代码旨在测试 PIC32 从 ESP32 读取一个数据字节,因此 PIC 应在 ESP 发送最后一个数据位后发送 NACK。正如您在逻辑分析仪中看到的那样,没有 NACK 位,也没有第 9 个 SCL 脉冲,即使我已经设置了 I2CCON 寄存器的相应 ACKDT 和 ACKEN 位。接线正确,5.1k 上拉,100kbits(但问题必须在软件中......)任何观察?
(无法上传逻辑分析仪图表,当我尝试上传时,我只得到一行文本,如何解决?)
////////////////////////////////////////
//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"
#include "liquid_crystal_display.h"
#include "pulse_width_modulation.h"
#include "timer.h"
#include "state_change_interrupts.h"
#include "analog_to_digital_conversion.h"
#define ESP32_WRITE (0B01100000)
#define ESP32_READ (0B01100001)
uint8_t test = 0;
int main(void) {
Inter_Integrated_Circuit_Setup ();
Inter_Integrated_Circuit_Enable ();
delay_ms(400);
Inter_Integrated_Circuit_Start();
Inter_Integrated_Circuit_Write(ESP32_READ);
test = Inter_Integrated_Circuit_Read(1);
Inter_Integrated_Circuit_Stop();
while (true){
}
return (EXIT_FAILURE);
}
////////////////////////////////////////
//inter_integrated_circuit_protocol.c
////////////////////////////////////////
#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);
I2C1TRN = I2C_data;
while(I2C1STATbits.TRSTAT != 0);
if(I2C1STATbits.ACKSTAT == 0){
}
else delay_ms(1000);
}
uint8_t Inter_Integrated_Circuit_Read (uint8_t LastRead){
uint32_t I2C_raw_data = 0;
uint8_t I2C_data = 0;
Inter_Integrated_Circuit_State ();
I2C1CONbits.RCEN = 0b1;
while(I2C1STATbits.RBF != 0);
I2C_raw_data = I2C1RCV;
I2C_data = (I2C_raw_data & 0x000000FF);
if(LastRead){
I2C1CONbits.ACKDT = 0b1; //Set NACK for acknowledge sequence
I2C1CONbits.ACKEN = 0b1; //Initiate acknowledge sequence
}
else {
I2C1CONbits.ACKDT = 0b0; //Set ACK for acknowledge sequence
I2C1CONbits.ACKEN = 0b1; //Initiate acknowledge sequence
}
return (I2C_data);
}