基于RT-thread低功耗远程NB-IOT开锁,实现NB-IOT+STM32L4待机功耗5uA。

先上结果,实现了NB+STM32L4待机时的功耗为5uA。当然可以看到,我这只是MCU+NB的功耗。

项目整体简介:

整个项目基于RT-thread系统搭建,类似于共享单车的模式,是为共享锁,由微信小程序扫码然后远程开锁,并对锁的控制,需要有低功耗。

小程序界面

板子照片

MCU为STM32L431CCT6 ,NBIOT采用有人NB73,板子集成了电机驱动芯片(用来控制门锁驱动电机)蜂鸣器驱动,以及一个超低静态电流的LDO,以及低功耗的电压检测电路。

最终整个板子的功耗为30uA,MCU+NBIOT+LDO+电压检测电路。

低功耗实现

整个系统最重要的就是低功耗的实现,在这里除了特别选用了STM32L4的MCU,以及电路上其他器件的选型也特别重要,特别是稳压芯片的的静态电路不容忽视。

除此之外,也还要有软件上的控制,这里我使用的RT-thread的PM组件,进入了待机模式,并设置了两个唤醒按键以及RTC定时唤醒。

设置唤醒按键的HAL库函数如下

HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_HIGH|PWR_WAKEUP_PIN2_HIGH);

设置PIN1高电平唤醒以及PIN2高电平唤醒,在此之前,由于系统进入待机模式后,所有IO都处于复位状态,为了避免误动作,需要使用如下函数,来设置待机模式的引脚状态。

HAL_PWREx_EnableGPIOPullDown(PWR_GPIO_A, PWR_GPIO_BIT_0); HAL_PWREx_EnablePullUpPullDownConfig();

这是是设置了A0。

然后就可以愉快的进入待机模式了,当然进入之前,需要将唤醒标志位清0.

__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);  

其中PWR_FLAG_WU可以有多个参数选择,WUF1、WUF2等等,看看库函数的注释就可以了。

然后就可以调用RTT的PM组件进入待机模式了。

rt_pm_request(PM_SLEEP_MODE_STANDBY);  

当然,唤醒后,是出于复位装状态,会重新执行初始化,这里最好判断一下是否是被唤醒以及被什么方式唤醒。可以使用如下函数:

__HAL_PWR_GET_FLAG(PWR_FLAG_WUF1)

这里WUF1指的是WKUP_PIN1的事件。

关于RTC唤醒

我这里使用的是闹钟中断作为唤醒,你只需要初始化RTC在设置闹钟中断就可以,但是唤醒后复位并不会进入闹钟中断,他只是唤醒。

我本打算在RTT中直接添加RTC组件,但我发现他并没有使用硬件的闹钟中断,所以我在他的drv_rtc中自行实现了闹钟中断的初始化及设置函数。如下

rt_err_t rtc_set_alarmA(rt_uint8_t week, rt_uint8_t hour, rt_uint8_t min, rt_uint8_t sec,rt_uint32_t alarm_mask)
{
    RTC_AlarmTypeDef RTC_AlarmSturuct;

    RTC_AlarmSturuct.AlarmTime.Hours = hour; //小时
    RTC_AlarmSturuct.AlarmTime.Minutes = min; //分钟
    RTC_AlarmSturuct.AlarmTime.Seconds = sec; //秒
    RTC_AlarmSturuct.AlarmTime.SubSeconds = 0;
    RTC_AlarmSturuct.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;

    RTC_AlarmSturuct.AlarmMask = alarm_mask; 
    RTC_AlarmSturuct.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
    RTC_AlarmSturuct.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY; //按星期
    RTC_AlarmSturuct.AlarmDateWeekDay = week; //星期
    RTC_AlarmSturuct.Alarm = RTC_ALARM_A;   //闹钟A
    if(HAL_RTC_SetAlarm_IT(&RTC_Handler, &RTC_AlarmSturuct, RTC_FORMAT_BIN)!=HAL_OK)
		{
			return -RT_ERROR;
		}
    HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x01, 0x02); //抢占优先级1,子优先级2
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
		
		return RT_EOK;
}

只要正常使用RTT系统的settime函数设置RTC时间,在调用rtc_set_alarmA函数即可添加闹钟。闹钟中断函数只需要在某处定义即可。

 

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会飞的瘦子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值