分享

AVR单片机定时器按键扫描程序

 龙龙生日是多少 2016-03-08

VR单片机定时器按键扫描程序

[日期:2008-07-09 ] [来源:东哥单片机学习网 www.picavr.com 整理 作者:佚名] [字体:大 中 小] (投递新闻)

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

*程序共定义了6个键的功能:K1、K2、K3、K4以及K5、K8组成的一对复合键,其中K2,K3为

*连击键,K5为上档键。在正常工作模式下按K1则切换至状态,在设定模式下按K1键循环选

*择4个数码管中的某个,被选中的数码管闪烁,此时单按K2键显示数值加1;常按K2显示数

*值以一定速度递增,同时数码管停止闪烁,当K2松开,数码管恢复闪烁,显示数值停留在

*K2松开前的值上。K3完成的功能和K2类似。其完成减操作。这2个键只有在设定状态才有

*效,可以有效防止误操作。K4为确认键,按下该键回到正常显示状态,所有指示灯熄灭,

*数码管显示刚刚设定的数值。K5 K8这对复合键执行复位操作,任何情况下同时按下K5和K8

*或先按下K5再按下K8,所有数码管的显示全为0,指示灯全灭,进入正常显示状态。同时程

*序还对如下几个异常操作进行了处理:

* 2个或多个功能键同时按下

* 一个功能键按下未释放,又按另一个功能键,然后再松开其中一个功能键

* 先按下功能键再按下上档键

* 多个上档键和一个功能键同时按下,此时不做处理。等到松开其他上档键,只剩下一个上

* 档键和一个功能键时才执行这对复合键;或松开所有上档键,处理单一功能键。

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

#include <iom8v.h>

#include <macros.h>

#define uchar unsigned char

#define uint unsigned int

#define RCtrl 0x20 //定义上挡键 第5键

#define RConti 0xfe //定义连击键 第6键

#define N 2 //去抖年龄下限

#defi

1/15页

ne MaxRate 50 //重复前的延迟值 600ms

#define MinRate 20 //重复速度 240ms

#define leddark 83 //闪烁时灭时间1s

#define ledshow 83 //闪烁时亮时间1s

#define decimal 0x80 //小数点的段数

#define KEY_DDR DDRC

#define KEY_PORTO PORTC

#define KEY_PORTI PINC

#define OUT 0x3f

#define IN 0xc0

#define KeyValue 0x3f

#define LEDD_DDR DDRB

#define LEDD_PORTO PORTB

#define LEDS_DDR DDRD

#define LEDS_PORTO PORTD

#define LEDS_MASK 0xfc

#define LEDS_NUM 0x06

#define TRUE 1

#define FALSE 0

/*定义键盘扫描程序返回数据类型*/

typedef struct

{

uchar shiftcnt; //上档键的个数值

uchar funcnt; //功能键的个数值

uchar shiftval; //最后扫描到的上档键的值

uchar funval; //最后扫描到的功能键的值

} keyret;

/*定义显示字符段码*/

uchar const led_stroke[19] =

{

//0,1,2,3,4,5,6,7,8,9

0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,

//a,b,C,d,e,F,P,

0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x73,

//all on all off

0xff, 0x00

};

/*定义位选码*/

uchar const led_cs[LEDS_NUM] =

{

2/15页

0xfb, //11111011

0xf7, //11110111

0xef, //11101111

0xdf, //11011111

0xbf, //10111111

0x7f //01111111

};

uchar led_buf[LEDS_NUM] =

{

0x73, 0x81, 0x82, 0x83, 0x84,0x85

};

uchar *pb = &led_buf[1]; //定义指向数码管数据缓冲区的指针

/*定义全局变量*/

uchar task, state; //task:按键状态,0:去抖 1,重复的延迟 2,重复

//state:显示位置变量

uchar keydone, keyprocess; //keydone: 按键任务完成标志,为1表示已完成

//keyprocess: 按键有效标志,为1时表示对按键执行

uchar keypre[2] =

{

0x00, 0x00

}; //存放上次功能键和上档键的键值

//keypre0存放功能键

uchar blink, ledtime; //blink:闪烁控制寄存器,某位为1时闪烁

//d7d6d5d4d3d2d1d0

//xxxx1111

//ledtime:累计闪烁时已点亮和已熄灭的时间

uchar ledtask; //ledtask: 当前的闪烁状态,0代表亮

uchar keymark; //keymark:只是当前工作状态,为1时处于设定状态,为0时正常工作

uchar enflash; //enflash:闪烁使能标志,1闪烁

#define shut_dis() LEDS_PORTO|=LEDS_MASK; //shut display

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

*函数原型: uchar _crol_(uchar data,uchar shiftbit);

*功能:字节左移shiftbit

*参数:

*说明:

**********************

3/15页

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

uchar _crol_(uchar data,uchar shiftbit)

{

data &=0xff;

if(shiftbit>8)return 0;

return ((~data)<<shiftbit);

}

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

*函数原型: uchar _cror_(uchar data,uchar shiftbit);

*功能:字节右移shiftbit

*参数:

*说明:

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

uchar _cror_(uchar data,uchar shiftbit)

{

data &=0xff;

if(shiftbit>8)return 0;

return ((~data)>>shiftbit);

}

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

*函数原型: void send_shift(uchar d);

*功能: 将显示数据由B口送出

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

void send_shift(uchar data)

{

LEDD_PORTO = data;

}

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

*函数原型: void lflash();

*功能:闪烁处理。ledtask指示当前的显示状态:亮或灭,ledtask为0时亮

*参数:

*说明:

********************************

4/15页

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

void lflash()

{

if (enflash && (blink &0x3f))

{

if (ledtime-- == 0)

{

if (!ledtask)

ledtime = leddark;

else

ledtime = ledshow;

ledtask = ~ledtask; //显示状态翻转

}

}

else

ledtask = 0;

}

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

*函数原型: void display(uchar pos);

*功能:将pos对应的显示缓冲区的内容显示在第pos位数码管上

*参数:

*说明:

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

void display(uchar pos)

{

uchar sflag;

shut_dis(); //关显示

sflag = (blink >> (6-pos)) &0x01; //取出pos对应的数码管的闪烁控制位

if (pos == 0)

send_shift(led_buf[0]); //指示灯显示时直接将显示内容送显示端口

else if (!sflag || (sflag &!ledtask)) //不闪烁或正处于闪烁的亮阶段

if ((led_buf[pos] &0x80) == 0) //不显示小数点,查表得到段码送显示端口

send_shift(led_stroke[led_buf[pos] &0x7f] |decimal); //显示小数点,把查表得到段码与小数点的段码与的结果送显示端口

else

send_shift(led_stroke[led_buf[pos] &0x7f]);

els

5/15页

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多