原创 指针理解与msOS中的矩阵键盘值读取运用

2013-9-4 14:57 1624 19 22 分类: 消费电子

         指针实际上只是一个寄存器,只保存指向内存的地址非实际需要的数值。一般使用它都是需要有一个实际保存内容的变量,一般是用结构体,使用指针主要是方便操作,如下Key 键值读取,直接操作寄存器地址,同时运用宏定义,简化使用。


        msOS 通过扫描方式实现了矩阵键盘值读取同时也实现了长按与短按键功能,通过注册函数KeySystemTickService 来收集与检测按键信息供其他函数使用。


        按键实现机理,从原理图来分析,原理图设计已经做了特如处理,按键处接了vdd3.3V 和 电阻 1K,默认状况是接按键的5个IO口都是低电平,若是有按键按下,其中相应的IO口为输入高电平。

        扫描函数(ScandPin)中通过改变了行按键输出值, (ScandPin01 = 0;ScandPin00 = 1),通过判断列的IO口状况,输出自己定义的按键值。

 

        长按与短按及去抖动实现原理:是在 KeySystemTickService 函数中进行计数 ScandCounter 及 JitterCounter,此函数被SysTick_Handler 函数调用,sysTick 为系统CPU 节拍时钟,即所谓心跳函数。每隔100个tick 进行运行一次KeySystemTickService 函数。 一个Tick 时间由如下函数得到  SysTick_Config(SystemCoreClock / 10000);长按短按判断依据是在每执行一次KeySystemTickService 函数时候,若是有按键之后读到的值为invalid,JitterCounter--,去抖动,若是无松开则ScandCounter++,判断第二次值是否一样,若是不一样丢掉按键信息即是去抖原理,一样按键值,ScandCounter++ 继续增加,当超过设定的最长按键时间(ScandCounter >= LongInterval)之后抛出按键消息。
  

精彩绝妙的宏定义及指针使用,直接操作寄存器。

//IO口操作,只对单一的IO口!确保n的值小于16!
#define BIT_BAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BIT_BAND(addr, bitnum))

#define PaIn(n)    BIT_ADDR(GPIOA_IDR_ADDR,n)
#define PaOut(n)   BIT_ADDR(GPIOA_ODR_ADDR,n)

#define PbIn(n)    BIT_ADDR(GPIOB_IDR_ADDR,n)
#define PbOut(n)   BIT_ADDR(GPIOB_ODR_ADDR,n)

#define ScandPin00 PbOut(4)
#define ScandPin01 PbOut(5)

#define ScandPin10 PcIn(10)
#define ScandPin11 PcIn(11)
#define ScandPin12 PcIn(12)
#define ScandPin13 PbIn(3)

#define ShortInterval   3  /*短按按键间隔*/
#define LongInterval    40  /*长按按键间隔*/
#define JitterInterval  10  /*防误动按键间隔*/


详细操作函数如下:(函数名字很直观表达函数内容)


static byte RemapKey(byte scandValue) //重新定义短按键键值
{
    switch(scandValue)
    {
        case 0xEF:
            return(0);
        case 0xDF:
            return(1);
       。。。
        default:
            return(invalid);
    }
}


static byte RemapLongKey(byte scandValue) //重新定义长按键键值

{
    switch(scandValue)
    {
        case 0xEF:
            return(0x30);
        case 0xDF:
        。。。
        default:
            return(invalid);
    } 
}

 

static byte ScandPin(void) // 扫描方式检测按键
{
    byte scandValue;
 
    scandValue = invalid;
    if(ScandPin13 == 0)
        scandValue &= 0x7F;

    if(ScandPin12 == 0)
        scandValue &= 0xBF;

    if(ScandPin11 == 0)
        scandValue &= 0xDF;

    if(ScandPin10 == 0)
        scandValue &= 0xEF;

    ScandPin00 = 0;
    ScandPin01 = 1;

 

    DelayUs(1);

    if(ScandPin13 == 0)
        scandValue &= 0xF7;

    if(ScandPin12 == 0)
        scandValue &= 0xFB;

    if(ScandPin11 == 0)
        scandValue &= 0xFD;

    if(ScandPin10 == 0)
        scandValue &= 0xFE;

    ScandPin01 = 0;
    ScandPin00 = 1;

    return(scandValue);
}

void KeySystemTickService(void) // 注册机制,检测是否有按键,发送KeyMessageType 类型的PostMessageQueue 消息。
{
    byte scandValue;

    scandValue = ScandPin();
   ....
       
        if (ScandCounter == LongInterval)
        {
            PostMessageToLogicTask(KeyMessageType, RemapLongKey(ScandValueSave));           
        }
        else if (ScandCounter > ShortInterval)
        {
            PostMessageToLogicTask(KeyMessageType, RemapKey(ScandValueSave));
        }
        ScandCounter = 0;
        ScandValueSave = invalid;
        JitterCounter = JitterInterval;
 }
    .....
}

void SysTick_Handler(void)
{
    static unsigned char Counter = 0;
 
  。。。。
    switch(Counter)
    {
     。。。。。。
        case 15:
            SystemTick100RegisterPointBlock[7]();
            break; 
           
        case 97:
            RtcSystemTickService();
            break;
        case 99:
            KeySystemTickService();
            break;
        default:
            break;
    }

    AdcSystemTickService();
// System.Device.Io.SetBeep(true);
 CheckstationSystemTickService();
}

 

硬件图如下:

20130903075909194.jpg

欢迎各位与我一起学习ARM 技术,我的E-MIAL:timeisours@163.com,web:www.51buddy.com,QQ:158377757

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1636821 2014-5-31 09:00

做工程师的人,头脑都一根筋,不善于同人打交道

用户1625273 2014-4-17 17:26

了解了解。

用户1744924 2014-4-14 15:33

中国环境在这  休年假像老外那样    估计要诺干年后。。。。。只有淡定啊   

用户1001211 2014-4-12 08:51

文化差异啊!

用户1037098 2014-3-25 09:08

干工程除了苦逼以外,文中提到的公司还需要两个要素:1)严谨,2)人文关怀。对IC设计公司来说,在掩膜后发现重大缺陷,会承受较大的经济损失,管理层和工程师会很痛苦,所以不会随意压缩开发周期。从第三篇老C的故事来看,公司有一定包容文化,不会要求人人苦逼,而是因人而宜。你苦是发自你内心,我没逼你,你不苦,我也不逼你苦。任何行业优秀者都是以苦为乐,或自己逼自己。

用户1449773 2014-3-23 08:41

大老美敬业

用户1631092 2014-3-19 21:57

工作氛围,环境的差异,心态更是重要。

ND7 2014-3-19 21:48

其实有很多人干到50多60岁就被裁了,再找工作也不容易。具体的以后开一篇说说。但是心态确实不一样,感觉老美们的危机感不如我们强烈,即使是和这边的华人比较也是。

用户956057 2014-3-19 19:02

很正常,人家是生活,咱们是生存。 档次不一样。

用户1199062 2014-3-19 15:03

我曾經到北美出差,到子公司去測試一些東西,常常看到有人都利用中午時間在跑步運動的,沒有人會睡午覺的。 還有一些人早上7點到,下午4點就離開了。夏天,北美要8點才天黑,也就是說他們還有4個小時的時間可以從事戶外活動。 熱愛運動以及戶外活動就是他們生活的寫照,假日,拖著露營車,在湖邊一紮營就是兩天一夜,哪裡也沒去,就一直呆在哪裡~ 種種的事情,在我們的眼裡看起來,有些都是無法理解的,這就是文化上的差異~
相关推荐阅读
用户1711683 2014-05-08 06:32
亚马逊智能手机 解读
  亚马逊智能手机 查询各大网站,还真看到介绍出入不大的介绍,难道是为了前期推广之用还是?请各位高手解答为什么没有上市,外面的介绍这么详细且正确呢? 详细如下:     亚马逊智能手机 编辑 ...
用户1711683 2014-05-05 06:56
云存储及反向控制(51buddy)
                 软硬开发工作总算在青年节全部完成,恭喜。恭喜。      成本非常低廉,硬件和软件支持(云服务器服务2年)大约在300元。    ...
用户1711683 2013-12-07 00:47
PSU 设计学习与探讨
       最近学习,老是感觉身边没有一个程控电源,在网络里找到开源的,查询淘宝没有看到有程控电源学习扳子卖,所以想做自己DIY,看到元器件不知道如何采购,本着学习原则,想先购一批回来,大概投入...
用户1711683 2013-12-03 17:59
上下拉电阻大小计算
            上下拉电阻大小计算,一直很困惑,这些大小计算来路,还恳请各位帮忙引导~~决定因子有那些.   ...
用户1711683 2013-12-03 17:59
LDO 电路中LC 计算来由
LC 电路相关属性计算来由,这些困惑小弟很久,还请各位帮忙引导,L 的阻抗大小跟什么有关系,及感抗,C的大小确定. ...
用户1711683 2013-12-02 11:35
0欧姆电阻学习
         如下为收集到的资料,可是没有实力,还是不能完全理解,还肯请各位帮忙提供具体例子,Buddy 兄在此谢各位了.   1,在电路中没有任何功能,只是在PCB上为了调试方便或兼...
EE直播间
更多
我要评论
3
19
关闭 站长推荐上一条 /3 下一条