pic - Esp32 到 pic16lf18346 i2c 通信问题
问题描述
我在我的项目中使用 esp32 和 pic16lf18346。esp32 是 i2cc 主控。我从图片中看到错误的 i2c 数据。esp32 每 1 秒读取一次多字节。在 pic 主线程有 while(1) 和睡眠。仅启用 i2c isr。如果我从 pic 主线程中删除睡眠,我会得到正确的 i2c 数据。在逻辑分析仪中,我看到 i2c isr 在睡眠状态下运行,但 SDA 数据显示错误。
对此的任何指导将不胜感激。
请看mcc生成的i2c代码。指导是否有任何配置问题。
谢天谢地,Manas /** MSSP1 生成的驱动程序文件
@Company
Microchip Technology Inc.
@File Name
i2c1.c
@Summary
This is the generated header file for the MSSP1 driver using
PIC10 / PIC12 / PIC16 / PIC18 MCUs
@Description
This header file provides APIs for driver for I2C1.
Generation Information :
Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.76
Device : PIC16LF18346
Driver Version : 2.01
The generated drivers are tested against the following:
Compiler : XC8 2.00
MPLAB : MPLAB X 5.10
*/
/*
(c) 2018 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and any
derivatives exclusively with Microchip products. It is your responsibility to comply with third party
license terms applicable to your use of third party software (including open source software) that
may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY
IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS
FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP
HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO
THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL
CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT
OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS
SOFTWARE.
*/
#include "i2c1.h"
#define I2C1_SLAVE_ADDRESS 0x08
#define I2C1_SLAVE_MASK 0x7F
typedef enum
{
SLAVE_NORMAL_DATA,
SLAVE_DATA_ADDRESS,
} SLAVE_WRITE_DATA_TYPE;
/**
Section: Global Variables
*/
volatile uint8_t I2C1_slaveWriteData = 0x55;
I2C1_RegisterWriteISR_t I2C1_RegisterWriteISR;
I2C1_RegisterReadISR_t I2C1_RegisterReadISR;
/**
Section: Local Functions
*/
void I2C1_StatusCallback(I2C1_SLAVE_DRIVER_STATUS i2c_bus_state);
/**
Prototype: void I2C1_Initialize(void)
Input: none
Output: none
Description: I2C1_Initialize is an
initialization routine that takes inputs from the GUI.
Comment:
Usage: I2C1_Initialize();
*/
void I2C1_Initialize(void)
{
// initialize the hardware
// R_nW write_noTX; P stopbit_notdetected; S startbit_notdetected; BF RCinprocess_TXcomplete; SMP Standard Speed; UA dontupdate; CKE disabled; D_nA lastbyte_address;
SSP1STAT = 0x80;
// SSPEN enabled; WCOL no_collision; CKP disabled; SSPM 7 Bit Polling; SSPOV no_overflow;
SSP1CON1 = 0x26;
// ACKEN disabled; GCEN disabled; PEN disabled; ACKDT acknowledge; RSEN disabled; RCEN disabled; ACKSTAT received; SEN enabled;
SSP1CON2 = 0x01;
// ACKTIM ackseq; SBCDE disabled; BOEN disabled; SCIE disabled; PCIE disabled; DHEN disabled; SDAHT 300ns; AHEN disabled;
SSP1CON3 = 0x08;
// SSP1MSK 127;
SSP1MSK = (I2C1_SLAVE_MASK << 1); // adjust UI mask for R/nW bit
// SSP1ADD 8;
SSP1ADD = (I2C1_SLAVE_ADDRESS << 1); // adjust UI address for R/nW bit
// clear the slave interrupt flag
PIR1bits.SSP1IF = 0;
// enable the master interrupt
PIE1bits.SSP1IE = 1;
}
void I2C1_ISR ( void )
{
int readerr = 0;
uint8_t i2c_data = 0x55;
// NOTE: The slave driver will always acknowledge
// any address match.
PIR1bits.SSP1IF = 0; // clear the slave interrupt flag
i2c_data = SSP1BUF; // read SSPBUF to clear BF
if(1 == SSP1STATbits.R_nW)
{
if((1 == SSP1STATbits.D_nA) && (1 == SSP1CON2bits.ACKSTAT))
{
// callback routine can perform any post-read processing
I2C1_StatusCallback(I2C1_SLAVE_READ_COMPLETED);
}
else
{
// callback routine should write data into SSPBUF
I2C1_StatusCallback(I2C1_SLAVE_READ_REQUEST);
}
}
else if(0 == SSP1STATbits.D_nA)
{
// this is an I2C address
// callback routine should prepare to receive data from the master
I2C1_StatusCallback(I2C1_SLAVE_WRITE_REQUEST);
}
else
{
I2C1_slaveWriteData = i2c_data;
// callback routine should process I2C1_slaveWriteData from the master
I2C1_StatusCallback(I2C1_SLAVE_WRITE_COMPLETED);
}
SSP1CON1bits.CKP = 1; // release SCL
} // end I2C1_ISR()
void I2C1_SetRegisterCallbackFunctions(I2C1_RegisterWriteISR_t write,
I2C1_RegisterReadISR_t read) {
I2C1_RegisterWriteISR = write;
I2C1_RegisterReadISR = read;
}
/**
Custom implementation of the callback
This slave driver emulates an command-driven Device.
Reads can be performed by writing a single byte as a command address
followed by 1 read.
Writes can be performed by writing a single byte address, followed by 1 data
write.
*/
void I2C1_StatusCallback(I2C1_SLAVE_DRIVER_STATUS i2c_bus_state)
{
static uint8_t registerAddress = 0;
static uint8_t slaveWriteType = SLAVE_NORMAL_DATA;
switch (i2c_bus_state)
{
case I2C1_SLAVE_WRITE_REQUEST:
// the master will be sending the eeprom address next
slaveWriteType = SLAVE_DATA_ADDRESS;
break;
case I2C1_SLAVE_WRITE_COMPLETED:
switch(slaveWriteType)
{
case SLAVE_DATA_ADDRESS:
registerAddress = I2C1_slaveWriteData;
break;
case SLAVE_NORMAL_DATA:
// the master has written data to store in the eeprom
if (I2C1_RegisterWriteISR) {
I2C1_RegisterWriteISR(registerAddress, I2C1_slaveWriteData);
}
break;
default:
break;
} // end switch(slaveWriteType)
slaveWriteType = SLAVE_NORMAL_DATA;
break;
case I2C1_SLAVE_READ_REQUEST:
if (I2C1_RegisterReadISR) {
SSP1BUF = I2C1_RegisterReadISR(registerAddress);
}
break;
case I2C1_SLAVE_READ_COMPLETED:
if (I2C1_RegisterReadISR) {
I2C1_RegisterReadISR(-1); //indicate no more calls for this address
}
break;
default:
break;
} // end switch(i2c_bus_state)
}
解决方案
每个都有备用 GPIO 吗?在 GPIO 下降到低电平时唤醒 PIC,PIC 在您的 while() 中进行监控,并且在线路恢复为高电平之前不会重新进入睡眠状态。在进行 I2C 读取之前,您可以稍作延迟...
推荐阅读
- php - PHP错误,无法将图像插入数据库
- lucene - 未分析字段的短语查询不起作用
- tensorflow - 如何在 jupyter notebook 中多次拟合/运行神经网络?
- android - 将 OnActivityResult 数据从电容器传回混合应用程序
- php - Laravel - 为多种目的处理刀片的标准方法
- python - 如何让这个终端命令从 python 执行?
- micronaut - Micronaut 不是 Failfast
- zend-framework2 - 单元测试时类型错误异常(zend-test,PHPUnit)
- https - 如何通过 https 访问本地主机?
- html - Angularjs - 如何用动画慢慢折叠和展开手风琴