如何利用STM8S单片机实现一键式的开关机功能

开关机功能是使用电池供电系统的最基本功能。如果使用机械式开关(2段拨动开关,自锁开关等)等直接接通和切断电源,不说机械部件的可靠性,至少自动关机(一般在长时间不操作、电池电量低时需要自动关机)功能就比较难实现。所以电池供电系统一般采用按钮开关,用一个按钮配合软件实现按一次开机、再按一次关机的功能及自动关机的功能。
这部分内容就讲述如何在上实现一键式的开关机功能。开关机功能要使用单片机的一个引脚(pd4)作为输入端,连接到按钮,接收按纽按下产生的电信号,然后再使用另一个引脚(pd3)作为输出端去驱动由三极管8550构成的一个电子开关实现对系统电源的控制。而stm8s单片机本身就直接接在电池上,利用单片机的停机模式,将单片机本身的电流降低到μa级,对电池的消耗就可以忽略不计了。
1、电路设计
电路图如下,c1是stm8s单片机vcap电容,保持内部1.8v电压的稳定,是stm8s单片机唯一必须接要的外部元件,选用容量为1μf的瓷片电容,而且从电路可靠性讲,这个电容越靠近单片机ic越好。
k1是按钮,一端接到单片机的pd4引脚上,另一端接地,这样按钮被按下就会产生一个低电平的脉冲。
q1是三极管,通过发光二极管d1和限流电阻r1接到单片机的pd3上。这样当pd3输出低电平时,q1导通,vcc上有电压,可以对系统供电,反之pd3输出高电平时,q1截止vcc没有电压。
发光二极管d1还兼作电源指示灯的作用, q1导通时发光反之不发光。
剩余的c2~c5都是电源退藕电容,用于消除电源上的干扰信号。p1、p2两个接线端分别接3.6v锂电池的正负极。
2、软件设计
软件要实现的功能是,在pd4引脚上监控按钮按下产生的低电压脉冲信号,并根据这个信号来设置pd3引脚的输出电平去控制q1的导通和截止,以及设置单片机自身的工作状态,以此实现对电源供电的控制。
1)引脚工作模式设置
首先要做的,就是设置单片机引脚的工作模式,把pd4设置为输入模式,d3设置为输出模式。
在stm8s_stdperiph_lib库中,可以使用这个函数进行设置:
void gpio_init(gpio_typedef* gpiox, gpio_pin_typedef gpio_pin, gpio_mode_typedef gpio_mode)
gpiox是端口编号,取值有gpioa、gpiob、gpioc、gpiod,分别对应单片机的pax、pbx、pcx、pdx端口,gpio_pin是引脚编号,取值有gpio_pin_1~gpio_pin_7,函数通过gpiox和gpio_pin两个参数指定一个唯一的引脚。
gpio_mode是工作模式了。表示输入模式的取值有四种,分别是要不要上拉,要不要中断的四种组合:
gpio_mode_in_fl_no_it input floating, no external interrupt
gpio_mode_in_pu_no_it input pull-up, no external interrupt
gpio_mode_in_fl_it input floating, external interrupt
gpio_mode_in_pu_it input pull-up, external interrupt
要上拉的话,单片机内部会自动为引脚提供一个上拉电流,在没有外部输入的情况下,引脚就是高电平了。
表示输出模式的取值有8种,分别是是否开漏输出、输出高低电平、是否高速输出的组合:
gpio_mode_out_od_low_fast output open-drain, low level, 10mhz
gpio_mode_out_pp_low_fast output push-pull, low level, 10mhz
gpio_mode_out_od_low_slow output open-drain, low level, 2mhz
gpio_mode_out_pp_low_slow output push-pull, low level, 2mhz
gpio_mode_out_od_hiz_fast output open-drain, high-impedance level,10mhz
gpio_mode_out_pp_high_fast output push-pull, high level, 10mhz
gpio_mode_out_od_hiz_slow output open-drain, high-impedance level, 2mhz
gpio_mode_out_pp_high_slow output push-pull, high level, 2mhz
在这个应用中,需要把pd4设置为带上拉(因为按钮未按下时要呈高电平)、有中断的输入模式。开机时,pd3要设置为低电平的输出模式(低电平才能让q1导通)。关机时pd3要设置为不带上拉的输入模式,所以这部分代码要这样写:
gpio_init(gpiod, gpio_pin_4, gpio_mode_in_pu_it); //pd4设置为带上拉、有中断的输入模式
gpio_init(gpiod, gpio_pin_3, gpio_mode_out_pp_low_fast); //开机时把pd3设置低电平的输入模
gpio_init(gpiod, gpio_pin_3, gpio_mode_in_fl_no_it);//关机时把pd3设置低电平的输入模式
额外提一下,除了gpio_init函数可以设置引脚是输出高电平还是低电平,还可以用下面四个函数继续引脚的高低电平:
void gpio_write(gpio_typedef* gpiox, uint8_t portval) //输出portval指定的电平
void gpio_writehigh(gpio_typedef* gpiox, gpio_pin_typedef portpins) //输出高电平
void gpio_writelow(gpio_typedef* gpiox, gpio_pin_typedef portpins) //输出低电平
void gpio_writereverse(gpio_typedef* gpiox, gpio_pin_typedef portpins) //高低电平翻转一次
2)停机模式设置
stm8s单片机有停机模式,在停机模式下,单片机功耗降到最低,所有时钟停止工作,但可以保留ram和寄存器的值,停机模式只能可以通过下面几种方式退出:
-外部中断(gpio)
-can接收中断
-spi传输结束
-i2c中断(从地址匹配)
-复位
通过执行halt指令,也就是执行库函数的halt()函数进入停机模式。
3)设置外部中断
外部中断通过setextintsensitivity函数设置:
void exti_setextintsensitivity(exti_port_typedef port, exti_sensitivity_typedef sensitivityvalue)
其中port是要设置外部中断的端口,取值有gpioa、gpiob、gpioc、gpiod,分别对应单片机的pax、pbx、pcx、pdx端口;
sensitivityvalue是外部中断类型,有以下几种取值,分别表示下降沿和低电平触发中断、上升沿触发中断、下降沿触发中断、上升沿和下降沿触发中断:
exti_sensitivity_fall_low interrupt on falling edge and low level
exti_sensitivity_rise_only interrupt on rising edge only
exti_sensitivity_fall_only interrupt on falling edge only
exti_sensitivity_rise_fall interrupt on rising and falling edges
在这个应用中,按钮按下是产生下降沿,要选取exti_sensitivity_fall_only模式。
设置中断模式后,还需要启用中断,使用enableinterrupts()函数启用。
4)外部中断处理程序
在st官方提供的stm8s_stdperiph_lib库自带的模板中,中断处理程序都在stm8s_it.c中实现。stm8s_it.c中已经根据中断向量设置好了每种中断处理程序的入口函数。只需在相应函数中填入内容即可。
这个应用中是要编写gpiod端口的外部中断处理函数,所以要在这个中
这个应用中是要编写gpiod端口的外部中断处理函数,所以要在这个中断处理函数中增加开关机的内容:
interrupt_handler(exti_portd_irqhandler, 6)
{
}
5)整体程序设计和源代码
单片机程序流程图如下,包含主程序main()的流程和stm8s_it.c的外部中断处理程序流程:
具体源代码如下,关键点前面已经介绍,就不再详细说明了:
a)main.c的源代码:
void delay(uint16_t ncount)//定义延时函数,ffff大约是0.2s
{
while (ncount != 0)
{
ncount--;
}
}
bool fpoweron_flag =false;//定义开关机标志
void main(void)
{
gpio_init(gpiod,gpio_pin_4,gpio_mode_in_pu_it);
exti_setextintsensitivity(exti_port_power_key,exti_sensitivity_fall_only);
enableinterrupts();
while (1)
{
if(fpoweron_flag == false)
{
gpio_init(gpiod, gpio_pin_3, gpio_mode_in_fl_no_it);//pd3脚设置为输入模式,q1截止
halt();//进入停机模式
}else
{
gpio_init(gpiod, gpio_pin_3, gpio_mode_out_pp_low_fast);//pd3脚设置为输出模式且为低电平,q1导通
///////
//插入用户自定义的代码
//////
}
}
}
b)stm8s_it.c的源代码:
void delay(uint16_t ncount); //delay函数在main.c中定义
extern bool fpoweron_flag; //fpoweron_flag在main.c中定义,所以这里要声明成外部变量
interrupt_handler(exti_portd_irqhandler, 6)
{
delay(6000); //延时消抖
if(!gpio_readinputpin(gpiod, gpio_pin_3))//判断是不是按钮被按下
{
if(fpoweron_flag)
{
fpoweron_flag=false;
}else
{
fpoweron_flag=true;
}
}
}
3、关机后实测结果
使用stm8s开发板实测关机电流,为40μa左右:
按18650锂电池的典型容量2500mah计算,关机后可以支持2500mah/0.04ma/24小时/365天=7.1年,已经超过电池的充电循环使用寿命了,基本可以接受,不过应该还没有达到最低值,还可以研究datasheet,继续优化软件,进一步减低关机电流。
4、总结
开关机部分就讲完了,最后总结一下,这部分学习到的知识点包括:
1、单片机硬件设计,至少需要一个vcap电容接到vcap引脚和地之间,选用容量为1μf的瓷片电容,电在路布局上,这个电容越靠近单片机ic越好。
2、设置各个引脚的输入、输出模式设置方法
3、进入和退出停机模式的方法
4、设置外部中断和中断处理程序


动环监控系统方案简介
利用3D打印技术制作电动三轮车
苹果虚拟现实技术升级 未来或用于AR导航
MEMS 麦克风技术简介 — 模拟麦克风与数字麦克风
5G技术+AI技术开启万物智能时代
如何利用STM8S单片机实现一键式的开关机功能
吉拓网络签约英国会议话筒专家品牌ClockAudio ,成为中国大陆区总代理
C语言与C#的区别
无线充电或将成2019年技术大趋势
智能电网的内涵及其作用
Cloudera宣布将在 Cloudera Data Platform中推出全新的企业数据云服务
基于TIDA-00982型号的非军用无人机、机器人或 RC 2S1P 电池管理解决方案参考设计
可调电阻怎么接线
利用光化学反应实现三维纳米材料的高分辨率制造
泛林集团推出开创性的选择性刻蚀设备组合,以加速芯片制造商的3D路线图
关于Linux字符设备基本类型
努比亚红魔5G“火星红”配色曝光 专为手游女玩家设计
从停滞到解禁,人工智能的开荒记正式开始
美中在全球人工智能竞赛中独占鳌头
2019年5月六届中国机器人峰会上的机器鱼运动控制项目方法