当前位置:文档之家› STM8的按键程序学习笔记

STM8的按键程序学习笔记

STM8的按键程序学习笔记
STM8的按键程序学习笔记

STM8的按键程序学习笔记

本程序基于STM8S105K4 单片机学习程序。程序硬件就是STM8的最小开发板搭建,用的内部晶振1分频。经测试可以正常检测到按键的短按和长按。程序思想见。C程序中的注释。最终通过调试和实验。所有的程序如下:(程序中可能还有些其他没有发现的问题,或其他错误有问题再学习更改。)

///////**********按键扫描程序********//////

/*

本程序定义四个独立按键,对四个独立按键的短按长按进行识别,返回最终的键值

key_value为最终键值:0x11为按键1的短按,0x12为按键的长按。0x21为按键2的短按,0x22为按键的长按。类推

注意:键值读取之后应将键值复位清零,以备下次检测;

注意:系统中断函数中有按键扫描的部分程序INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 4)等。

调用方法:

void key_port_init();//按键端口的定义

void scan_key();//按键的扫描程序,放在定时器中断中,定时器1ms 中断。

extern unsigned char key_down_IF=0x00; //在中断函数中加入变量声明

extern scan_key(); //在中断函数中加入变量声明

extern key_value; //在主函数中加入变量声明

*/

#ifndef __KEY_SCAN_H

#define __KEY_SCAN_H

/*定义按键的端口位*/

#define key_1_io GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_PU_IT)

#define key_2_io GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_IN_PU_IT)

#define key_3_io GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_IN_PU_IT)

#define key_4_io GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_IN_PU_IT)

//#define key_1_in() {(GPIO_ReadInputPin(GPIOC, GPIO_PIN_5)==SET)? 1:0}

/*设置端口按键中断的触发方式下降沿和低电平触发*/

#define key_int_way EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);

//#define key_short 0x01; //定义短按键值,按键按下后根据按键1号按键短按最终键值为0x11,长按为0x12.类推

//#define key_long 0x02; //定义长按键值,

//#define key_short 0x01;

//#define key_short 0x01;

unsigned char key_value=0; //定义一个键值变量。

unsigned char key_down_IF=0x00; //按键按下标志位,0x10代表key1按下标志,0x20为key2按下,0x30为key3按下。

unsigned int key_delay_count=0; //按键延时计数器

unsigned int key_delay_short=100; //定义短按延时判断时间

unsigned int key_delay_long=1000; //定义长按的延时判断时间

/*读取按键的位值*/

unsigned char key_1_in()

{

if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_4))

return 1;

else return 0;

}

unsigned char key_2_in()

{

if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_5))

return 1;

else return 0;

}

unsigned char key_3_in()

{

if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_6))

return 1;

else return 0;

unsigned char key_4_in()

{

if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_7))

return 1;

else return 0;

}

#endif

///////**********按键扫描程序********//////

/*

建档时间:20151215

跟新记录:20151218测试通过。

注意事项:调试中遇到的问题有:按键的键值读取函数unsigned char key_1_in();等本来是准备放在宏定义里面的,但是总是报错有问题。所以放在函数中。

导致不能直接在其他程序中包含这个头文件。

程序思想:按键按下后进入中断,然后判断是哪个按键按下,并赋值。当有按键按下后按键按下标志位会被置位,然后在定时器的中断中不断检测是否有按键按下,如果

有按键被按下,则开始计时,如果计数值没有达到去抖的累计值则松手之后计时自动清零。当按下后计数根据定时器的计数的时间长短判断是长按还是短按,

然后将数据复制到键值返回到主函数中。按键程序没有在线等待,而是扫描形式判断。减小CPU的负担。

硬件支持:16MHz晶振1分频。按键中断选择下降沿中断。

*/

#include "key_scan.h"

void key_port_init()

{

key_1_io; //端口上拉输入中断

key_2_io;

key_3_io;

key_4_io;

key_int_way; //按键触发方式为下降沿低电平触发

}

////////INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 4)///////

void key_interrupt_do()

{

key_down_IF=0x10;

key_down_IF=0x20;

key_down_IF=0x30;

key_down_IF=0x40;

}

//1ms定时器中调用次程序,即每1ms扫描检测一次//

void scan_key()

{

if(key_down_IF != 0x00) //有按键按下开始扫描此时key_down_IF就有key1,2,3的信息

{

key_delay_count++; //延时计数器开始计数

if(key_delay_count>=65530)

{key_delay_count=0;key_down_IF=0;} //按键按下时间过长,则是故障,不执行按键反馈

if(key_delay_count>=key_delay_long)

{key_down_IF &=0xf0; key_down_IF |=0x02;} //加上长按标志else if((key_delay_count=key_delay_short)) {key_down_IF &=0xf0; key_down_IF |=0x01; } //加上短按标志

if( (key_1_in()) && (key_2_in()) && (key_3_in()) && (key_4_in()) ) //松手后判断

switch(key_down_IF&0xf0) //有按键按下的条件下,读取那个键按下的,然后判断是否已经松手,当前键值是什么

{

case 0x10:

if((key_2_in())&&((key_down_IF & 0x0f)> 0)) //松手后如果有长短按标志,则将结果公布这句可以省略

key_value=key_down_IF;

//松手的时候没有长短按标志,则不显示结果,且清零标志

{key_down_IF=0;key_delay_count=0;}

break;

case 0x20:

if((key_2_in())&&((key_down_IF & 0x0f) > 0)) //松手后如果有长短按标志,则将结果公布这句可以省略下同

key_value=key_down_IF;

//松手的时候没有长短按标志,则不显示结果

{key_down_IF=0;key_delay_count=0;}

break;

case 0x30:

if((key_3_in())&&((key_down_IF & 0x0f) > 0)) //松手后如果有长短按标志,则将结果公布

key_value=key_down_IF;

//松手的时候没有长短按标志,则不显示结果

{key_down_IF=0;key_delay_count=0;}

break;

case 0x40:

if((key_4_in())&&((key_down_IF & 0x0f) > 0)) //松手后如果有长短按标志,则将结果公布

key_value=key_down_IF;

//松手的时候没有长短按标志,则不显示结果

{key_down_IF=0;key_delay_count=0;}

break;

default: //如果是其他干扰的话,清零所有计数和标志

key_down_IF=0;key_delay_count=0;

break;

}

}

}

相关主题
文本预览
相关文档 最新文档