C语言 为什么唤醒中断在裸机编程中对STM32L412不起作用?

slmsl1lt  于 2023-02-03  发布在  其他
关注(0)|答案(1)|浏览(154)

我正在尝试对STM32L412T6控制器进行裸机编程。我在RTC唤醒中断处卡住了。我的代码跳到了while(1)循环,而没有进入中断处理程序,下面提到了我的代码。

int main(void)
{

    //LedConfig();
    rtc_domain_access();
    rtc_init();

    initialize_rtc_wakeup();
    NVIC_EnableIRQ(RTC_WKUP_IRQn);

    /* Loop forever */
    for(;;)
    {
        flag = 1;
    }
}

void rtc_domain_access(void)
{
    /* Enable Clock for Power interface.*/
    RCC->APB1ENR1 |= (1U<<28);

    /*Disable backup domain write protection*/
    PWR->CR1 |= (1U<<8);
    while((PWR->CR1 & (1U<<8))==0);

    /*Reset the Backup domain*/
    RCC->BDCR |= (1U<<16);
    RCC->BDCR &= ~(1U<<16);

    /*Enable LSE Clock source and wait until LSERDY bit to set*/
    RCC->BDCR |= (1U<<0);
    while ((RCC->BDCR & (1U<<1)) == 0);

    /*Select LSE as RTC Clock*/
    RCC->BDCR |= (1U<<8);
    RCC->BDCR &= ~(1U<<9);

    /*Enable RTC Clock*/
    RCC->BDCR |= (1U<<15);

    /*Disable access to RTC registers*/
    RCC->APB1ENR1 &= ~(1U<<28);

}

void rtc_init(void)
{
     /* Disable the write protection for RTC registers */
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;

    /* Check if the Initialization mode is set */
    if((RTC->ICSR & (1U<<6))==0)
    {
        /* Set the Initialization mode */
        RTC->ICSR |= (1U<<7);

        /* Wait till RTC is in INIT state*/
        while((RTC->ICSR & (1U<<6))==0);
    }

     /* Clear RTC_CR FMT, OSEL, POL and TAMPOE Bits */
    RTC->CR &= ~(1U<<6);         //FMT
    RTC->CR &= ~(1U<<20);        //POL
    RTC->CR &= ~(1U<<21);        //OSEL
    RTC->CR &= ~(1U<<22);        //OSEL
    RTC->CR &= ~(1U<<26);        //TAMPOE

    /* Set RTC_CR register */
    RTC->CR &= ~(1U<<6);         //FMT bit set as Zero,Hour Format Selected as 24
    RTC->CR &= ~(1U<<20);        //POL bit set as Zero, Output polarity selected as high.
    RTC->CR &= ~(1U<<21);        //OSEL[22:21] set as zero, output selection disabled.
    RTC->CR &= ~(1U<<22);

    /* Configure the RTC PRER */
    RTC->PRER = 0xFF;           // Synchronus value set as 255
    RTC->PRER |= (0x7F<<16);    // Asynchronus value set as 127.

    /* Exit Initialization mode */
    RTC->ICSR &= ~(1U<<7);      // Clear INIT bit.

     /* If CR_BYPSHAD bit = 0, wait for synchro */
    if((RTC->CR & (1U<<5))==0)
    {
        /* Clear RSF flag */
        RTC->ICSR &= ~(1U<<5);

        /* Wait the registers to be synchronised */
        while((RTC->ICSR & (1U<<5))==0);
    }

    /* Clear RTC_CR TAMPALRM_PU, TAMPALRM_TYPE and OUT2EN Bits */
    RTC->CR &= ~(1U<<29);
    RTC->CR &= ~(1U<<30);
    RTC->CR &= ~(1U<<31);

    /*Set Output type as open drain pullup*/
    RTC->CR |= (1U<<30);

    /* Enable the write protection for RTC registers */
    RTC->WPR = 0xFF;

}

void Pwr_Clear_Flag(void)
{
    PWR->SCR = 0x1F;
}

void RTCEx_DeactivateWakeUpTimer(void)
{
    /*Disable Write protection for RTC Registers*/
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;

    /*Disable the Wakeup Timer*/
    RTC->CR &= ~(1U<<10);

    /*In case of interrupt mode is used, the interrupt source must disabled*/
    RTC->CR &= ~(1U<<14);

    /* Wait till RTC WUTWF flag is set */
    while ((RTC->ICSR & (1U<<2)) == 0);

    /* Enable the write protection for RTC registers */
    RTC->WPR = 0xFF;
}

void RTCEx_SetWakeUpTimer_IT(uint32_t RTC_WAKEUP_TIME_IN_SECONDS,uint32_t WakeUpAutoClr)
{
     /* Disable the write protection for RTC registers */
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;

     /* Clear WUTE in RTC_CR to disable the wakeup timer */
    RTC->CR &= ~(1U<<10);

     /* Clear flag Wake-Up */
    RTC->SCR = (1U<<2);

     /* Poll WUTWF until it is set in RTC_ICSR to make sure the access to wakeup autoreload
         counter and to WUCKSEL[2:0] bits is allowed. */
    if((RTC->ICSR & (1U<<6))==0)
    {
        while((RTC->ICSR & (1U<<2))==0);
    }

    /* Configure the Wakeup Timer counter and auto clear value */
    RTC->WUTR |= (RTC_WAKEUP_TIME_IN_SECONDS-1);
    RTC->WUTR |= (WakeUpAutoClr<<16);

   /* Configure the clock source */
    RTC->CR &= ~(1U<<0);
    RTC->CR &= ~(1U<<1);
    RTC->CR |= (1U<<2);

     /* RTC WakeUpTimer EXTI Configuration: Interrupt configuration */
    EXTI->IMR1 |= (1U<<20);
    EXTI->RTSR1 |= (1U<<20);

     /* Configure the Interrupt in the RTC_CR register */
    RTC->CR |= (1U<<14);

     /* Enable the Wakeup Timer */
    RTC->CR |= (1U<<10);

     /* Enable the write protection for RTC registers */
    RTC->WPR = 0xFF;
}

void initialize_rtc_wakeup(void)
{
    RTCEx_DeactivateWakeUpTimer();
    Pwr_Clear_Flag();
    RTCEx_SetWakeUpTimer_IT(RTC_WAKEUP_TIME_IN_SECONDS,WakeUpAutoClr);
}

void RTC_WKUP_IRQHandler(void)
{
    EXTI->PR1 = (1U<<20);
    if((RTC->MISR & (1U<<2))!=0)
    {
        //GPIOB->ODR |= 1<<13;
        RTC->SCR |= (1U<<2);
        count++ ;

    }

}

我尝试每3秒进行一次RTC唤醒中断,当它发生时,我尝试增加变量count的值,而不是进入无限循环并更改标志值。

a64a0gku

a64a0gku1#

问题已解决,所发生的情况是RTC_WUTR寄存器在提供唤醒时钟之前重置值为0x0000FFFF,我必须将寄存器设置为零,一旦完成,问题已解决。

相关问题