[英]Trying to understand Microchip PIC16LF15344 peripheral pin selection for I2C
我一直在查看Microchip PIC16LF15344
数据手册中的外设引脚选择,或者我读取不正确,或者文档中似乎有错误和不一致。 我想知道是否有人使用过该设备并且可以确认我的解释。
我正在尝试为PIC16LF15344
编写代码以利用I2C
接口。 我已经设法为PIC16LF1822
编写了可以正常工作的I2C
代码,但是到目前为止,我仍然无法使它在PIC16LF15344
上正常工作,并且数据表中有一些令人困惑的文档需要清除。
这是对数据表的参考。
PIC16LF15344
的pinout
说明表明,可以将I2C SDA
功能分配给RC1
或RB6
。 同样, I2C SCL
可以分配给RC0
或RB4
。 但是在Section 15.3 Bidirectional Pins
有一个注意事项,如下所示。
可以通过
PPS
重新映射I2C SCLx
和SDAx
功能。 但是,只有RB1
,RB2
,RC3
和RC4
品脱实现了I2C
和SMBus
特定的输入缓冲区(I2C
模式禁用INLVL
并设置特定于I2C
阈值)。 如果将SCLx
或SDAx
功能映射到其他某个引脚(RB1
,RB2
,RC3
或RC4
除外),则将使用通用TTL
或ST
输入缓冲区(基于INLVL
寄存器设置进行配置)。 因此,在大多数应用中,建议仅将SCLx
和SDAx
引脚功能映射到RB1
,RB2
,RC3
或RC4
引脚。
问题不仅在于注释似乎与引脚分配表中的描述冲突,而且还引用了引脚RB1
和RB2
,这些引脚未出现在引脚分配表中的任何位置,即,它们似乎不存在本PIC
。 我看到了与RB1
和RB2
类似的脚注,但在文档或表格的正文中均未记录。
当然,这肯定是一个文档错误,但是我无法在PIC16LF15324/44
数据手册上找到当前的勘误表来更正此错误。 我读对了吗?
我尝试用PPS
将SCL
和SDA
配置为引脚RC0
和RC1
,因为这是它们在PCB
,但是我仍然无法使用与PIC16LF1822
相同的软件来使I2C
工作。 EUSART TX2
和RX2
默认PPS
为RC0
和RC1
。 这是否意味着在使用SSP1CLKPPS
和SSP1DATPPS
将SCL
和SDA
分配给RC0
和RC1
之前,我需要使用TX2CKPPS
和RX2DTPPS
将EUSART
分配移动到其他位置?
我将调查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初始化代码是否正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.