请选择 进入手机版 | 继续访问电脑版
查看: 177|回复: 1

[原创] 【LPC1768-DEV】⑤读按键值

[复制链接]
  • TA的每日心情
    慵懒
    昨天 08:46
  • 签到天数: 356 天

    [LV.8]以坛为家I

    10

    主题

    712

    帖子

    21

    金豆

    金牌会员

    Rank: 6Rank: 6

    积分
    1636
    最后登录
    2019-8-22
    发表于 2019-3-31 22:13:31 | 显示全部楼层 |阅读模式
    本帖最后由 yinwuqing 于 2019-3-31 22:17 编辑

         今天既是周末,也是月末。时间过得好快,平时工作比较忙,上班也是六休一,因此只有挤挤周末的时间来研究研究LPC1768这款工业级开发板。我们从之前的宝马LPC1768资料库中以及@管管给我们的sdk资料,我们可以得知按键板是使用PCA9555的i2c与LPC1768通信的。
    IRD Keypad.png Keypad简介.png
      原理图如下:
       Keypad原理图.png
      其实现的原理如下:
    原理.png
       按键时的结构映射如下图所示:
    Keypad结构映射.png
    按键解码的流程图如下所示:
    解码流程.png
         跟之前操作一样,新建一个工程,然后将微控制器软件接口标准库(CMSIS)勾选好。并在“RTE_Device.h”头文件中使能I2C接口。按键的键值可以在头文件的宏定义中自定义,工程中大部分代码如下:
    1. #include "LPC17xx.h"                    /* LPC17xx Definitions        */
    2. #include "GPIO_LPC17xx.h"
    3. #include "PIN_LPC17xx.h"
    4. #include "UART_LPC17xx.h"
    5. #include "I2C_LPC17xx.h"
    6. #include <string.h>
    7. #include <stdio.h>
    8. #include "keypad.h"

    9. typedef unsigned char UCHAR;

    10. UCHAR      Key_Flag;
    11. UCHAR      I2C_Read_Counter = 0;
    12. UCHAR      I2C_Write_Counter = 0;
    13. UCHAR      Keypad_Data_Read;
    14. UCHAR      Column_Value = 0;
    15. UCHAR      Row_Counter=0;
    16. UCHAR      Row_Found = 0;
    17. UCHAR      Row_Value;
    18. UCHAR      Brightness_Global=8;
    19. UCHAR      I2C_Data_Read_Buffer[2];
    20. UCHAR      I2C_Data_Write_Buffer[2];

    21. #define INTERNAL 0
    22. #define EXTERNAL 1

    23. #define KPAD_NB_ROW              6
    24. #define KPAD_NB_COLUMN           6

    25. /*Keypad defines*/
    26. #define P1_KPAD_COLUMN           0x3F     // 6 columns P1[0] to P1[5]
    27. #define P1_KPAD_COLUMN_MASK      0xC0
    28. #define P1_KPAD_ROW_OUT_REG      0xC0     // column configured as output
    29. #define P0_KPAD_ROW              0x3F     // 6 rows P0[0] to P0[5]

    30. #define P0_6_BACKLIGHT           0x40     // P0[6] used for backlight control
    31. #define P0_6_BACKLIGHT_OUT_REG   0xBF     // P0[6] configured as output
    32. #define P0_7_LED                 0x80     // P0[7] used for LED control
    33. #define P0_7_LED_OUT_REG         0x7F     // P0[7] configured as output
    34. #define P1_7_6_LED               0xC0     // P1[7:6] used for LED control
    35. #define P1_7_6_LED_OUT_REG       0x3F     // P1[7:6] configured as output

    36. /*---------------------------------------------------------------------------*
    37. * Constants & Macros:
    38. *---------------------------------------------------------------------------*/
    39. #define INSTR_CLEAR                 0x01                // 1.53 ms
    40. #define INSTR_RETURN_HOME(settings) 0x02                // 1.53 ms
    41. #define INSTR_ENTRY_MODE(settings)  (0x06|(settings))   // 39 uS
    42. #define IENTRY_INCREMENT            (1<<1)
    43. #define IENTRY_DECREMENT            (0<<1)
    44. #define IENTRY_SHIFT_ON             (1<<0)
    45. #define IENTRY_SHIFT_OFF            (0<<0)

    46. #define INSTR_DISPLAY(settings)     (0x08|(settings))   // 39 uS
    47. #define IDISPLAY_ON                 (1<<2)
    48. #define IDISPLAY_OFF                (0<<2)
    49. #define IDISPLAY_CURSOR_ON          (1<<1)
    50. #define IDISPLAY_CURSOR_OFF         (0<<1)
    51. #define IDISPLAY_BLINK_ON           (1<<0)
    52. #define IDISPLAY_BLINK_OFF          (0<<0)

    53. #define INSTR_SHIFT(settings)       (0x10|(settings))   // 39 uS
    54. #define ISHIFT_SCREEN               (1<<3)
    55. #define ISHIFT_CURSOR               (0<<3)
    56. #define ISHIFT_RIGHT                (1<<2)
    57. #define ISHIFT_LEFT                 (0<<2)

    58. #define INSTR_FUNC(settings)        (0x20|(settings))   // 39 uS
    59. #define IFUNC_8BIT                  (1<<4)
    60. #define IFUNC_4BIT                  (0<<4)
    61. #define IFUNC_TWO_LINE              (1<<3)
    62. #define IFUNC_ONE_LINE              (0<<3)
    63. #define IFUNC_DISPLAY_ON            (1<<2)
    64. #define IFUNC_DISPLAY_OFF           (0<<2)

    65. #define INSTR_SET_CGRAM_ADDR(x)      (0x40|((x)&0x3F))   // 39 uS
    66. #define INSTR_SET_DDRAM_ADDR(x)      (0x80|((x)&0x7F))   // 39 uS
    67. #define LUMEX_SO2004DSR_NUM_COLUMNS   20
    68. #define LUMEX_SO2004DSR_NUM_ROWS      4

    69. #define LED_PORT 0
    70. #define LED_PIN  7
    71. #define PCA9555D_I2C_ADDR  0x40>>1   //IICÈ¡7λµØÖ·£¬ËùÒÔÐèÒªÓÒÒÆһλ
    72. #define PROGRAM_KEYPAD_GREEN_LED_ON         0x01  // Exercise 2: actual value to be found
    73. #define PROGRAM_KEYPAD_GREEN_LED_OFF        0x00  // Exercise 2: actual value to be found
    74. UCHAR F4_Flag = 0;
    75. uint32_t LEDOn, LEDOff;
    76. uint32_t uTimeCnt=0;

    77. /* I2C driver instance */
    78. extern ARM_DRIVER_I2C            Driver_I2C0;  
    79. static ARM_DRIVER_I2C *I2Cdrv = &Driver_I2C0;

    80. struct LPC_PORT
    81. {
    82.         uint32_t uPort;
    83.         uint32_t uPin;
    84. };
    85. /*********************************************************************************************************
    86. * Keypad_Write()
    87. *
    88. * Description : Function to write to the Keypad Controller (PCA9555)
    89. *
    90. * Argument(s) : Address of the register to be accessed and data to write to that register
    91. *
    92. * Return(s)   : none.
    93. *********************************************************************************************************/
    94. void Keypad_Write(UCHAR Reg_Ptr, UCHAR Data_Write)
    95. {
    96.     I2C_Data_Write_Buffer[0] = Reg_Ptr;
    97.     I2C_Data_Write_Buffer[1] = Data_Write;
    98.     I2Cdrv->MasterTransmit (PCA9555D_I2C_ADDR, I2C_Data_Write_Buffer, 2, false);  
    99.     while (I2Cdrv->GetStatus().busy);
    100. }
    101. /*********************************************************************************************************
    102. * Keypad_Read()
    103. *
    104. * Description : Function to read from the Keypad Controller (PCA9555)
    105. *
    106. * Argument(s) : Address of the register to be accessed and data to be read from that register
    107. *
    108. * Return(s)   : none.
    109. *********************************************************************************************************/
    110. UCHAR Keypad_Read(void)
    111. {
    112.         I2Cdrv->MasterTransmit (PCA9555D_I2C_ADDR, I2C_Data_Read_Buffer, 1, true);  
    113.         while (I2Cdrv->GetStatus().busy){;}
    114.         I2Cdrv->MasterReceive (PCA9555D_I2C_ADDR, &I2C_Data_Read_Buffer[1], 1, false);  //»ñÈ¡µØÖ·ÉϵÄÊý¾Ý
    115.         while (I2Cdrv->GetStatus().busy){;}
    116.         //I2C_ReadReg(PCA9555_ADDRESS, I2C_Data_Read_Buffer,1,0);
    117.   return I2C_Data_Read_Buffer[1];
    118. }

    119. /*********************************************************************************************************
    120. * Keypad_Init()
    121. *
    122. * Description : Initialize the Keypad Controller (PCA9555)
    123. *               Registers to be written:
    124. *               0x02:   Program Port 0    (MSB = 0.7 - LSB = 0.0) ; 0: Port = 0         1: Port = 1
    125. *               0x03:   Program Port 1    (MSB = 1.7 - LSB = 1.0) ; 0: Port = 0         1: Port = 1
    126. *               0x06:   Configure Port 0  (MSB = 0.7 - LSB = 0.0) ; 0: Port = output    1: Port = input
    127. *               0x07:   Configure Port 1  (MSB = 1.7 - LSB = 1.0) ; 0: Port = output    1: Port = input
    128. * Argument(s) : none.
    129. *
    130. * Return(s)   : none.
    131. *********************************************************************************************************/
    132. void Keypad_Init(void)
    133. {
    134.     Keypad_Write(0x06, P0_7_LED_OUT_REG & P0_6_BACKLIGHT_OUT_REG);    // Program output port 0  7F&BF 01111111&10111111=00111111  1 is input;
    135.     Keypad_Write(0x07, P1_7_6_LED_OUT_REG & P1_KPAD_ROW_OUT_REG);     // Program output port 1  3F&C0 00111111&11000000=00000000  all is output
    136.     Keypad_Write(0x03,0xC0);                                          // Program Port1 - LEDs off and Kpad Column = 0
    137. }

    138. /*********************************************************************************************************
    139. * Decode_Column()
    140. *
    141. * Description : Decode the column of the pressed key
    142. *               Input Register has been read in UCHAR KeypadCheck(void) in app_keyboard.c
    143. *
    144. * Argument(s) : none.
    145. *
    146. * Return(s)   : none.
    147. *********************************************************************************************************/
    148. void Decode_Column(void)
    149. {
    150.     I2C_Read_Counter+=1;
    151. /* Check value of the PCA9555's Input Register and store Column value accordingly */
    152.     switch (Keypad_Data_Read | P1_KPAD_COLUMN_MASK)  
    153.       {
    154.         case 0xFE:  Column_Value = 0;
    155.                     break;
    156.         case 0xFD:  Column_Value = 1;
    157.                     break;
    158.         case 0xFB:  Column_Value = 2;
    159.                     break;
    160.         case 0xF7:  Column_Value = 3;
    161.                     break;
    162.         case 0xEF:  Column_Value = 4;
    163.                     break;
    164.         case 0xDF:  Column_Value = 5;
    165.                     break;
    166.         default:    break;
    167.     }
    168. }

    169. /*********************************************************************************************************
    170. * Decode_Row()
    171. *
    172. * Description : Decode the row of the pressed key
    173. *
    174. * Argument(s) : none.
    175. *
    176. * Return(s)   : none.
    177. **********************************************************************************************/
    178. void Decode_Row(void)
    179. {
    180.     UCHAR Keypad_Data_Read;
    181.     UCHAR Keypad_Data_Read_Masked;
    182.     Row_Counter = 0;
    183.     I2C_Write_Counter=0;
    184.     I2C_Read_Counter=0;
    185.     Row_Found=0;
    186. /*Perform the loop to check ALL the rows (0 to 5) - Write to the Output register accordingly */
    187.     do   
    188.     {
    189.       if (Row_Counter == 0)
    190.       {
    191.         Keypad_Write(0x03,0xFE);
    192.       }
    193.       if (Row_Counter == 1)
    194.       {
    195.         Keypad_Write(0x03,0xFC);
    196.       }      
    197.       if (Row_Counter == 2)
    198.       {
    199.         Keypad_Write(0x03,0xF8);
    200.       }
    201.       if (Row_Counter == 3)
    202.       {
    203.         Keypad_Write(0x03,0xF0);
    204.       }     
    205.       if (Row_Counter == 4)
    206.       {
    207.         Keypad_Write(0x03,0xE0);
    208.       }
    209.       if (Row_Counter == 5)
    210.       {
    211.         Keypad_Write(0x03,0xC0);
    212.       }         
    213.       
    214.       I2C_Write_Counter+=1;
    215.                         
    216.         I2C_Data_Read_Buffer[0]=0;            
    217.         I2C_Data_Read_Buffer[1]=0;
    218.       Keypad_Data_Read = Keypad_Read(); // Read Input Register
    219.   
    220.       I2C_Read_Counter+=1;
    221.       Keypad_Data_Read_Masked = Keypad_Data_Read | P1_KPAD_COLUMN_MASK;
    222.       if (Keypad_Data_Read_Masked != 0xFF)  // Check if Read Data is different from 0xFF = Row has been found when no 0xFF
    223.       {
    224.         if (Row_Found == 0)
    225.         {
    226.           Row_Value = Row_Counter;  // Store Row Value
    227.           Row_Found = 1;
    228.         }
    229.       }
    230.       Row_Counter+=1;
    231.     } while (Row_Counter <= KPAD_NB_ROW-1);
    232. }

    233. /*********************************************************************************************************
    234. * Keypad_Map()
    235. *
    236. * Description : Map the Row and Column values found in Decode_Row() and Decode_Column() to a specific key
    237. *
    238. * Argument(s) : none.
    239. *
    240. * Return(s)   : Pressed Key.
    241. *********************************************************************************************************/
    242. UCHAR Keypad_Map(void)
    243. {
    244.   UCHAR lKey = 0;
    245.   if (Column_Value == 5)
    246.   {
    247.     if (Row_Value == 0)       lKey = KEY_F4;
    248.     else if (Row_Value == 1)  lKey = KEY_ARW_UP;
    249.     else if (Row_Value == 2)  lKey = KEY_PLUS;
    250.     else if (Row_Value == 3)  lKey = KEY_F3;
    251.     else if (Row_Value == 4)  lKey = KEY_F2;
    252.                 else if (Row_Value == 5)  lKey = KEY_F1;
    253.   }
    254.   else if (Column_Value == 4)
    255.   {
    256.     if (Row_Value == 0)       lKey = KEY_MENU;
    257.     else if (Row_Value == 1)  lKey = KEY_ARW_DN;
    258.                 else if (Row_Value == 2)  lKey = KEY_MINUS;
    259.     else if (Row_Value == 3)  lKey = KEY_ARW_RT;
    260.     else if (Row_Value == 4)  lKey = KEY_OK;
    261.     else if (Row_Value == 5)  lKey = KEY_ARW_LT;
    262.   }
    263.   else if (Column_Value == 3)
    264.   {
    265.     if (Row_Value == 0)       lKey = KEY_ERROR;
    266.     else if (Row_Value == 1)  lKey = KEY_3;
    267.     else if (Row_Value == 2)  lKey = KEY_2;
    268.     else if (Row_Value == 3)  lKey = KEY_1;
    269.                 else if (Row_Value == 4)  lKey = KEY_CLEAR;
    270.     else if (Row_Value == 5)  lKey = KEY_SEND;
    271.   }
    272.   else if (Column_Value == 2)
    273.   {
    274.     if (Row_Value == 0)       lKey = KEY_ERROR;
    275.     else if (Row_Value == 1)  lKey = KEY_ERROR;
    276.     else if (Row_Value == 2)  lKey = KEY_7;
    277.     else if (Row_Value == 3)  lKey = KEY_6;
    278.     else if (Row_Value == 4)  lKey = KEY_5;
    279.     else if (Row_Value == 5)  lKey = KEY_4;
    280.   }
    281.   else if (Column_Value == 1)
    282.   {
    283.     if (Row_Value == 0)       lKey = KEY_ERROR;
    284.                 else if (Row_Value == 1)  lKey = KEY_POUND;
    285.     else if (Row_Value == 2)  lKey = KEY_0;
    286.                 else if (Row_Value == 3)  lKey = KEY_ASTERISK;
    287.     else if (Row_Value == 4)  lKey = KEY_9;
    288.     else if (Row_Value == 5)  lKey = KEY_8;
    289.   }
    290.   else if (Column_Value == 0)
    291.   {
    292.     lKey = KEY_END;
    293.   }
    294.   return lKey;
    295. }

    296. /*********************************************************************************************************
    297. * Keypad_Decoder()
    298. *
    299. * Description : Keypad_Decoder Function
    300. *               1) Decode the column               
    301. *               2) Decode the row                  
    302. *               3) Map the coordinate to a key
    303. *
    304. * Argument(s) : none.
    305. *
    306. * Return(s)   : Pressed Key.
    307. *********************************************************************************************************/
    308. UCHAR Keypad_Decoder (void)
    309. {
    310.   Decode_Column();
    311.   Decode_Row();
    312.   return Keypad_Map();
    313. }

    314. /*----------------------------------------------------------------------------
    315.   SysTick IRQ Handler
    316. *----------------------------------------------------------------------------*/
    317. void SysTick_Handler (void)
    318. {  
    319.         uTimeCnt++;
    320. }
    321. /* Initialize I2C connected SA56004 */
    322. int32_t PCA9555D_Initialize (void)
    323. {
    324.   I2Cdrv->Initialize (NULL);
    325.   I2Cdrv->PowerControl (ARM_POWER_FULL);
    326.   I2Cdrv->Control      (ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);  
    327.   I2Cdrv->Control      (ARM_I2C_BUS_CLEAR, 0);
    328.   return 1;
    329. }

    330. int32_t Delayms(uint32_t ms)
    331. {  
    332.         uTimeCnt=0;
    333.         while(uTimeCnt<ms){};
    334.         return 0;
    335. }

    336. int32_t LED_Initialize (void)
    337. {
    338.   /* Enable GPIO clock */
    339.   GPIO_PortClock     (1);
    340.   /* Configure pins: Output Mode with Pull-down resistors */
    341.   PIN_Configure (LED_PORT, LED_PIN, PIN_FUNC_0, PIN_PINMODE_PULLDOWN, PIN_PINMODE_NORMAL);
    342.   GPIO_SetDir   (LED_PORT, LED_PIN, GPIO_DIR_OUTPUT);
    343.   GPIO_PinWrite (LED_PORT, LED_PIN, 0);

    344.   return 0;
    345. }
    复制代码
    主函数如下:
    1. /*----------------------------------------------------------------------------
    2.   Main function
    3. *----------------------------------------------------------------------------*/
    4. int main (void)
    5. {
    6.         char buff[40];
    7.         uint8_t uLedState=0;
    8.         UCHAR keypadval=0;
    9.         SystemCoreClockUpdate ();                 /* Update system core clock       */  
    10.         SysTick_Config(SystemCoreClock/1000);     /* Generate interrupt each 1 ms  */
    11.         LED_Initialize();                         /* LED Initialization             */
    12.         PCA9555D_Initialize();
    13.         Keypad_Init();                                          
    14.         LCD_Init();
    15.         LCD_WR_Str("Welcome used LPC1768");
    16.         while (1)
    17.         {
    18.                 I2C_Data_Read_Buffer[0]=0;                  
    19.                 I2C_Data_Read_Buffer[1]=0;
    20.                
    21.                 Keypad_Data_Read=Keypad_Read();         
    22.                
    23.                 if((Keypad_Data_Read|P1_KPAD_COLUMN_MASK)!=0xFF)
    24.                 {
    25.                   keypadval=Keypad_Decoder();
    26.                   sprintf(buff,"CurKeypad value:%d",keypadval);
    27.                   LCD_Set_RowCol(0,2);
    28.                   LCD_WR_Str(buff);
    29.                 }else
    30.                 {
    31.                   memset(buff,0,sizeof(buff));
    32.                   sprintf(buff,"No Key Pressed!    ");
    33.                   LCD_Set_RowCol(0,2);
    34.                   LCD_WR_Str(buff);
    35.                 }
    36.                 GPIO_PinWrite(LED_PORT, LED_PIN, uLedState);        /* Turn specified LED off   */
    37.                 uLedState=!uLedState;
    38.                 Delayms(100);        
    39.           }
    40. }
    复制代码
    本次实现按下键时获取对应键值的结果如下所示:
    演示效果.gif

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2019-5-1 06:15
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    0

    主题

    91

    帖子

    0

    金豆

    中级会员

    Rank: 3Rank: 3

    积分
    201
    最后登录
    2019-5-1
    发表于 2019-4-30 10:31:20 | 显示全部楼层
    谢谢分享
    开心!!!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|恩智浦技术社区

    GMT+8, 2019-8-23 08:08 , Processed in 0.093853 second(s), 14 queries , MemCache On.

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表