1

我最近在一家新公司开始工作,在那里进行 PIC32 编程的程序员现在已经不在了,我确实需要对他的 uC 代码进行故障排除。

他不喜欢 Microchip Harmony 配置器/框架,因此他只使用 Harmony 框架的外设库进行编码(这意味着他在代码中使用了很多 PLIB_* 函数,取自示例)。为此,他从 framework/system/devcon/src 中提取了 sys_devcon.c 和 sys_devcon.h 文件,并将该文件复制到项目的源代码中。

现在我的问题:下面你会看到 device.cfg。引脚 OSC1 和 OSC2 连接到主振荡器 (4MHz)。我们已经通过 LeCroy Teledyne(显示为 4MHz)对其进行测试,确认振荡器工作正常。通过文件给出的配置,系统时钟 (SYSCLK) 由 SYSPLL 派生。由于我的 IDIV 为 1,我的 MULT 为 18,而我的 ODIV 为 1,我希望 SYSCLK 以 72MHz (4/1*18/1=72) 运行。PBDIV 设置为 DIV_2(因此 PBCLK=SYSCLK/2 -> 36MHz)。REFCLK 预计以 6.4MHz 运行。

但是: 测量的 PBCLK 显示 18MHz,测量的 REFCLK(SYSPLL 作为 F_REFIN,显示 3.2MHz,这意味着 SYSCLK 仅运行 36MHz(不是预期的 72MHz)。但考虑到配置,一切都应该运行两倍快。我无法找到为什么 SYSCLK 以半速运行的问题。

我对代码中的每个 PLIB_OSC*(包括 PLIB_OSC_SLEW*)函数进行了故障排除,但没有发现一个问题(仅 5 行就可以使用某种 PLIB_OSC* 函数)。也许有人有一些想法/提示来解决问题。也不清楚 SYSCLK 是否实际上减半,或者 SYSPLL 之后是否有一些分频器(在 REFCLK 和 PBCLK 之间)。有什么方法可以测量 SYSCLK 吗?

uC:PIC32MX174F256B XC 版本:V2.10 Harmony:V2.05.01(仅使用 PLIB) MPLAB X IDE:v4.20

#ifndef PIC32MX174F256B_CONFIG_HEADER

#define PIC32MX174F256B_CONFIG_HEADER


#ifdef __cplusplus
extern "C" {
#endif

/* PIC32MX174F256B Configuration Bit Settings */


// DEVCFG3
// USERID = No Setting

// Alternate I/O Select for I2C1 (I2C1 uses the SDA1/SCL1 pins)
#pragma config AI2C1 = OFF

// Alternate I/O Select for I2C2 (I2C2 uses the SDA2/SCL2 pins)  
#pragma config AI2C2 = OFF              
#pragma config PMDL1WAY = OFF            // Peripheral Module Enable Configuration
#pragma config IOL1WAY = OFF             // Peripheral Pin Select Configuration (Allow reconfigurations)

// DEVCFG2
#pragma config FPLLIDIV = DIV_1         // PLL Input Divider (1x Divider)
#pragma config FPLLMUL = MUL_18         // PLL Multiplier (18x Multiplier)
#pragma config FPLLICLK = PLL_POSC      // System PLL Input Clock Selection (POSC is input to the System PLL)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)
#pragma config BOREN = ON               // Brown-Out Reset (BOR) Enable (Enable BOR)
#pragma config DSBOREN = ON             // Deep Sleep BOR Enable (Enable ZPBOR during Deep Sleep Mode)
#pragma config DSWDTPS = DSPS7         // Deep Sleep Watchdog Timer Postscaler (1:2^11)
#pragma config DSWDTOSC = LPRC          // Deep Sleep WDT Reference Clock Selection (Select LPRC as
                                        // DSWDT Reference clock)
#pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer Enable (Disable DSWDT during
                                        // Deep Sleep Mode)
#pragma config FDSEN = ON               // Deep Sleep Enable (Enable DSEN bit in DSCON)

// DEVCFG1
#pragma config FNOSC = SPLL             // Oscillator Selection Bits (Primary Osc (HS,EC, XT))
#pragma config FSOSCEN = OFF            // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT             // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)

// value can also be adjusted in module sys_system from libpic32mx174f256b
#pragma config FPBDIV = DIV_2           // Peripheral Clock Divisor

#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch
                                        // Disable, FSCM Disabled)
#pragma config WDTPS = PS1              // Watchdog Timer Postscaler (1:1)
#pragma config WDTSPGM = ON             // Watchdog Timer Stop During Flash Programming (Watchdog
                                        // Timer stops during Flash programming)
#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25     // Watchdog Timer Window Size (Window Size is 25%)

// DEVCFG0
#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config SMCLR = MCLR_NORM        // Soft Master Clear Enable (MCLR pin generates a normal system Reset)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
4

2 回答 2

0

我可能发现了问题:设备数据表指出:0-72 MHz 操作需要“3”个等待状态

但是,sys_devcon.c 只定义了 0-2 个等待状态。但不仅如此,它实际上不会定义等待状态,因为 #if defined(PLIB_PCACHE_ExistsWaitState) 没有定义。

 #if defined(PLIB_PCACHE_ExistsWaitState)
if (PLIB_PCACHE_ExistsWaitState(PCACHE_ID_0))
{
    int ws; /* number of wait states */
    if (sysclk <= 30000000)
        ws = 0;
    else if (sysclk <= 60000000)
        ws = 1;
    else
        ws = 2;

    /* Interrupts must be disabled when changing wait states */
    int_flag = (bool)(PLIB_INT_GetStateAndDisable( INT_ID_0 ) & 0x01);

    PLIB_PCACHE_WaitStateSet(PCACHE_ID_0, ws);

    if (int_flag)
    {
        PLIB_INT_Enable(INT_ID_0);
        int_flag = false;
    }
}
#endif // defined(PLIB_PCACHE_ExistsWaitState)

但是, #if defined(PLIB_PCACHE_ExistsWaitState) 没有定义,因此它永远不会分配等待状态。我是简单地定义它#define PLIB_PCACHE_ExistsWaitState还是会遇到错误?

于 2019-08-23T12:09:30.357 回答
0

我终于自己解决了这个问题。

这只是我缺乏知识。我在 2 个单独的数据表中找到了关键信息。

其中之一是第 318 页的“PIC32MX1XX/2XX 28/44-PIN XLP FAMILY Data Sheet”,其中规定最大 SPICLK 不得超过 25MHz(我相信 .

第二个关键信息是波特率的计算。我认为 BaudRate 等于所选的 PBCLK(所以当我有一个 72MHz 的 SYSCLK 并且 PBCLK 是 SYSCLK=PBCLK/2 => 36MHz 时,BaudRate 也设置为 36MHz)。但是在“PIC32 FRM 第 23 节。串行外设接口 (SPI)”的第 23-29 页,有公式 F_SCK = F_PB / ( 2 ⋅ ( SPIxBRG + 1 ))

于 2019-10-08T14:33:41.983 回答