ghost2 发表于 2009-1-2 10:45:59

很久没有发有价值的贴了,再帖一个74HC595的按键检测,希望抛砖引玉【恢复】

最近家中内外交困,没有任何“重登机器人分坛主”的实际行动,先发个没有技术含量的串行按键驱动回馈各位热心坛友。


功能:
最大8按键检测,带消干扰;
4线制驱动(其中2线为共用SPI时钟、数据,1线锁存,1线KEY_FEED反馈);
类似PC键盘的按键重发(首次重发长延时,其后端延时,可调)。


http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_568143.JPG
74HC595串行按键检测电路 (原文件名:KeyBoard.JPG) 

代码:


#include "key_board.h"                        /* 头文件啦,里面就一个函数声明,大家应该知道怎么写的 */

#include "chip.h"                                /* 一些WinAVR的类型定义等,如uint8_t */
#include "util.h"


#define SCAN_THREASHOLD                                2        /* 重复判断多少次以上视为按键被按下 */
#define FIRST_REPEAT_THREASHOLD                20        /* 首次重复多少次视为按住不放 */
#define NORMAL_REPEAT_THREASHOLD        10        /* 首次重复以后,重复多少次视为按住不放 */

static uint8_t repeat_threashold        = FIRST_REPEAT_THREASHOLD;


uint8_t get_key()
{
        uint8_t i;
        static uint8_t        last_code, last_code_count;
        static uint8_t        last_key, last_key_repeat;
        static uint8_t        chk_repeat = 0;


        for (i=0xFE; i!=0; i=(i<<1))
        {
                //
                // Shift data & check ket feed
                
                /* Start transmission */
                SPDR = i;
                
                /* Wait for transmission complete */
                while(!(SPSR & (1<<SPIF)));


                PORT_PIN_CLR (KEY_RCLK);
                NOP ();
                PORT_PIN_SET (KEY_RCLK);

                delay_us(1);
                
                if (!PORT_PIN_VALUE (KEY_FEED))
                {
                        if (i == last_code)
                        {
                                /* 按下的键与上次相同 */
                                if (++last_code_count> SCAN_THREASHOLD)
                                {
                                        last_key = i;
                                        last_code_count = 0;

                                        if( chk_repeat )
                                        {
                                                if (last_key_repeat++> repeat_threashold)
                                                {
                                                        repeat_threashold = NORMAL_REPEAT_THREASHOLD;
                                                        return last_key;
                                                }
                                                else
                                                        return 0xFF;
                                        }
                                        else
                                        {
                                                // 首次检测到该按键,下次该检查重发啦
                                                chk_repeat = 1;
                                                repeat_threashold = FIRST_REPEAT_THREASHOLD;
                                                return last_key;
                                        }
                                }
                        }
                        else
                        {
                                /* 换了个键按下 */
                                last_code = i;
                                last_code_count = 0;
                                last_key = 0;
                                last_key_repeat = 0;

                                chk_repeat = 0;
                                repeat_threashold = FIRST_REPEAT_THREASHOLD;
                        }

                        break;
                }
        }

        if (i == 0)
        {
                /* 没有键按下 */
                last_code = 0;
                last_code_count = 0;
                last_key = 0;
                last_key_repeat = 0;

                chk_repeat = 0;
                repeat_threashold = FIRST_REPEAT_THREASHOLD;
        }

        return 0xFF;
}

代码检测的是7个按键,但是改一下循环,就能够检测8个了,有兴趣的可以试试。

ghost2 发表于 2009-1-2 11:35:16

发错坛了,应该在AVR坛里-_-!!!

cowboy 发表于 2009-1-2 15:12:09

楼主,多个按键同时按下,HC595输出短路了

h2feo4 发表于 2009-1-2 15:14:10

键上串个二极管吧

cowboy 发表于 2009-1-2 15:46:21

既然只是检测按键,不如用HC165,只用三个IO(常规接法),或者两个IO(节约接法),或者一个IO(最省接法)。

ndust 发表于 2009-1-2 15:50:23

jh

Gorgon 发表于 2009-1-2 15:52:37

以下蓝色文字由版主:Gorgon&nbsp;Meducer&nbsp;于:2009-01-02,15:52:37&nbsp;加入。<font color=black>请发贴人注意:本贴放在这分区不合适,即将移走
原来分区:51单片机
即将移去的分区:AVR&nbsp;(原ourAVR.com)&nbsp;技术论坛
移动执行时间:自本贴发表0小时后
任何的疑问或咨询,请可随时联系站长。谢谢你的支持!</font>

ghost2 发表于 2009-1-2 17:29:24

>>>【2楼】&nbsp;cowboy
>>>&nbsp;楼主,多个按键同时按下,HC595输出短路了
多亏兄台提醒,再次瀑布汗……
反正要修改键位,我会加上1K电阻。谢谢!


>>>【3楼】&nbsp;h2feo4&nbsp;无机酸
>>>&nbsp;键上串个二极管吧&nbsp;&nbsp;

>>>【4楼】&nbsp;cowboy
>>>&nbsp;既然只是检测按键,不如用HC165,只用三个IO(常规接法),或者两个IO(节约接法),或者一个IO(最省接法)。
再次多谢提醒!以前发过过164驱动的按键+显示,74HC164键扫+显示实例,已经过项目验证
不过居然也没考虑多个按键同时按的问题,有一次瀑布汗

见笑了,各位./emotion/em012.gif&nbsp;

本贴被 ghost2 编辑过,最后修改时间:2009-01-02,17:32:02.

a105 发表于 2009-1-2 19:11:03

mark

erxun 发表于 2009-1-2 19:45:55

这个程序可以修改为:同时驱动数码管,同时检测按钮~~~~,

rainyss 发表于 2009-1-3 21:12:13

对,用165好,多键同时按下也能识别出来.

tkdr2001 发表于 2009-1-3 21:24:45

mark

xullin 发表于 2009-1-3 21:37:46

坛子就没有多少iar写得程序吗?

lydxbzw 发表于 2010-10-30 11:09:49

mark

blacknewnew 发表于 2011-9-2 10:49:25

mark

xld826 发表于 2017-7-19 17:01:35

MARK                           
页: [1]
查看完整版本: 很久没有发有价值的贴了,再帖一个74HC595的按键检测,希望抛砖引玉【恢复】