打印

发现GD32F103一个bug:Stop模式RTC闹铃事件唤醒有问题

[复制链接]
9542|33
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
周立功GD32|  楼主 | 2013-8-5 19:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天调试Stop模式RTC闹铃事件唤醒功能,发现一个bug:

int main(void)
{
    uint32_t  n;

    DeviceInit();                                       //  初始化
    rtcAlarmAheadSet(500);                              //  设置RTC闹铃超前值
    rtcAlarmEventEnable();                              //  使能RTC闹铃事件

    for (;;)
    {
        //  进入停机模式,等待RTC闹铃事件唤醒
        sysModeStop(SYS_WAKEUP_EVENT);

        //  对GD32F103必须插入一个延时才行,否则LED不会闪烁(STM32F103不需要)
        n = 80;
        while (--n != 0);

        //  重新设定RTC闹铃超前值
        rtcAlarmAheadSet(500);

        //  反转LED,形成闪烁效果
        LedToggle(LED1);
    }
}

调试结果:
    n值取60以上才行,取60以下LED可能不会闪烁
    用GD32F103RBT6、GD32F103VBT6等多颗样片试过,现象都一样,但在STM芯片里没有此现象

当然,不算大问题,只要插入一个足够长的延时(80以上)就能解决掉
沙发
人生之际| | 2013-8-5 20:14 | 只看该作者
STOP模式时,PLL、HSI和HSE RC振荡器的功能被禁止。恢复的比较慢是不是和GD的芯片外时钟起振慢有联系,既然初始化配置的时候要延迟的比STM的大,估计唤醒后也要一定的延迟才能正常起振

使用特权

评论回复
板凳
Anthony_l| | 2013-8-6 16:45 | 只看该作者
自古二楼出真相

使用特权

评论回复
地板
s99060| | 2013-8-6 19:51 | 只看该作者
恢复的时候内核有时钟外设没时钟?

使用特权

评论回复
5
google21| | 2013-8-7 11:25 | 只看该作者
从“LED不闪烁”的现象看,可能是ALM和CNT这两个寄存器没配置成功。
如果在配置这两个寄存器的前后没有等到RTOFF FLAG置位的话,配置就会不成功,不知道是不是这个问题。
STOP起来以后,恢复的就是HSI,只要不使能HSE和等HSE_READY的话,就不存在在这方面花时间的问题,所以应该不是二楼说的那个问题。

使用特权

评论回复
6
周立功GD32|  楼主 | 2013-8-7 17:23 | 只看该作者
今天调试另外一个例程,仍然是“Stop模式+RTC闹铃事件唤醒”的问题:

int main(void)
{
    ...(初始化配置)

    rtcAlarmAheadSet(1);
    rtcAlarmEventEnable();     //  使能RTC闹铃事件功能

    //  无限循环
    for (;;)
    {
        sysModeStop(SYS_WAKEUP_EVENT);          //  进入停机模式,RTC闹铃事件唤醒
        rtcAlarmAheadSet(1);                    //  设置RTC闹铃超前值(单位:秒)
        LedToggle(LED1);                        //  反转LED指示灯(输出0.5Hz方波)
        sec = rtcCounterGet();                  //  读取日历值(单位:秒)
        CalendarDisp(sec);                      //  显示日历(通过USART输出)
    }
}

问题:同样的hex文件,烧录到STM32F103里运行正常(LED正常闪烁,时分秒正常显示),但烧录到GD32F103里,却出现LED疯狂闪烁(222Hz)、USART疯狂刷屏的现象!(似乎是Stop模式失效了)

使用特权

评论回复
7
周立功GD32|  楼主 | 2013-8-7 17:27 | 只看该作者
暂时还没有找到解决/规避方法,郁闷ing

使用特权

评论回复
8
王紫豪| | 2013-8-7 23:05 | 只看该作者
这正说明 GD 不是克隆stm32 的

使用特权

评论回复
9
GONGO| | 2013-8-8 11:20 | 只看该作者
周立功GD32 发表于 2013-8-7 17:23
今天调试另外一个例程,仍然是“Stop模式+RTC闹铃事件唤醒”的问题:

int main(void)

建议你先检查一下自己的程序或者尝试一下以下的例程。应该不会有你说的问题。

//初始化部分省略

        /* Configure EXTI Line to generate an interrupt on falling edge */
        EXTI_Configuration();

        /* LSI on, RTC on */
        /* Configure RTC clock source and prescaler */
        RTC_Configuration();

while( 1 )
{
                /* Wait till RTC Second event occurs */
                RTC_ClearFlag(RTC_FLAG_SEC);
                while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);
               
                /* Set the RTC Alarm after 3s */
                RTC_SetAlarm(RTC_GetCounter()+ 3 );
               
                /* Wait until last write operation on RTC registers has finished */
                RTC_WaitForLastTask();
               
                /* Request to enter STOP mode with regulator in low power mode*/
                PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

          // 这里唤醒   可以放 LED 反转

}


使用特权

评论回复
10
google21| | 2013-8-8 11:50 | 只看该作者
我也来贴个代码吧,不知道楼主函数的具体实现,就自己写了。

int main(void)
{
//        uint32_t  n;
    DeviceInit();                                   //  初始化
    rtcAlarmAheadSet(500);                                      //  设置RTC闹铃超前值
    rtcAlarmEventEnable();                              //  使能RTC闹铃事件
    for (;;)
    {       
        //  进入停机模式,等待RTC闹铃事件唤醒
        //sysModeStop(SYS_WAKEUP_EVENT);
                 /* Request to enter STOP mode with regulator in low power mode*/
            PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
//        //  对GD32F103必须插入一个延时才行,否则LED不会闪烁(STM32F103不需要)
//        n = 80;
//        while (--n != 0);
        //  重新设定RTC闹铃超前值
        rtcAlarmAheadSet(500);
        //  反转LED,形成闪烁效果
//        LedToggle(LED1);
                LedToggle();
    }
}


void DeviceInit(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(LED_GPIO_CLK , ENABLE);
  GPIO_InitStructure.GPIO_Pin = LED_PIN ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(LED_PORT, &GPIO_InitStructure);
  GPIO_ResetBits(LED_PORT, LED_PIN );

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  PWR_BackupAccessCmd(ENABLE);
  BKP_DeInit();
  RCC_LSEConfig(RCC_LSE_ON);
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  RCC_RTCCLKCmd(ENABLE);

  RTC_WaitForSynchro();
  RTC_WaitForLastTask();
  RTC_SetPrescaler(32);
  RTC_WaitForLastTask();
}

void LedToggle(void)
{
        LED_PORT->ODR ^= LED_PIN;
}

void rtcAlarmAheadSet(uint32_t almtime)
{
//按道理这几句是不该注释掉的,不过注释掉了程序也没出问题,呵呵
//        RTC_WaitForSynchro();
//        RTC_ClearFlag(RTC_FLAG_SEC);
//    while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);
//        RTC_WaitForLastTask();
        RTC_SetAlarm(almtime);
        RTC_WaitForLastTask();
        RTC_SetCounter(0);
        RTC_WaitForLastTask();
}

void rtcAlarmEventEnable(void)
{
   EXTI_InitTypeDef EXTI_InitStructure;

  /* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */
  EXTI_ClearITPendingBit(EXTI_Line17);
  EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}

使用特权

评论回复
11
周立功GD32|  楼主 | 2013-8-8 13:17 | 只看该作者
GONGO 发表于 2013-8-8 11:20
建议你先检查一下自己的程序或者尝试一下以下的例程。应该不会有你说的问题。

//初始化部分省略

看到:PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
我也试过WFI方式,即GPIO中断唤醒,没发现问题,但WFE方式+RTC闹铃唤醒就有问题

使用特权

评论回复
12
GONGO| | 2013-8-8 14:01 | 只看该作者
周立功GD32 发表于 2013-8-8 13:17
看到:PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
我也试过WFI方式,即GPIO中断唤 ...

建议你用 ST 标准的库试一下,请注意 STOP 模式下的唤醒方式 。





使用特权

评论回复
13
google21| | 2013-8-8 16:38 | 只看该作者
周立功GD32 发表于 2013-8-8 13:17
看到:PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
我也试过WFI方式,即GPIO中断唤 ...

实习生可怜啊    我贴的代码是WFE的啊

使用特权

评论回复
14
周立功GD32|  楼主 | 2013-8-8 17:00 | 只看该作者
上例程!
大家如果感兴趣的话就调试一下,帮我看看到底是哪里出了问题?
现在还不能确定是我的代码有问题,还是芯片有问题,但表现是:烧录同样的hex文件,STM32F103正常,GD32F103通不过
问题:Stop模式RTC闹铃事件唤醒.rar (648.38 KB)

使用特权

评论回复
15
google21| | 2013-8-9 17:56 | 只看该作者
周立功GD32 发表于 2013-8-8 17:00
上例程!
大家如果感兴趣的话就调试一下,帮我看看到底是哪里出了问题?
现在还不能确定是我的代码有问题, ...

加上这句话试试,因为你在设置alm以前有一个读cnt,要读的话,就得等RSF起来。只是写寄存器无所谓。
G_rtcAheadVal = AheadVal;
  RTC_WaitForSynchro();
    Val = RTC_GetCounter();
    RTC_SetAlarm(Val + AheadVal - 1);

使用特权

评论回复
16
周立功GD32|  楼主 | 2013-8-12 08:59 | 只看该作者
刚才试过,楼上的方法有效!:handshake

使用特权

评论回复
17
周立功GD32|  楼主 | 2013-8-12 09:29 | 只看该作者
但是,另外一个问题尚未解决,见6楼的描述
上例程:
问题:Stop模式RTC简易日历.rar (66.67 KB)

使用特权

评论回复
18
google21| | 2013-8-12 17:01 | 只看该作者
在void DeviceInit(void)中加上
  //  Led初始化
    LedInit();
    LedOn(LED1);

在 for (;;)中注释掉最后一句话,灯好像能正常闪烁,所以问题可能出在CalendarDisp(sec);  这里面。
    {
        sysModeStop(SYS_WAKEUP_EVENT);                     
        rtcAlarmAheadSet(1);                              
        LedToggle(LED1);                                   
        sec = rtcCounterGet();                             
        //CalendarDisp(sec);                                 
    }

另一个思路是,既然肯定是stop mode没进去,那就来个大招:
不用注释CalendarDisp(sec);                                 
只需将sysModeStop(SYS_WAKEUP_EVENT);函数中的
__WFE();替换为__SEV();__WFE();__WFE();
O了。

使用特权

评论回复
19
周立功GD32|  楼主 | 2013-8-12 17:34 | 只看该作者
google21是高人啊!

●初始化时确实忘记写LedInit()了

●我也发现注释掉CalendarDisp(sec)就会正常
在该函数内部是调用usartPuts()函数实现的,而usartPuts()采用的是软件FIFO+中断自动进行发送的
软件FIFO是纯粹的内存操作,不会影响到硬件动作,那么有可能是Stop模式与USART的中断有冲突?
但是,同样的程序STM32跑起来很正常,GD32就不行,不理解!

●__WFE();替换为__SEV();__WFE();__WFE();
试过,能解决问题!
但是,为何呢?

使用特权

评论回复
20
google21| | 2013-8-12 18:01 | 只看该作者
绝对不是高人。
Stop模式与USART的中断有冲突?这个结论我更不敢下,没专门写代码测过。我看你代码中还用到了sleep mode,所以可能几个因素在一块儿了。两家芯片就是功能一样呗,具体咋实现的,肯定还是有些差异。
__WFE();替换是ARM给的建议,你可以google一下。其实就是在某些不知道什么原因的情况下,__WFE();不起作用了,而我们又非得想用__WFE();那就用__SEV();__WFE();__WFE();代替吧。所以只要我们代码肯定没问题,就大胆的用吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:GD兆易半导体——周立功单片机 www.zlgmcu.com/GigaDevice

5

主题

124

帖子

5

粉丝