PIC24FJ128GB204 - 深度睡眠问题:无法在深度睡眠后恢复代码 + 无法进入深度睡眠超过 1 次



实际上我正在使用PIC24FJ128GB204,并且我在使用DeepSleep时遇到了问题。

我的设备由 4 个按钮和几个 LED(彩色手电筒)组成。有一个按钮,使设备睡眠,直到我想使用它,相同的按钮唤醒我的设备。

消耗将全部LED熄灭为10mA。

我尝试过睡眠模式,简单的功能进入基本睡眠,而不是在断言所选引脚后唤醒。在睡眠模式下测量功耗 我有 2.50mA。工作得很好。

我已经开始使用 DeepSleep,因为我不需要任何代码保留,只需要将我的设备保持在尽可能低的消耗状态(但避免使用滑动电源开关)。我使用数据表示例代码来实现我的函数。结果我可以进入这种状态,而不是我有 0.45mA 作为消耗。

我已经设置了一个INT0(如数据表建议的那样)来唤醒我的设备,并将其与正确的唤醒PIN相关联。

问题从现在开始:

  • 当我按下唤醒按钮时,我的功耗正常变为 10mA,但我无法点亮任何 LED。似乎我的设备没有响应。

  • 如果我再次按下睡眠按钮,我的设备将进入睡眠模式而不是深度睡眠,因为我的功耗回到 2.50mA。同样,如果我唤醒我的设备,它会唤醒但没有响应。不知道我再试了多少次,但我的设备再也不会进入深度睡眠,直到我关闭并再次打开我的设备。

我已经进行了一些测试,但无法理解会发生什么。也许在DeepSleep设备应该手动重置(尝试但没有成功)之后,或者可能需要再次设置一些配置位。或者也许配置位不正确?

以下是代码的有趣部分:

配置

// CONFIG4
#pragma config DSWDTPS = DSWDTPS3       // Deep Sleep Watchdog Timer Postscale Select bits (1: 256 (8.3 mS))
#pragma config DSWDTOSC = LPRC          // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock)
#pragma config DSBOREN = ON             // Deep Sleep BOR Enable bit (DSBOR Enabled)
#pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer Enable (DSWDT Disabled)
//#pragma config DSSWEN = OFF             // DSEN Bit Enable (Deep Sleep operation is always disabled)
#pragma config DSSWEN = ON              // DSEN Bit Enable (Deep Sleep is controlled by the register bit DSEN)
#pragma config PLLDIV = DIVIDE2         // USB 96 MHz PLL Prescaler Select bits (Oscillator input divided by 2 (8 MHz input))
#pragma config I2C1SEL = DISABLE        // Alternate I2C1 enable bit (I2C1 uses SCL1 and SDA1 pins)
#pragma config IOL1WAY = ON             // PPS IOLOCK Set Only Once Enable bit (Once set, the IOLOCK bit cannot be cleared)
// CONFIG3
#pragma config WPFP = WPFP0             // Write Protection Flash Page Segment Boundary (Page 0 (0x00))
#pragma config SOSCSEL = ON             // SOSC Selection bits (SOSC circuit selected)
#pragma config WDTWIN = PS25_0          // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent)
#pragma config PLLSS = PLL_PRI          // PLL Secondary Selection Configuration bit (PLL is fed by the Primary oscillator)
#pragma config BOREN = ON               // Brown-out Reset Enable (Brown-out Reset Enable)
#pragma config WPDIS = WPDIS            // Segment Write Protection Disable (Disabled)
#pragma config WPCFG = WPCFGDIS         // Write Protect Configuration Page Select (Disabled)
#pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)
// CONFIG2
#pragma config POSCMD = HS              // Primary Oscillator Select (HS Oscillator Enabled)
#pragma config WDTCLK = LPRC            // WDT Clock Source Select bits (WDT uses LPRC)
#pragma config OSCIOFCN = ON            // OSCO Pin Configuration (OSCO/CLKO/RA3 functions as port I/O (RA3))
#pragma config FCKSM = CSECME           // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching is enabled, Fail-Safe Clock Monitor is enabled)
//#pragma config FCKSM = CSDCMD           // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = PRIPLL           // Initial Oscillator Select (Primary Oscillator with PLL module (XTPLL,HSPLL, ECPLL))
#pragma config ALTRB6 = APPEND          // Alternate RB6 pin function enable bit (Append the RP6/ASCL1/PMPD6 functions of RB6 to RA1 pin functions)
#pragma config ALTCMPI = CxINC_RX       // Alternate Comparator Input bit (C1INC, C2INC and C3INC are on RB9 )
#pragma config WDTCMX = WDTCLK          // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits)
#pragma config IESO = OFF               // Internal External Switchover (Disabled)
// CONFIG1
#pragma config WDTPS = PS1024           // Watchdog Timer Postscaler Select (1:1,024)
#pragma config FWPSA = PR128            // WDT Prescaler Ratio Select (1:128)
#pragma config WINDIS = OFF             // Windowed WDT Disable (Standard Watchdog Timer)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config ICS = PGx3               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC3/PGED3)
#pragma config LPCFG = OFF              // Low power regulator control (Disabled - regardless of RETEN)
//#pragma config LPCFG = ON               // Low power regulator control (Low voltage regulator controlled by RETEN bit)
#pragma config GWRP = OFF               // General Segment Write Protect (Write to program memory allowed)
#pragma config GCP = OFF                // General Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF             // JTAG Port Enable (Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>

关断功能

void TurnOff(void)
{
T1CONbits.TON = 0;
IEC0bits.T1IE = 0;
/* turn off */
OC1CON1bits.OCM = 0;
OC2CON1bits.OCM = 0;
OC3CON1bits.OCM = 0;
OC4CON1bits.OCM = 0;
OC5CON1bits.OCM = 0;
//    OC6CON1bits.OCM = 0;
if (!USB_BUS_SENSE)
{
USBMaskInterrupts();
USBModuleDisable();
OS_ENTER_CRITICAL();
T2CONbits.TON = 0;
IEC0bits.T2IE = 0;
TRISA = 0xffff;
TRISB = 0xffff;
TRISC = 0xffff;
//        I2C1CONLbits.I2CEN = 0;
//        
//        SPI1CON1Lbits.SPIEN = 0;
//        SPI2CON1Lbits.SPIEN = 0;
//        SPI3CON1Lbits.SPIEN = 0;
//        
//        U1MODEbits.UARTEN = 0;
//        U2MODEbits.UARTEN = 0;
//        U3MODEbits.UARTEN = 0;
//        U4MODEbits.UARTEN = 0;
//        
//        DMACONbits.DMAEN = 0;
//        
//        U1CONbits.USBEN = 0;
//        PMD1 = 0xffff;
//        PMD2 = 0xffff;
//        PMD3 = 0xffff;
//        PMD4 = 0xffff;
//        PMD5 = 0xffff;
//        PMD6 = 0xffff;
//        PMD7 = 0xffff;
//        PMD8 = 0xffff;
WDTDisable();
LPAppState = OFF_ST;
CNInit();
Nop();
Nop();
OS_EXIT_CRITICAL();
//#ifndef DEBUG_PENNA
{
//            ENTRATA IN SLEEP MODE(pag 164)
//            TEST 1
//            DSCONbits.DSEN = 1;
//            DSCONbits.DSEN = 1;
//            __asm__ volatile("pwrsav #0");
//            TEST 2    non funziona anche se c'è scritto così sul manuale (pag 164)
//            __asm__ volatile("disi #7");
//            __asm__ volatile("mov #8000, w2");
//            __asm__ volatile("mov w2, DSCON");
//            __asm__ volatile("mov w2, DSCON");
//            __asm__ volatile("nop");
//            __asm__ volatile("nop");
//            __asm__ volatile("nop");
//            __asm__ volatile("PWRSAV #0");
//            TEST 3
DSCONbits.DSEN = 1;
DSCONbits.DSEN = 1;
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("PWRSAV #0");
//            TEST 4    - LOW VOLTAGE (pag. 420) [provato sia con CONFIG LPCFG=1 e 0, l'effetto si ha con 1 anche se da manuale c'è scritto il contrario]
//            RCONbits.RETEN = 1;
//            __asm__ volatile("PWRSAV #0");
}
//#endif
USBDeviceInit();
}
WDTEnable();
T2CONbits.TON = 1;
IEC0bits.T2IE = 1;
}

中断声明

//------------------------------------------------
/**
void INTERRUPT_Initialize (void)
*/
void INTERRUPT_Initialize(void)
{
//    INT0I: INT0 - External Interrupt 0
//    Priority: 1
IPC0bits.INT0IP = 1;
}
/**
Section: External Interrupt Handlers
*/
void __attribute__((weak)) EX_INT0_CallBack(void)
{
// Add your custom callback code here
// Verifico se il dispositivo è uscito dal Deep Sleep (pag.165 datasheet)
if (RCONbits.DPSLP == 1)
{
// Risveglio da deep sleep
RCONbits.DPSLP = 0;
DSCONbits.RELEASE = 0;
}
}
/**
Interrupt Handler for EX_INT0 - INT0
*/
void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void)
{
//***User Area Begin->code: INT0 - External Interrupt 0***
EX_INT0_CallBack();
//***User Area End->code: INT0 - External Interrupt 0***
EX_INT0_InterruptFlagClear();
}
/**
Section: External Interrupt Initializers
*/
/**
void EXT_INT_Initialize(void)
Initializer for the following external interrupts
INT0
*/
void EXT_INT_Initialize(void)
{
/*******
* INT0
* Clear the interrupt flag
* Set the external interrupt edge detect
* Enable the interrupt, if enabled in the UI. 
********/
EX_INT0_InterruptFlagClear();
EX_INT0_PositiveEdgeSet();
EX_INT0_InterruptEnable();
}

当我按下唤醒按钮时,我的功耗正常变为 10mA,但是 我不能点亮任何指示灯。似乎我的设备没有响应

您的问题就在这里:

TRISA = 0xffff;
TRISB = 0xffff;
TRISC = 0xffff;

您在进入深度睡眠之前将引脚设置为输入,但我在您的代码中没有看到您在退出睡眠后设置引脚的任何地方,因此它们仍然充当输入,因此您将无法点亮 LED。

最新更新