⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 键盘扫描的程序 经过调试后的 应用的为行列式的模式 应用单片机的端口中断
💻 C
字号:
#include "Key.h"
#include "Lcd.h"


#ifdef _USE_KEYPAD

KEYBUFF m_KB;

/*
*************************************************************************************
*                             键盘处理部分
*/
//将缓冲区中填满保留字
void ResetKey()
{
    char i;
    P1IE &= 0xC0;//中断禁止
    for (i=0;i<KEYBUFFERLEN;i++)
    {
        //初始化键盘缓冲区
        m_KB.KeyBuff[i] = KEYNO;
    }
    m_KB.cKHead = 0;
    m_KB.cKTail = 0;
    P1IE |= 0X3F;  //中断允许
}
/*
*************************************************************************************
*描述:键盘控制和数据结构初始化数据
*参数:无
*************************************************************************************
*/
void Init_Key()
{
    //端口设置,PORT1 为键盘接口,允许中断
    //P1.4~P1.7已经上拉
    char i;
    for (i=0;i<KEYBUFFERLEN;i++)
    {
        //初始化键盘缓冲区
        m_KB.KeyBuff[i] = KEYNO;
    }
    m_KB.cKHead = 0;
    m_KB.cKTail = 0;

    P2OUT &= 0xF0;         //将低4位置低
    P2DIR |= 0x0F;         //p2口的p1.0~p1.3,为输出状态
    P1DIR &= 0xC0;         //p1.0~p1.5 键盘扫描输入,P1.6无用
    P1OUT &= 0x7F;         //P1.7 buz 置低
    P1IES |= 0X3F;         //设置下降沿产生中断
    P1IE  |= 0X3F;         //P1.0~P1.5中断允许
}

/*
*************************************************************************************
*描述: 从键盘缓冲区读取键盘值
*参数: 
*说明:  返回值是读取的键盘值
*        [0  1  2 ....   L-1]  (L is KeyBufer length)
*         H=T                  (Initialization, H is cKHead, T is cKTail)
*         if a key is pressed H+1
*         if a key is read T+1  
*         if T>= H no key in buffer
*         if T+1-L = H  no key in buffer
*************************************************************************************
*/
char  GetKey()   //得到按键的值
{
    char akey = KEYNO;
    P1IE &= 0xC0;
    if (m_KB.cKTail!=m_KB.cKHead) 
    {
        akey = m_KB.KeyBuff[m_KB.cKTail];
        m_KB.cKTail++;
        if (m_KB.cKTail>=KEYBUFFERLEN) m_KB.cKTail = 0;
    }
    P1IE |= 0X3F;                                    //中断允许
    return  akey;
}

/*
*************************************************************************************
*描述: 在键盘缓冲区读取位置插入键盘值
*参数: key 为要插入的值
*说明:  
*************************************************************************************
*/
void  InsertKey(char key)
{
    P1IE &= 0xC0;
    if (m_KB.cKTail ==0) m_KB.cKTail = KEYBUFFERLEN-1;
    else --m_KB.cKTail;
    m_KB.KeyBuff[m_KB.cKTail] = key;
    P1IE |= 0X3F;                                    //中断允许
}

/*
*************************************************************************************
*描述: 在键盘缓冲区末尾插入键盘值
*参数: key 为要插入的值
*说明:  
*************************************************************************************
*/
void  AddKey(char key)
{
    P1IE &= 0xC0;
    m_KB.KeyBuff[m_KB.cKHead++] = key;
    if (m_KB.cKHead>=KEYBUFFERLEN)  m_KB.cKHead = 0;
    P1IE |= 0X3F;                                    //中断允许
}

// Port1 用于键盘控制
const char KeyCode[KEYROWS][KEYCOLS] = {//键盘码映射
  {KEYNUM1,KEYNUM2,KEYNUM3,KEYF4},//row1
  {KEYNUM4,KEYNUM5,KEYNUM6,KEYF5},//row2
  {KEYNUM7,KEYNUM8,KEYNUM9,KEYF6},//row3
  {KEYSTAR,KEYNUM0,KEYWELL,KEYF7},//row4  
  {KEYF1  ,KEYF2  ,KEYF3  ,KEYF8},//row5  
  {KEYPLUS,KEYPLUS,KEYPLUS,KEYPLUS}//row6  
  };

uchar scan_col(uchar bit)
{
    uchar col=0;
    
    P2OUT = 0xFE;                                 //p2.0 置0 
    _NOP();_NOP();_NOP();_NOP();
    if((P1IN & bit)!=bit)
        col = 1;
    else
    {  
        P2OUT = 0xFD;                             //p2.1 置0 
        _NOP();_NOP();_NOP();_NOP();
        if((P1IN & bit)!=bit)
            col = 2;
        else
        {
            P2OUT = 0xFB;                          //p2.2 置0 
            _NOP();_NOP();_NOP();_NOP();
            if((P1IN & bit)!=bit)
                col = 3;
            else
            {
                P2OUT = 0xF7;                      //p2.3 置0 
                _NOP();_NOP();_NOP();_NOP();
                if((P1IN & bit)!=bit)
                {
                    col = 4;
                }
            }
        }
    }
    P2OUT &= 0xF0; 
    return (col);
}

#pragma vector=PORT1_VECTOR
__interrupt  void KeyInterrupt(void)
{
    char row=0,col=0;
    Lcd_LightOn();            //打开背光
    P1IE &= 0xC0;            //屏蔽键盘中断 
    if (P1IFG&0x01)
    {
        row = 1;
        col = scan_col(BIT0);
    }
    else if (P1IFG&0x02)
    {
        row = 2;
        col = scan_col(BIT1);
    }
    else if (P1IFG&0x04)
    {
        row = 3;
        col = scan_col(BIT2);
    }
    else if (P1IFG&0x08)
    {
        row = 4;
        col = scan_col(BIT3);
    }
    else if (P1IFG&0x10)
    {
        row = 5;
        col = scan_col(BIT4);
    }
    else if (P1IFG&0x20)
    {
        row = 6;
        col = 1;
    }
    if (col && row) //如果水平序列的值和垂直序列的值都不为0的情况。则说明按键有效
    {
        m_KB.KeyBuff[m_KB.cKHead++] = KeyCode[row-1][col-1];
        if (m_KB.cKHead>=KEYBUFFERLEN)  m_KB.cKHead = 0;
    }
    P1IFG &= 0xC0;                                  //清除中断标示
    P1IE  |= 0x3F;                                  //中断允许
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -