我一直在查看有关外设引脚选择的 Microchip PIC16LF15344
数据表,要么我读错了它,要么它在文档中似乎有错误和不一致。我想知道是否有其他人使用过此设备并可以确认我的解释。
我正在尝试为 PIC16LF15344
编写代码以使用 I2C
接口(interface)。我已经设法为一个工作正常的 PIC16LF1822
编写了 I2C
代码,但到目前为止我无法让它在 PIC16LF15344
上工作,数据表中有一些令人困惑的文档,我想清理一下。
这里是对 datasheet 的引用.
PIC16LF15344
的pinout
说明表明I2C SDA
功能可以分配给RC1
或RB6
。同样,I2C SCL
可以分配给RC0
或RB4
。但是在Section 15.3 Bidirectional Pins
中有注释如下。
The
I2C SCLx
andSDAx
functions can be remapped throughPPS
. However, only theRB1
,RB2
,RC3
, andRC4
pints have theI2C
andSMBus
specific input buffers implemented (I2C
mode disablesINLVL
and sets thresholds that are specific forI2C
). If theSCLx
orSDAx
functions are mapped to some other pin (other thanRB1
,RB2
,RC3
, orRC4
), the general purposeTTL
orST
input buffers (as configured based onINLVL
register setting) will be used instead. In most applications, it is therefore recommended only to map theSCLx
andSDAx
pin functions to theRB1
,RB2
,RC3
orRC4
pins.
问题不仅是注释似乎与管脚分配表中的描述冲突,它还引用了管脚 RB1
和 RB2
,但它们并没有出现管脚分配表中的任何位置,即对于此 PIC
,它们似乎不存在。我看到了对 RB1
和 RB2
的类似脚注引用,但它们没有记录在文档正文或表格中的任何位置。
当然,这一定是文档错误,但我在 PIC16LF15324/44
数据表上找不到当前勘误表来更正此问题。我没看错吗?
我已尝试使用 PPS
配置 SCL
和 SDA
以固定 RC0
和 RC1
,因为这就是它们在我的 PCB
上的接线方式,但我无法让 I2C
使用与我用于 PIC16LF1822
。 EUSART TX2
和 RX2
的 PPS
默认值是 RC0
和 RC1
。这是否意味着在使用 SSP1CLKPPS
和 之前,我需要使用
将TX2CKPPS
和 RX2DTPPS
将 EUSART
赋值移动到别处>SSP1DATPPSSCL
和SDA
分配给RC0
和RC1
?
我将调查我的 PCB
的其他潜在问题,但我想在提交另一个 PCB
用于晶圆厂之前解决这个问题。无论如何我需要做一些改变,所以我可能只是将 SCL
和 SDA
连接到它们在下一个版本中的 PPS
默认值,然后再试一次。
初始化代码如下:
OSCFRQbits.HFFRQ = 0b011; // Set internal HF oscillator frequency to 8 MHz
WPUA = 0b00111111; // Enable all weak pull-up resistors on port A
WPUB = 0b11110000; // Enable all weak pull-up resistors on port B
WPUC = 0b11111100; // Enable all weak pull-up resistors on port C except
// RC0 and RC1 to be used as I2C SCL and SDA
TRISA = 0b00110000; // Set RA4 and RA5 as inputs
ANSELA = 0b00110000; // Set RA4 and RA5 to analog
TRISB = 0b00110000; // Set RB6 and RB7 as inputs
ANSELB = 0b11000000; // Set RB6 and RB7 as analog
TRISC = 0b11111011; // Set RC0, RC1, RC3, RC4, RC5, RC6, and RC7 as inputs
ANSELC = 0b11111000; // Set RC3, RC4, RC5, RC6, and RC7 as analog
TX2CKPPS = 0b01100; // Use RB4 for TX2
RX2DTPPS = 0b01110; // Use RB6 for RX2
SSP1CLKPPS = 0b10000; // Use RC0 as SCL
SSP1DATPPS = 0b10001; // Use RC1 as SDA
SSP1CON1 = 0b00100110; // SSPEN enabled, WCOL no collision, SSPOV no overflow,
// CKP low hold, SSPM I2C slave 7-bit
SSP1CON2 = 0b00000000; // ACKSTAT received, RCEN disabled, RSEN disabled,
// ACKEN disabled, ACKDT acknowledge, SEN disabled,
// GCEN disabled, PEN disabled
SSP1CON3 = 0b00000000; // BOEN disabled, AHEN disabled, SBCDE disabled,
// SDAHT 100 ns hold, ACKTIM ackseq, DHEN disabled,
// PCIE disabled, SCIE disabled
SSP1STAT = 0x00;
SSP1BUF = 0x00;
SSP1MSK = 0xff;
SSP1ADD = I2C_SLAVE_ADDR << 1;
PIR3bits.SSP1IF = 0; // Clear the SSP Interrupt flag
PIE3bits.SSP1IE = 1; // Enable SSP Interrupts
INTCONbits.GIE = 1; // Enable global interrupts
INTCONbits.PEIE = 1; // Enable peripheral interrupts
最佳答案
您可能有几个问题需要处理。
所有默认的 I2C
引脚也都具有模拟功能。确保与 I2C
引脚关联的 ANSB
或 ANSC
位设置为数字操作。
虽然上电复位为 I2C
输入引脚分配选择数据表默认值,但默认情况下 I2C
输出未分配给任何 GPIO
别针。您需要将 SCL
和 SDA
的 I2C
输出放置在正确的 PPS
映射寄存器中。
请注意,无论 I2C
是主设备还是从设备,输入和输出功能都应映射到同一引脚。
这将有助于编辑您的问题并发布您用于初始化 I2C
引脚和 PPS
映射寄存器的代码。
/*
* File: main.c
* PIC16LF15354
* +-------------:_:-------------+
* 10K Pull-Up -> 1 : RE3/MCLR ANB7/RX2/PGD/RB7 : 28 <>
* <> 2 : RA0/ANA0 ANB6/TX2/PGC/RB6 : 27 <> RX2
* <> 3 : RA1/ANA1 ANB5/RB5 : 26 <>
* <> 4 : RA2/ANA2 ANB4/RB4 : 25 <> TX2
* <> 5 : RA3/ANA3 ANB3/RB3 : 24 <>
* <> 6 : RA4/ANA4 ANB2/SDA2/RB2 : 23 <>
* <> 7 : RA5/ANA5 ANB1/SCL2/RB1 : 22 <>
* GND -> 8 : VSS ANB0/RB0 : 21 <>
* <> 9 : RA7/OSC1/ANA7 VDD : 20 <- 3v3
* <> 10 : RA6/OSC2/ANA6 VSS : 19 <- GND
* SCL1 <> 11 : RC0/ANC0 ANC7/RX1/RC7 : 18 <>
* SDA1 <> 12 : RC1/ANC1 ANC6/TX1/RC6 : 17 <>
* <> 13 : RC2/ANC2 ANC5/RC5 : 16 <>
* <> 14 : RC3/SCL1/ANC3 ANC4/SDA1/RC4 : 15 <>
* +-----------------------------:
* DIP-28
*
* Created on January 4, 2019, 6:20 PM
*/
// PIC16LF15354 Configuration Bit Settings
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = SWDTEN // WDT operating mode (WDT enabled/disabled by SWDTEN bit in WDTCON0)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
#pragma config BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)
#pragma config CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)
#include <xc.h>
#define I2C_SLAVE_ADDR 0x00
void main(void)
{
WPUA = 0b00111111; // Enable all weak pull-up resistors on port A
WPUB = 0b11110000; // Enable all weak pull-up resistors on port B
WPUC = 0b11111100; // Enable all weak pull-up resistors on port C except
// RC0 and RC1 to be used as I2C SCL and SDA
TRISA = 0b00110000; // Set RA4 and RA5 as inputs
ANSELA = 0b00110000; // Set RA4 and RA5 to analog
TRISB = 0b00110000; // Set RB6 and RB7 as inputs
ANSELB = 0b11000000; // Set RB6 and RB7 as analog
TRISC = 0b11111011; // Set RC0, RC1, RC3, RC4, RC5, RC6, and RC7 as inputs
ANSELC = 0b11111000; // Set RC3, RC4, RC5, RC6, and RC7 as analog
#ifdef WRONG_WAY_TO_DO_PPS
TX2CKPPS = 0b01100; // Use RB4 for TX2
RX2DTPPS = 0b01110; // Use RB6 for RX2
SSP1CLKPPS = 0b10000; // Use RC0 as SCL
SSP1DATPPS = 0b10001; // Use RC1 as SDA
#else
RB4PPS = 0x11; // Assign TX2 output to RB4
RX2DTPPS = 0x0E; // Assign RB6 to RX2 input
RC0PPS = 0x15; // Assign SCL1 output to RC0
SSP1CLKPPS = 0x10; // Assign RC0 to SCL1 input
RC1PPS = 0x16; // Assign SDA1 output to RC1
SSP1DATPPS = 0x11; // Assign RC1 to SDA1 input
#endif
SSP1CON1 = 0b00100110; // SSPEN enabled, WCOL no collision, SSPOV no overflow,
// CKP low hold, SSPM I2C slave 7-bit
SSP1CON2 = 0b00000000; // ACKSTAT received, RCEN disabled, RSEN disabled,
// ACKEN disabled, ACKDT acknowledge, SEN disabled,
// GCEN disabled, PEN disabled
SSP1CON3 = 0b00000000; // BOEN disabled, AHEN disabled, SBCDE disabled,
// SDAHT 100 ns hold, ACKTIM ackseq, DHEN disabled,
// PCIE disabled, SCIE disabled
SSP1STAT = 0x00;
SSP1BUF = 0x00;
SSP1MSK = 0xff;
SSP1ADD = I2C_SLAVE_ADDR << 1;
PIR3bits.SSP1IF = 0; // Clear the SSP Interrupt flag
PIE3bits.SSP1IE = 1; // Enable SSP Interrupts
INTCONbits.GIE = 1; // Enable global interrupts
INTCONbits.PEIE = 1; // Enable peripheral interrupts
/*
* Embedded code never returns from main
*/
for(;;)
{
}
}
PPS 设置正确,但我不知道 I2C 初始化代码是否正确。
关于c - 试图了解 Microchip PIC16LF15344 I2C 外围引脚选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54015997/