​开发过程中,为了节省成本,常常会采用按键和LED复用,从而达到节省IO口的目的。很多刚刚碰到这种情况的工程师,可能会不知道如何处理,PS:大神请自动略过。下面来给大家讲讲按键和LED复用IO口时,程序该如何处理吧。(这里采用状态机编程的方法,来实现按键和LED复用扫描功能)。

一、 按键和LED复用原理图如下:

按键和LED复用原理图及编程方法

LEDC是LED灯的COM控制端,LED1_K1和LED2_K2是按键和LED的复用IO口。扫描过程如下:

1、上电初始化时,先将LEDC、LED1_K1和LED2_K2设置为推挽输出高;

2、首先扫描LED1和LED2,LEDC输出高,LED1_K1根据系统标志判断,LED1需要亮,就输出低,LED1不需要亮,就输出高,LED2和LED1处理一样。

3、LED1和LED2扫描完成以后,LEDC输出低,LED1和LED2输出高,将LED1_K1和LED2_K2的IO口切换为输入状态,并且用一个变量备份一下LED1和LED2的输出电平状态,以便按键扫描完成后,恢复LED1和LED2的亮灭状态。

4、进入按键扫描状态,读取LED1_K1和LED2_K2引脚的电平状态,读取IO口电平完成以后,立即将LED1_K1和LED2_K2切换为推挽输出低模式,并且恢复步骤3中备份的LED1_K1和LED2_K2的电平状态到LED1_K1和LED2_K2管脚上。

以上四个步骤就是按键和LED复用时,程序的扫描过程,看不懂的话没有关系,大家结合源代码理解,就很清楚了。按键和LED复用扫描程序如下:

/**********************************************************

* 名称: void Led2Disp_Scan(void)

* 功能: led2和按键扫描函数

* 形参: 无

* 返回: 无

* 说明: 无

注意:当在使用STM8单片机编程时,切换IO口的输入输出状态时,请将IO口配置成低速模式(2MHz),要不然在切换IO口的输入输出状态时,会触发IO口的外部中断,造成程序异常。

**********************************************************/

void Led2Disp_Scan(void)

{

static INT8U scan_num = 0;//扫描状态变量

scan_num++;

switch(scan_num)

{

case 1://状态1扫描LED灯

{

COM1_ON();//置高LED公共端

LedDisp_Process(0,Bit_TyPeDefStructure.led2_disp);//根据标志位控制LED2的亮灭

LedDisp_Process(1,Bit_TyPeDefStructure.led1_disp);//根据标志位控制LED1的亮灭

}

break;

case 2://LED灯扫描完毕

{

COM1_OFF();//置低LED公共端

PC_ODR_BACK = GPIOC->ODR;//备份LED端口输出寄存器

LED1_ON();//LED1和LED2引脚置高

LED2_ON();

IO_INPUT();//切换成输入模式

}

break;

case 12://按键扫描一次的时间12*250us等于3ms

{

process_key();//按键处理函数,看不懂请参考源代码理解 scan_num = 0;//按键扫描完成后,回到状态0,继续LED灯的扫描

}

break;

default :

break;

}

}

以上就是整个扫描过程,注释已经讲解的很清楚了,就不在继续讲了。按键处理函数看不懂,请百度搜索“基于状态机的按键扫描程序”一文。

//main函数如下:

int main(void)

{

//设置内部16M晶振为系统时钟

System_Init();////

while (1)

{

IWDG_ReloadCounter();//清看门狗

if(fTimer1_250us)//查询是否到250us

{

Led2Disp_Scan();

fTimer1_250us = FALSE;//250us到任务处理完成,清除250us到标志

}

}

}

以上程序实现的功能是:

短按K1,LED1亮,LED2灭;

短按K2,LED1灭,LED2亮;

长按K1两秒,LED1翻转;

长按K2两秒,LED2翻转;

K1和K2同时按下2秒,LED1和LED2都翻转。

使用的是STM8S003F3单片机编程实现的,大家可以移植到任何平台

  • UC3846控制芯片工作原理控制图 逆变焊机原理与用途
  • 数字万用表电阻档测试二极管正反向没有阻值(使用万用表测量二极管的正向电阻,为什么各档)
  • 学单片机需要学数电模电吗(学单片机要先学数电模电吗)
  • 电工怎么选择适合自己用的万用表(电工初学者买什么样的万用表好)
  • 单片机需要同时运行多个任务怎么办(单片机怎么同时执行多个任务)
  • 电机保护的方案取决于负载的机械特性
  • 绝缘电阻表正负搭接不复零位是怎么回事
  • 短路怎么用万用表查