在线时间970 小时
UID1694538
注册时间2018-5-21
NXP金币1950
TA的每日心情 | 奋斗 19 小时前 |
---|
签到天数: 1995 天 [LV.Master]伴坛终老
金牌会员
- 积分
- 11870
- 最后登录
- 2024-4-19
|
本帖最后由 yinwuqing 于 2019-3-31 22:17 编辑
今天既是周末,也是月末。时间过得好快,平时工作比较忙,上班也是六休一,因此只有挤挤周末的时间来研究研究LPC1768这款工业级开发板。我们从之前的宝马LPC1768资料库中以及@管管给我们的sdk资料,我们可以得知按键板是使用PCA9555的i2c与LPC1768通信的。
原理图如下:
其实现的原理如下:
按键时的结构映射如下图所示:
按键解码的流程图如下所示:
跟之前操作一样,新建一个工程,然后将微控制器软件接口标准库(CMSIS)勾选好。并在“RTE_Device.h”头文件中使能I2C接口。按键的键值可以在头文件的宏定义中自定义,工程中大部分代码如下:
- #include "LPC17xx.h" /* LPC17xx Definitions */
- #include "GPIO_LPC17xx.h"
- #include "PIN_LPC17xx.h"
- #include "UART_LPC17xx.h"
- #include "I2C_LPC17xx.h"
- #include <string.h>
- #include <stdio.h>
- #include "keypad.h"
- typedef unsigned char UCHAR;
- UCHAR Key_Flag;
- UCHAR I2C_Read_Counter = 0;
- UCHAR I2C_Write_Counter = 0;
- UCHAR Keypad_Data_Read;
- UCHAR Column_Value = 0;
- UCHAR Row_Counter=0;
- UCHAR Row_Found = 0;
- UCHAR Row_Value;
- UCHAR Brightness_Global=8;
- UCHAR I2C_Data_Read_Buffer[2];
- UCHAR I2C_Data_Write_Buffer[2];
- #define INTERNAL 0
- #define EXTERNAL 1
- #define KPAD_NB_ROW 6
- #define KPAD_NB_COLUMN 6
- /*Keypad defines*/
- #define P1_KPAD_COLUMN 0x3F // 6 columns P1[0] to P1[5]
- #define P1_KPAD_COLUMN_MASK 0xC0
- #define P1_KPAD_ROW_OUT_REG 0xC0 // column configured as output
- #define P0_KPAD_ROW 0x3F // 6 rows P0[0] to P0[5]
- #define P0_6_BACKLIGHT 0x40 // P0[6] used for backlight control
- #define P0_6_BACKLIGHT_OUT_REG 0xBF // P0[6] configured as output
- #define P0_7_LED 0x80 // P0[7] used for LED control
- #define P0_7_LED_OUT_REG 0x7F // P0[7] configured as output
- #define P1_7_6_LED 0xC0 // P1[7:6] used for LED control
- #define P1_7_6_LED_OUT_REG 0x3F // P1[7:6] configured as output
- /*---------------------------------------------------------------------------*
- * Constants & Macros:
- *---------------------------------------------------------------------------*/
- #define INSTR_CLEAR 0x01 // 1.53 ms
- #define INSTR_RETURN_HOME(settings) 0x02 // 1.53 ms
- #define INSTR_ENTRY_MODE(settings) (0x06|(settings)) // 39 uS
- #define IENTRY_INCREMENT (1<<1)
- #define IENTRY_DECREMENT (0<<1)
- #define IENTRY_SHIFT_ON (1<<0)
- #define IENTRY_SHIFT_OFF (0<<0)
- #define INSTR_DISPLAY(settings) (0x08|(settings)) // 39 uS
- #define IDISPLAY_ON (1<<2)
- #define IDISPLAY_OFF (0<<2)
- #define IDISPLAY_CURSOR_ON (1<<1)
- #define IDISPLAY_CURSOR_OFF (0<<1)
- #define IDISPLAY_BLINK_ON (1<<0)
- #define IDISPLAY_BLINK_OFF (0<<0)
- #define INSTR_SHIFT(settings) (0x10|(settings)) // 39 uS
- #define ISHIFT_SCREEN (1<<3)
- #define ISHIFT_CURSOR (0<<3)
- #define ISHIFT_RIGHT (1<<2)
- #define ISHIFT_LEFT (0<<2)
- #define INSTR_FUNC(settings) (0x20|(settings)) // 39 uS
- #define IFUNC_8BIT (1<<4)
- #define IFUNC_4BIT (0<<4)
- #define IFUNC_TWO_LINE (1<<3)
- #define IFUNC_ONE_LINE (0<<3)
- #define IFUNC_DISPLAY_ON (1<<2)
- #define IFUNC_DISPLAY_OFF (0<<2)
- #define INSTR_SET_CGRAM_ADDR(x) (0x40|((x)&0x3F)) // 39 uS
- #define INSTR_SET_DDRAM_ADDR(x) (0x80|((x)&0x7F)) // 39 uS
- #define LUMEX_SO2004DSR_NUM_COLUMNS 20
- #define LUMEX_SO2004DSR_NUM_ROWS 4
- #define LED_PORT 0
- #define LED_PIN 7
- #define PCA9555D_I2C_ADDR 0x40>>1 //IICÈ¡7λµØÖ·£¬ËùÒÔÐèÒªÓÒÒÆһλ
- #define PROGRAM_KEYPAD_GREEN_LED_ON 0x01 // Exercise 2: actual value to be found
- #define PROGRAM_KEYPAD_GREEN_LED_OFF 0x00 // Exercise 2: actual value to be found
- UCHAR F4_Flag = 0;
- uint32_t LEDOn, LEDOff;
- uint32_t uTimeCnt=0;
- /* I2C driver instance */
- extern ARM_DRIVER_I2C Driver_I2C0;
- static ARM_DRIVER_I2C *I2Cdrv = &Driver_I2C0;
- struct LPC_PORT
- {
- uint32_t uPort;
- uint32_t uPin;
- };
- /*********************************************************************************************************
- * Keypad_Write()
- *
- * Description : Function to write to the Keypad Controller (PCA9555)
- *
- * Argument(s) : Address of the register to be accessed and data to write to that register
- *
- * Return(s) : none.
- *********************************************************************************************************/
- void Keypad_Write(UCHAR Reg_Ptr, UCHAR Data_Write)
- {
- I2C_Data_Write_Buffer[0] = Reg_Ptr;
- I2C_Data_Write_Buffer[1] = Data_Write;
- I2Cdrv->MasterTransmit (PCA9555D_I2C_ADDR, I2C_Data_Write_Buffer, 2, false);
- while (I2Cdrv->GetStatus().busy);
- }
- /*********************************************************************************************************
- * Keypad_Read()
- *
- * Description : Function to read from the Keypad Controller (PCA9555)
- *
- * Argument(s) : Address of the register to be accessed and data to be read from that register
- *
- * Return(s) : none.
- *********************************************************************************************************/
- UCHAR Keypad_Read(void)
- {
- I2Cdrv->MasterTransmit (PCA9555D_I2C_ADDR, I2C_Data_Read_Buffer, 1, true);
- while (I2Cdrv->GetStatus().busy){;}
- I2Cdrv->MasterReceive (PCA9555D_I2C_ADDR, &I2C_Data_Read_Buffer[1], 1, false); //»ñÈ¡µØÖ·ÉϵÄÊý¾Ý
- while (I2Cdrv->GetStatus().busy){;}
- //I2C_ReadReg(PCA9555_ADDRESS, I2C_Data_Read_Buffer,1,0);
- return I2C_Data_Read_Buffer[1];
- }
- /*********************************************************************************************************
- * Keypad_Init()
- *
- * Description : Initialize the Keypad Controller (PCA9555)
- * Registers to be written:
- * 0x02: Program Port 0 (MSB = 0.7 - LSB = 0.0) ; 0: Port = 0 1: Port = 1
- * 0x03: Program Port 1 (MSB = 1.7 - LSB = 1.0) ; 0: Port = 0 1: Port = 1
- * 0x06: Configure Port 0 (MSB = 0.7 - LSB = 0.0) ; 0: Port = output 1: Port = input
- * 0x07: Configure Port 1 (MSB = 1.7 - LSB = 1.0) ; 0: Port = output 1: Port = input
- * Argument(s) : none.
- *
- * Return(s) : none.
- *********************************************************************************************************/
- void Keypad_Init(void)
- {
- 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;
- 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
- Keypad_Write(0x03,0xC0); // Program Port1 - LEDs off and Kpad Column = 0
- }
- /*********************************************************************************************************
- * Decode_Column()
- *
- * Description : Decode the column of the pressed key
- * Input Register has been read in UCHAR KeypadCheck(void) in app_keyboard.c
- *
- * Argument(s) : none.
- *
- * Return(s) : none.
- *********************************************************************************************************/
- void Decode_Column(void)
- {
- I2C_Read_Counter+=1;
- /* Check value of the PCA9555's Input Register and store Column value accordingly */
- switch (Keypad_Data_Read | P1_KPAD_COLUMN_MASK)
- {
- case 0xFE: Column_Value = 0;
- break;
- case 0xFD: Column_Value = 1;
- break;
- case 0xFB: Column_Value = 2;
- break;
- case 0xF7: Column_Value = 3;
- break;
- case 0xEF: Column_Value = 4;
- break;
- case 0xDF: Column_Value = 5;
- break;
- default: break;
- }
- }
- /*********************************************************************************************************
- * Decode_Row()
- *
- * Description : Decode the row of the pressed key
- *
- * Argument(s) : none.
- *
- * Return(s) : none.
- **********************************************************************************************/
- void Decode_Row(void)
- {
- UCHAR Keypad_Data_Read;
- UCHAR Keypad_Data_Read_Masked;
- Row_Counter = 0;
- I2C_Write_Counter=0;
- I2C_Read_Counter=0;
- Row_Found=0;
- /*Perform the loop to check ALL the rows (0 to 5) - Write to the Output register accordingly */
- do
- {
- if (Row_Counter == 0)
- {
- Keypad_Write(0x03,0xFE);
- }
- if (Row_Counter == 1)
- {
- Keypad_Write(0x03,0xFC);
- }
- if (Row_Counter == 2)
- {
- Keypad_Write(0x03,0xF8);
- }
- if (Row_Counter == 3)
- {
- Keypad_Write(0x03,0xF0);
- }
- if (Row_Counter == 4)
- {
- Keypad_Write(0x03,0xE0);
- }
- if (Row_Counter == 5)
- {
- Keypad_Write(0x03,0xC0);
- }
-
- I2C_Write_Counter+=1;
-
- I2C_Data_Read_Buffer[0]=0;
- I2C_Data_Read_Buffer[1]=0;
- Keypad_Data_Read = Keypad_Read(); // Read Input Register
-
- I2C_Read_Counter+=1;
- Keypad_Data_Read_Masked = Keypad_Data_Read | P1_KPAD_COLUMN_MASK;
- if (Keypad_Data_Read_Masked != 0xFF) // Check if Read Data is different from 0xFF = Row has been found when no 0xFF
- {
- if (Row_Found == 0)
- {
- Row_Value = Row_Counter; // Store Row Value
- Row_Found = 1;
- }
- }
- Row_Counter+=1;
- } while (Row_Counter <= KPAD_NB_ROW-1);
- }
- /*********************************************************************************************************
- * Keypad_Map()
- *
- * Description : Map the Row and Column values found in Decode_Row() and Decode_Column() to a specific key
- *
- * Argument(s) : none.
- *
- * Return(s) : Pressed Key.
- *********************************************************************************************************/
- UCHAR Keypad_Map(void)
- {
- UCHAR lKey = 0;
- if (Column_Value == 5)
- {
- if (Row_Value == 0) lKey = KEY_F4;
- else if (Row_Value == 1) lKey = KEY_ARW_UP;
- else if (Row_Value == 2) lKey = KEY_PLUS;
- else if (Row_Value == 3) lKey = KEY_F3;
- else if (Row_Value == 4) lKey = KEY_F2;
- else if (Row_Value == 5) lKey = KEY_F1;
- }
- else if (Column_Value == 4)
- {
- if (Row_Value == 0) lKey = KEY_MENU;
- else if (Row_Value == 1) lKey = KEY_ARW_DN;
- else if (Row_Value == 2) lKey = KEY_MINUS;
- else if (Row_Value == 3) lKey = KEY_ARW_RT;
- else if (Row_Value == 4) lKey = KEY_OK;
- else if (Row_Value == 5) lKey = KEY_ARW_LT;
- }
- else if (Column_Value == 3)
- {
- if (Row_Value == 0) lKey = KEY_ERROR;
- else if (Row_Value == 1) lKey = KEY_3;
- else if (Row_Value == 2) lKey = KEY_2;
- else if (Row_Value == 3) lKey = KEY_1;
- else if (Row_Value == 4) lKey = KEY_CLEAR;
- else if (Row_Value == 5) lKey = KEY_SEND;
- }
- else if (Column_Value == 2)
- {
- if (Row_Value == 0) lKey = KEY_ERROR;
- else if (Row_Value == 1) lKey = KEY_ERROR;
- else if (Row_Value == 2) lKey = KEY_7;
- else if (Row_Value == 3) lKey = KEY_6;
- else if (Row_Value == 4) lKey = KEY_5;
- else if (Row_Value == 5) lKey = KEY_4;
- }
- else if (Column_Value == 1)
- {
- if (Row_Value == 0) lKey = KEY_ERROR;
- else if (Row_Value == 1) lKey = KEY_POUND;
- else if (Row_Value == 2) lKey = KEY_0;
- else if (Row_Value == 3) lKey = KEY_ASTERISK;
- else if (Row_Value == 4) lKey = KEY_9;
- else if (Row_Value == 5) lKey = KEY_8;
- }
- else if (Column_Value == 0)
- {
- lKey = KEY_END;
- }
- return lKey;
- }
- /*********************************************************************************************************
- * Keypad_Decoder()
- *
- * Description : Keypad_Decoder Function
- * 1) Decode the column
- * 2) Decode the row
- * 3) Map the coordinate to a key
- *
- * Argument(s) : none.
- *
- * Return(s) : Pressed Key.
- *********************************************************************************************************/
- UCHAR Keypad_Decoder (void)
- {
- Decode_Column();
- Decode_Row();
- return Keypad_Map();
- }
- /*----------------------------------------------------------------------------
- SysTick IRQ Handler
- *----------------------------------------------------------------------------*/
- void SysTick_Handler (void)
- {
- uTimeCnt++;
- }
- /* Initialize I2C connected SA56004 */
- int32_t PCA9555D_Initialize (void)
- {
- I2Cdrv->Initialize (NULL);
- I2Cdrv->PowerControl (ARM_POWER_FULL);
- I2Cdrv->Control (ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
- I2Cdrv->Control (ARM_I2C_BUS_CLEAR, 0);
- return 1;
- }
- int32_t Delayms(uint32_t ms)
- {
- uTimeCnt=0;
- while(uTimeCnt<ms){};
- return 0;
- }
- int32_t LED_Initialize (void)
- {
- /* Enable GPIO clock */
- GPIO_PortClock (1);
- /* Configure pins: Output Mode with Pull-down resistors */
- PIN_Configure (LED_PORT, LED_PIN, PIN_FUNC_0, PIN_PINMODE_PULLDOWN, PIN_PINMODE_NORMAL);
- GPIO_SetDir (LED_PORT, LED_PIN, GPIO_DIR_OUTPUT);
- GPIO_PinWrite (LED_PORT, LED_PIN, 0);
- return 0;
- }
复制代码 主函数如下:- /*----------------------------------------------------------------------------
- Main function
- *----------------------------------------------------------------------------*/
- int main (void)
- {
- char buff[40];
- uint8_t uLedState=0;
- UCHAR keypadval=0;
- SystemCoreClockUpdate (); /* Update system core clock */
- SysTick_Config(SystemCoreClock/1000); /* Generate interrupt each 1 ms */
- LED_Initialize(); /* LED Initialization */
- PCA9555D_Initialize();
- Keypad_Init();
- LCD_Init();
- LCD_WR_Str("Welcome used LPC1768");
- while (1)
- {
- I2C_Data_Read_Buffer[0]=0;
- I2C_Data_Read_Buffer[1]=0;
-
- Keypad_Data_Read=Keypad_Read();
-
- if((Keypad_Data_Read|P1_KPAD_COLUMN_MASK)!=0xFF)
- {
- keypadval=Keypad_Decoder();
- sprintf(buff,"CurKeypad value:%d",keypadval);
- LCD_Set_RowCol(0,2);
- LCD_WR_Str(buff);
- }else
- {
- memset(buff,0,sizeof(buff));
- sprintf(buff,"No Key Pressed! ");
- LCD_Set_RowCol(0,2);
- LCD_WR_Str(buff);
- }
- GPIO_PinWrite(LED_PORT, LED_PIN, uLedState); /* Turn specified LED off */
- uLedState=!uLedState;
- Delayms(100);
- }
- }
复制代码 本次实现按下键时获取对应键值的结果如下所示:
|
|