这几天一直在做STM8l的低功耗模式调试,STM8l有三种低功耗模式(Wait 、Active-halt 、halt),这里对Active-halt模式进行调试,采用内部RTC进行唤醒,整个测试系统由STM8l芯片以及一个收发芯片构成,STM8l芯片睡眠唤醒后控制收发芯片进行收发数据。在STM8l进入Active-halt之前关闭所有外设时钟以及将外设失能,RTC的时钟采用内部LSI时钟二分频,对于IO口的设置,有文档说明:对于外设是高电平工作的,那么设置成推挽输出低,对于是低电平工作的那么设置成推挽输出高。按照以上文档配置IO口,测得的电流却比配置IO使收发芯片正常工作时测得的电流大。现在有几个问题:1、IO口的设置问题,在STM8l的低功耗模式下,应当如何设置其IO口尽量降低其功耗。
2、STM8l外设关闭问题?以前看到过文档说STM8l外设是默认关闭的,这与实际中自己测试得到的结果相一致,即对 ClosePeripheralClk()设置与不设置测得的电量几乎没有差别。
3、STM8l的低功耗模式:文档上写明STM8l在Active-halt模式下,电流为1 μA,现在已经关闭所有外设以及配置IO口,姑且认为收发芯片会产生一部分电流消耗,但实际测得的电流为2.5mA,电流太大(电流测量采用万用表进行测量)。
程序如下,希望大神帮忙看看问题出在哪里。
void RTC_timer(u16 m)
{
RTC_Config();
ClosePeripheralClk();
InIo();
RTC_WakeUpCmd(DISABLE);
RTC_SetWakeUpCounter(m); //设置RTC Weakup计算器初值
PWR_FastWakeUpCmd(ENABLE); //快速唤醒使能
PWR_UltraLowPowerCmd(ENABLE);//超低功耗
RTC_WakeUpCmd(ENABLE);//RTC唤醒使能
halt();
RTC_WakeUpCmd(DISABLE);
}
void RTC_Config(void)
{
RTC_DeInit(); //初始化默认状态
CLK_HSICmd(DISABLE);
CLK_LSICmd(ENABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE); //允许RTC时钟
CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_2); //选择RTC时钟源LSI、2=19K
while (CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == RESET);//等待时钟源就绪
RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16); //19k/16=1.1875KHz t=0.85ms
RTC_ITConfig(RTC_IT_WUT, ENABLE); //开启中断
}
void InIo(void)//初始化IO口,降低功耗
{
GPIO_Init(GPIOC, GPIO_Pin_2, GPIO_Mode_Out_PP_High_Slow);//pc2---out
GPIO_Init(GPIOC, GPIO_Pin_3, GPIO_Mode_Out_PP_Low_Slow);//pc3 ---vcc
GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Slow);//PC4--LED
GPIO_Init(GPIOD, GPIO_Pin_4, GPIO_Mode_Out_PP_High_Slow);//PD4--DIO0
GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_Out_PP_High_Slow);//PB7--DIO1
GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Slow);//PB6--DIO2
GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_Low_Slow);//PB5--DIO3
GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Slow);//PB4--DIO4
GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_Out_PP_Low_Slow);//PB3--DIO5
GPIO_Init(GPIOB, GPIO_Pin_2, GPIO_Mode_Out_PP_High_Slow);//PB2--SCLK
GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_Out_PP_High_Slow);//PB1--MISO
GPIO_Init(GPIOB, GPIO_Pin_0, GPIO_Mode_Out_PP_High_Slow);//PB0--MOSI
GPIO_Init(GPIOD, GPIO_Pin_3, GPIO_Mode_Out_PP_High_Slow);//PD3--NSS
GPIO_Init(GPIOD, GPIO_Pin_2, GPIO_Mode_Out_PP_High_Slow);//PD2--RXTX
GPIO_Init(GPIOD, GPIO_Pin_1, GPIO_Mode_Out_PP_High_Slow);//PD1--V2
GPIO_Init(GPIOD, GPIO_Pin_0, GPIO_Mode_Out_PP_High_Slow);//PD0--V1
GPIO_Init(GPIOA, GPIO_Pin_0, GPIO_Mode_Out_PP_High_Slow);//PA0
}
void ClosePeripheralClk(void)//关闭不用的外设
{
USART_DeInit(USART1);
TIM1_DeInit();
TIM2_DeInit();
TIM3_DeInit();
TIM4_DeInit();
ADC_DeInit(ADC1);
I2C_DeInit(I2C1);
DAC_DeInit();
CLK_PeripheralClockConfig(CLK_Peripheral_USART1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM3,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_DAC,DISABLE);
USART_Cmd (USART1,DISABLE);
TIM1_Cmd(DISABLE);
TIM2_Cmd(DISABLE);
TIM3_Cmd(DISABLE);
TIM4_Cmd(DISABLE);
ADC_Cmd(ADC1,DISABLE);
I2C_Cmd(I2C1,DISABLE);
DAC_Cmd(DAC_Channel_1,DISABLE);
}
void Systerm_Init(void)
{
CLK_HSICmd(ENABLE);
SX1278InitIo();//IO口初始化
InitUART1();//串口初始化
InitTIM4();//TIME初始化
sx1278LoRaInit(FRFMSB,FRFMID);//lora模式初始化
}
void main(void)
{
u16 addr=0x4926;
u8 *p=(u8*)addr;
u8 buf[4];
//系统初始化
SX1278InitIo();//IO口初始化
InitUART1();//串口初始化
InitTIM4();//TIME初始化
sx1278LoRaInit(0x7b,0x00)
for(t=0;t<4;t++)
{
buf[t]=*p++;
}
while(1)
{
enableInterrupts();//使能中断
//此处用RTC睡眠唤醒减小功耗,必要时可以考虑延时进行睡眠
RTC_timer(3915);
Systerm_Init();
if(Hallout==0)//唤醒后检测某个IO口的状态
{
GPIO_ResetBits(GPIOC, GPIO_Pin_3);//pc3脚置低电平
GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PINS);
delayms(500);//固定延时等待发送结束
GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PINS);
}
else//进入接收模式,持续时间为T5
{
T5=1;
enableInterrupts();//使能中断
TIM4_Cmd(ENABLE);
TIM4_ITConfig(TIM4_IT_Update, ENABLE); //允许tim4触发向上溢出中断
TIM4_TimeBaseInit(TIM4_Prescaler_128, 255); //定时器定式1s
while(1)
{
if(T5flag==0)//持续接收模式,时间为T5
{
}
else
{
}
}
}
}
嗯呢,解决了
一周热门 更多>