This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

为什么检测电平后x=0x20;还有那个0x21如何判断K1按下的



#include "DSP2833x_Device.h"     // DSP2833x 头文件

#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

 

/**************************************宏定义************************************************/

#define  K0   0 //宏定义 K0为0

#define  K1   1 //宏定义

#define  K2   2 //宏定义

#define  K3   3 //宏定义

#define  K4   4 //宏定义

#define  K5   5 //宏定义

#define  K6   6 //宏定义

#define  K7   7 //宏定义

#define  K8   8 //宏定义

#define  K9   9 //宏定义

 

#define  AD   14   //宏定义+ 为14

#define  SB   15   //宏定义- 为15

 

#define  L_O_V_I()     EALLOW;                             \

                       GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; \

   GpioDataRegs.GPBDAT.bit.GPIO48 = 0; DELAY_US(1);\

                       GpioCtrlRegs.GPADIR.bit.GPIO24 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO24 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO25 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO25 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO26 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO26 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO21 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO21 = 0; DELAY_US(1);\

   \

   \

   GpioCtrlRegs.GPADIR.bit.GPIO27 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO27 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO20 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO20 = 0; DELAY_US(1);\

   EDIS;

#define  L_I_V_O()     EALLOW;                             \

                       GpioCtrlRegs.GPBDIR.bit.GPIO48 = 0; \

   GpioDataRegs.GPBDAT.bit.GPIO48 = 0; DELAY_US(1);\

                       GpioCtrlRegs.GPADIR.bit.GPIO24 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO24 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO25 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO25 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO26 = 0; \

   GpioDataRegs.GPADAT.bit.GPIO26 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO21 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO21 = 0; DELAY_US(1);\

   \

   \

   GpioCtrlRegs.GPADIR.bit.GPIO27 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO27 = 0; DELAY_US(1);\

   GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; \

   GpioDataRegs.GPADAT.bit.GPIO20 = 0; DELAY_US(1);\

   EDIS;   

//键盘列的GPIO宏定义

#define   V2 GpioDataRegs.GPADAT.bit.GPIO21  //宏定义

#define   V4 GpioDataRegs.GPADAT.bit.GPIO27  //宏定义

#define   V3 GpioDataRegs.GPADAT.bit.GPIO20  //宏定义

//键盘行的GPIO宏定义

#define   L1 GpioDataRegs.GPADAT.bit.GPIO26  //宏定义

#define   L2 GpioDataRegs.GPADAT.bit.GPIO25  //宏定义

#define   L3 GpioDataRegs.GPBDAT.bit.GPIO48  //宏定义

#define   L4 GpioDataRegs.GPADAT.bit.GPIO24  //宏定义

#define   uchar unsigned char  //宏定义

 

#define   LCD_DATA_BUS (*((volatile  Uint16 *)0x4000))  //宏定义LCD总线的地址

#define   EN GpioDataRegs.GPBDAT.bit.GPIO54  //宏定义

#define   RW GpioDataRegs.GPBDAT.bit.GPIO56  //宏定义

#define   RS GpioDataRegs.GPBDAT.bit.GPIO57  //宏定义

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

 

/**************************************变量定义************************************************/

uchar u = 0;

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

 

/**************************************函数声明************************************************/

void LCDInit(void);              //LCD初始化

void Write_order(Uint16 order);  //LCD写函数

void Write_data(Uint16 data);    //LCD写函数

void delay(Uint16 t);            //延时函数

void configio(void);             //LCD控制脚的GPIO配置

void InitXintf(void);            //总线初始化

void display(uchar *hz);         //显示函数

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

 

void LCD_DATA(uchar d) //把数据传给总线

{

    LCD_DATA_BUS = d;  //把要显示的值赋给总线

}

void LCDInit(void)  //LCD初始化

{

  DELAY_US(5000);

  Write_order(0x30);//功能设定:基本指令动作

  DELAY_US(50);     //延时

  Write_order(0x0c);//显示状态:开

  DELAY_US(50);     //延时

  Write_order(0x01);//清屏

  DELAY_US(60);     //延时

  Write_order(0x02);//地址归位:AC=0x00

  DELAY_US(40);     //延时

}

 

void Write_order(Uint16 order) //LCD12864写指令函数

{

   RS=0;delay(1);   //指令

   EN=1;delay(1);   //允许

   LCD_DATA(order); //赋值

   EN=0;delay(1);   //允许

}

 

void Write_data(Uint16 data)  //LCD12864写数据函数

{

   RS=1;delay(1);   //指令

   EN=1;delay(1);   //允许

   LCD_DATA(data);  //赋值

   EN=0;delay(1);   //允许

}

void delay(Uint16 t) //延时函数

{

   Uint16 i;         //定义变量

   while(t--)        //while循环

    {

      for(i=0;i<500;i++);//FOR循环

    }

}

 

void configio(void)  // LCD屏读写、使能和时钟GPIO配置

{

    EALLOW;

    GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 0; // GPIO复用为GPIO功能

    GpioCtrlRegs.GPBDIR.bit.GPIO54 = 1;  // GPIO设置为输出

    GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 0; // GPIO复用为GPIO功能

    GpioCtrlRegs.GPBDIR.bit.GPIO56 = 1;  // GPIO设置为输出

    GpioCtrlRegs.GPBMUX2.bit.GPIO57= 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPBDIR.bit.GPIO57 = 1;  // GPIO设置为输出

    EDIS;

}

 

void display(uchar *hz)  //显示函数

{

   while(*hz!='\0')      //While循环

    {

       Write_data(*hz);

       hz++;

       DELAY_US(250);    //延时

    }

}

 

Uint16 Scan_Button(void) //按键扫描程序

{

   Uint16 i=0, num=0xFFFF, x=0, y=0;  //定义变量

 

   i = V2&V3&V4;  //如果列读取到有低电平说明有按键按下

   if(i == 0)

   {

     DELAY_US(50);//延时消抖

     i = V2&V3&V4;

 if(i == 0)   //如果列读取到仍然有低电平说明有按键按下

 {

if(!V2) x= 0x20;         //V2低电平的时候值为0x20

if(!V3) x= 0x30;         //......

if(!V4) x= 0x40;         //......

L_I_V_O();               //行与列输入输出反转

if(!L2) y= 0x02;         //......

if(!L3) y= 0x03;         //......

if(!L4) y= 0x04;         //......

if(!L1) y= 0x01;         //......

x |= y;                  //X或上Y

        L_O_V_I();               //行与列输入输出反转

switch(x){

          case 0x21: num = K1;break;  //得出0x21判断K1按下

  case 0x22: num = K4;break;  //......

  case 0x23: num = SB;break;  //......

  case 0x24: num = K7;break;  //......

  case 0x31: num = K2;break;  //......

  case 0x32: num = K5;break;  //......

  case 0x33: num = K0;break;  //......

  case 0x34: num = K8;break;  //......

  case 0x41: num = K3;break;  //......

  case 0x42: num = K6;break;  //......

  case 0x43: num = AD;break;  //......

  case 0x44: num = K9;break;  //......

 

          default: num=0xFFFF;        //如果没有按键按下返回值0XFFFF

}

 

 }

   }

   return num;  //返回按键值

}

 

void Configio_Button(void)

{

    EALLOW;

    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0;  // GPIO复用为GPIO功能

    GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;  // GPIO复用为GPIO功能

    EDIS;

    L_O_V_I();               //行与列输入输出反转

}

 

/****************************************主程序******************************************************/

void main(void)

{

Uint16 start1=0x87;

// 初始化系统控制:

// 设置PLL, WatchDog, 使能外设时钟

// 下面这个函数可以从DSP2833x_SysCtrl.c文件中找到..

    InitSysCtrl();

// Xintf总线配置和初始化

    InitXintf();

    InitXintf16Gpio();

// 清除所有中断初始化中断向量表:

// 禁止CPU全局中断

    DINT;

// 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)

// 这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中

// 这个函数放在了DSP2833x_PieVect.c源文件里面.

    InitPieCtrl();

// 禁止CPU中断和清除所有CPU中断标志

    IER=0x0000;

    IFR=0x0000;

// 按键GPIO的配置

    Configio_Button();

// LCD屏读写、使能和时钟GPIO配置

    configio();

 

    RS=0;     //初始化RS电平

    delay(5); //延时

    RW=0;     //初始化RS电平

    delay(5); //延时

    EN=0;     //初始化RS电平

    LCDInit();//LCD初始化

    delay(5); //延时

    Write_order(0x80);//第一行数据指针地址

    delay(5); //延时

    display("您的按键值为:");  //显示固定语句

 

    while(1)

    {

      u = Scan_Button();//u等于按键扫描程序得出的值

      if( u != 0xFFFF )  //如果有按键按下,执行下面的操作

      {

        switch(u)

        {

  case K0: Write_order(start1);delay(5);display("0");break;  //K0键按下,LCD显示0

  case K1: Write_order(start1);delay(5);display("1");break;  //......

  case K2: Write_order(start1);delay(5);display("2");break;  //......

  case K3: Write_order(start1);delay(5);display("3");break;  //......

  case K4: Write_order(start1);delay(5);display("4");break;  //......

  case K5: Write_order(start1);delay(5);display("5");break;  //......

  case K6: Write_order(start1);delay(5);display("6");break;  //......

  case K7: Write_order(start1);delay(5);display("7");break;  //......

  case K8: Write_order(start1);delay(5);display("8");break;  //......

  case K9: Write_order(start1);delay(5);display("9");break;  //......

  case AD: Write_order(start1);delay(5);display("+");break;  //......

  case SB: Write_order(start1);delay(5);display("-");break;  //......

          default: break;                                            //没有按键按下跳出

}

  }

}

}