第一步 时钟 void CLK_Config(void) { CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_8); / /设置系统分频,分频越大系统指令时间越长,功耗越低,如果主程序不用快速执行那么请将这个分频设的高一点(1-128分频) CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE); //启动ADC模块,启动后有1.2ma电流消耗,不用请禁用,对于间歇采样的用户,比如定时采样,请将此代码放置到采样开始前,采样好后立刻将模块禁止。 CLK_PeripheralClockConfig(CLK_Peripheral_TIM1, ENABLE);/ /其他模块做法相同,要一直用的就在系统初始化打开,否则请在用前开启。 /* Enable TIM2 clock */ CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE); /* Remap TIM2 ETR to LSE: TIM2 external trigger becomes controlled by LSE clock */ SYSCFG_REMAPPinConfig(REMAP_Pin_TIM2TRIGLSE, ENABLE); /* Enable LSE clock */ CLK_LSEConfig(CLK_LSE_ON); /* Wait for LSERDY flag to be reset */ while (CLK_GetFlagStatus(CLK_FLAG_LSERDY) == RESET); } 在主程序中的突击采样 u16 ADC_Supply(void) { uint8_t i; uint16_t res; /* Enable ADC clock */ CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE); //【1]】开启模块时钟 /* de-initialize ADC */ ADC_DeInit(ADC1); /*ADC configuration ADC configured as follow: - Channel VREF - Mode = Single ConversionMode(ContinuousConvMode disabled) - Resolution = 12Bit - Prescaler = /1 - sampling time 9 */ ADC_VrefintCmd(ENABLE); //【2】参考电压使能(如果需要矫正采样值才需要开启参考电压,更准确的应该叫对比电压,这个电压值是厂家标定过的。 delay(60); //【2.1】让参考电压稳定 ADC_Cmd(ADC1, ENABLE); //【3】使能模块 ADC_Init(ADC1, ADC_ConversionMode_Single, //【3.1】配置寄存器 ADC_Resolution_12Bit, ADC_Prescaler_1); ADC_SamplingTimeConfig(ADC1, ADC_Group_FastChannels, ADC_SamplingTime_9Cycles); ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, ENABLE); delay(60); //【3.2】给采样模块稳定时间 ADC_DeInit(ADC1); /* disable SchmittTrigger for ADC_Channel_24, to save power */ ADC_SchmittTriggerConfig(ADC1, ADC_Channel_24, DISABLE); CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, DISABLE); ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, DISABLE); /* initialize result */ //【3.3】软件触发采样,循环8次做平均 res = 0; for(i=8; i>0; i--) { /* start ADC convertion by software */ ADC_SoftwareStartConv(ADC1); /* wait until end-of-covertion */ while( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0 ); /* read ADC convertion result */ res += ADC_GetConversionValue(ADC1); } /* de-initialize ADC */ ADC_VrefintCmd(DISABLE); //【3.1】禁止参考电压,节能 /* Disable ADC 1 for reduce current */ ADC_Cmd(ADC1, DISABLE); //【4.1】禁止采样模块 CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, DISABLE); //【4.2】关闭采样时钟,到此模块不再耗电 return (res>>3); } 楼下继续 |
stm8l-discovery_RTC.rar
下载1.78 MB, 下载次数: 107, 下载积分: ST金币 -1
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗-<stm32L / STM8L>
合理配置端口,悬空的端口一律推挽输出低
按键端口使用内部上拉输入,如果检测到按键,迅速将按键端口改变为推挽拉低输出,直到按键处理完。再回复上拉输入
led 必须使用上拉输出推动
检查每一个端口,避免存在任何压差。
一个内部上拉电阻一般为 45k 左右,如果被一个10k 电阻对地,那么 3.3v/55k=60uA 非常可观的功耗吧
回复:【MCU实战经验】一步步实现超低功耗-
如果是外部电源,或使用电池与外部电源一起复合使用。那么需要选用一款低静态电流的LDO 比如合泰的 ht7533,微芯的MCP1703,一般只有2-5ua,
如果想要再省点,也可以使用肖特基二极管串联到LDO的输出,但是由于二极管有线性的温漂和负载压降变化较大,那么做为ADC,DAC 应用时需要做校准。
对于储能电容可以使用低压瓷片,10uf/10V 1206是不错的选择,当然如果有大功率的器件的话还是需要添加电解电容,当然也可以用二极管把单片机和大功率器件隔离。
回复:【MCU实战经验】一步步实现超低功耗-
低功耗的核心就是休眠和唤醒,其实低功耗的单片机在正常工作的时候几乎和其他单片机没有太多的区别,一般8M 至少也要1ma以上,一个cr2032 电池顶多能工作230小时。
但是如果一旦休眠后,电流需求是相当小的,一般就是 1uA 左右,那么一颗同样的电池不计自放电,可以提供芯片休眠230000小时=26年。
当然实际工作的时候需要让芯片做事的不是让他一直睡觉的,所以低功耗的设备一般就工作在脉冲式的工作方式,也就是突击采集,突击运算,让芯片的工作都集中在被划分成固定时间片中的一小段时间,比如每秒工作一次,在这一秒的某个时刻唤醒单片机,并调整到较快完成任务的时钟速度。干完后立刻休眠,如果我们每秒要检测一次电池电压,就可以每秒唤醒一次,唤醒后初始化电池电压采集,然后运算上一秒采集的电压值并处理,处理完成后开始采集,或保存采集的数据等待下一秒处理,在这里ADC采集初始化需要20us,采集8次做平均需要200个时钟,如果处理数据为500个时钟,那么对于stm8L (16M),每秒只需要工作 1/16000000/5XX=2800分之一秒,也就是每秒电流消耗平均下来只有 6ma(高速电流消耗)/2800+1ua=3ua左右 ,对于需要实时工作的系统同样有效,比如如果需要10ms 一次的话,电流消耗也只有 6ma/28+1ua=201ua,这是芯片的唤醒时间和中断处理就显得非常重要,在c 处理中,唤醒中断需要额外处理许多时间,对于stm8 唤醒时间是4us 实际测试的最大中断频率是300khz 也就是说stm8L 最大的实时处理的唤醒方式建议最大周期要《30k 最好
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗 第四步 唤醒工作方式
RE:【MCU实战经验】一步步实现超低功耗 简单的RTC 唤醒例程
RE:【MCU实战经验】一步步实现超低功耗 第五步 常用外设的连接
1分开供电:对一些大功率的外围,比如无线通讯模块,可以用一个mos开关控制是否为外设供电,对一些小功率器件,比如运放,存储器可以结合实际最大消耗电流,可以直接使用i/o口输出高电平为芯片供电,i/o一般可以输出 6-20ma,pp模式。当然别忘串一个很小的电阻,10欧,外设的退偶电容不能很大。一个i/o不够可以过个一起供。
让稳压器的输出电压略高于电池电压,这样有外部电源供电的时候就可以不消耗电池了
回复:【MCU实战经验】一步步实现超低功耗 第五步 常用外设的连接
RE:【MCU实战经验】一步步实现超低功耗 第五步 常用外设的连接