STM8 单片机调试笔记

1、休眠唤醒后串口异常问题

    STM8L主要用来做低功耗产品,这里就有休眠前跟唤醒后有差异的情况,在调试的时候碰到如果使用串口,在休眠前都正常,当唤醒后,串口发送的数据会出现异常的情况,发送的数据感觉会有丢帧。后来发现跟系统时钟有关,如果系统时钟采用外部时钟就会有问题,内部时钟就OK。

        /*
这里要用内部时钟
用外部时钟在进入halt之后会出现
串口发送异常
*/
CLK_HSICmd(ENABLE);
while (CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == RESET);

  CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);

  CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);


2、RTC唤醒设置问题

        如果要做低功耗,主要是通过RTC来唤醒,这样CPU能进入最低休眠。设置RTC也碰到一个奇怪问题,设置唤醒计数器一定要在开中断之前,不然设置会无效。

        CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
        CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);
        RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16); //32768/16  = 2048

        RTC_SetWakeUpCounter(2048 * g_RtcCtl.u32WakeInt); //这个要放在开中断前

        RTC_ITConfig(RTC_IT_WUT, ENABLE);
        RTC_WakeUpCmd(ENABLE);

        这也就是为什么,如果你原来设置5s唤醒一次,那么如果你不断电,然后下载10s唤醒一次的程序,RTC还是5s唤醒,除非你重新上电才会有效。


3、ADC多通道切换问题

      我程序要用到两个采集,一个用来做IO口的AD采集,一个用来内部参考电压做电源电量采集,这里碰到一个奇葩问题,如果你在切换通道的时候,第一次采集的数据就是不对,需要第二次采集的数据才行。


        SMOKE_DET_PWR_EN();

//ADC_DeInit(ADC1);
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_1);
        ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_384Cycles);
ADC_Cmd(ADC1, ENABLE);
        ADC_ChannelCmd(ADC1, ADC_Channel_4, ENABLE);
    
        T_U32 u32Delay = 100;
        while(u32Delay--);
    
     for(u8i = 0; u8i < 2; u8i++)
 {
            ADC_SoftwareStartConv(ADC1);
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0);
  ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  u16Ad = ADC_GetConversionValue(ADC1);
  }

SMOKE_DET_PWR_DI();

ADC_ChannelCmd(ADC1, ADC_Channel_4, DISABLE);
ADC_Cmd(ADC1, DISABLE);

CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, DISABLE);


        CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_1);
ADC_VrefintCmd(ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, ENABLE);

T_U32 u32Delay = 100;
        while(u32Delay--);

for(u8i = 0; u8i < 2; u8i++)
{
        ADC_SoftwareStartConv(ADC1);
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0);
  ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  u16Ad = ADC_GetConversionValue(ADC1);
}

ADC_Cmd(ADC1, DISABLE);
ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, DISABLE);

猜你喜欢

转载自blog.csdn.net/cheng401733277/article/details/81042021