一、简介
按键扫描就是通过软件获取引脚的电平变化,从而判断是长按,还是短按。如下原理图,只要按键按下引脚的电平就会被拉低。
二、程序
获取(一个)GPIO输入状态
extern CyU3PReturnStatus_t
CyU3PGpioGetValue (
uint8_t gpioId, /**< GPIO id to be queried. */
CyBool_t *value_p /**< Output parameter that will be filled with the GPIO value. */
);
获取(一个)简单GPIO输入状态
extern CyU3PReturnStatus_t
CyU3PGpioSimpleGetValue (
uint8_t gpioId, /**< GPIO id to be queried. */
CyBool_t *value_p /**< Output parameter that will be filled with the GPIO value. */
);
获取所有GPIO输入状态
extern CyU3PReturnStatus_t
CyU3PGpioGetIOValues (
uint32_t *gpioVal0_p, /**< Bit vector that represents the states of GPIO 31 : 00. */
uint32_t *gpioVal1_p /**< Bit vector that represents the states of GPIO 60 : 32. The
upper three bits are unused and reserved. */
);
对地址操作获取(一个)GPIO输入状态
#define CyFx3GpioReadBit(GpioPin) ((GPIO->lpp_gpio_simple[GpioPin]& CY_U3P_LPP_GPIO_IN_VALUE) >> 1)
KEY源文件
#include "cyfx3_key.h"
#include "cyfx3_gpio.h"
KeyInfoTypedef_t KeyInfo = {0};
uint8_t CyFx3KeyScan(void)
{
uint8_t KeyEvent = 0;
if(KEY_INPUT == KEY_DOWN)
{
KeyInfo.CountLow++;
if(KeyInfo.CountLow >= KEY_LONG_TIME
&& KeyInfo.AlreadLongFlag == 0)
{
KeyEvent = KEY_LONG;
KeyInfo.AlreadLongFlag = 1;
}
}
else
{
if(KeyInfo.CountLow >= KEY_SHORT_TIME && KeyInfo.CountLow < KEY_LONG_TIME)
{
KeyEvent = KEY_SHORT;
}
memset(&KeyInfo,0,sizeof(KeyInfo));
}
return KeyEvent;
}
KEY头文件
#ifndef CYFX3_KEY_H_
#define CYFX3_KEY_H_
#include "cyu3gpio.h"
#define KEY_DOWN 0 //按键按下为低电平
#define KEY_LONG 0x01
#define KEY_SHORT 0x02
#define KEY_LONG_TIME 100 //1S
#define KEY_SHORT_TIME 10
typedef struct {
uint16_t CountLow; //低电平计时
uint16_t CountHigh;
uint8_t AlreadLongFlag;
uint8_t LastValue;
uint8_t CurValue;
}KeyInfoTypedef_t;
uint8_t CyFx3KeyScan(void);
#endif /* CYFX3_KEY_H_ */
主函数
#include "cyu3os.h"
#include "cyu3error.h"
#include "cyu3uart.h"
#include "cyfx3_gpio.h"
#include "cyfx3_key.h"
CyU3PThread LedThreadHandler;
CyU3PThread KeyThreadHandler;
#define LED_THREAD_PRIORITY 8
#define LED_THREAD_STACK_SIZE 512
#define KEY_THREAD_PRIORITY 9
#define KEY_THREAD_STACK_SIZE 512
static CyU3PReturnStatus_t CyFx3LogInit(void)
{
CyU3PReturnStatus_t CyFx3Status;
//初始化串口设备
CyFx3Status = CyU3PUartInit();
if(CyFx3Status != CY_U3P_SUCCESS)
{
return CyFx3Status;
}
//配置uart
CyU3PUartConfig_t UartConfig = {
.txEnable = CyTrue,
.rxEnable = CyFalse,
.flowCtrl = CyFalse,
.isDma = CyTrue,
.baudRate = 115200,
.stopBit = CY_U3P_UART_ONE_STOP_BIT,
.parity = CY_U3P_UART_NO_PARITY,
};
CyFx3Status = CyU3PUartSetConfig(&UartConfig,NULL);
if(CyFx3Status != CY_U3P_SUCCESS)
{
return CyFx3Status;
}
//设置发送字节大小
CyFx3Status = CyU3PUartTxSetBlockXfer(0xFFFFFFFF);
if (CyFx3Status != CY_U3P_SUCCESS)
{
return CyFx3Status;
}
//不输出8字节前导数据
CyU3PDebugPreamble(CyFalse);
//初始化串口日志功能
CyFx3Status = CyU3PDebugInit(CY_U3P_LPP_SOCKET_UART_CONS,8);
if(CyFx3Status != CY_U3P_SUCCESS)
{
return CyFx3Status;
}
return CY_U3P_SUCCESS;
}
void LedThread(uint32_t arg)
{
CyFx3GpioInit();
CyFx3GpioConfig();
while(1)
{
LED_TOGGLE;
CyU3PThreadSleep(500);
}
}
void KeyThread(uint32_t arg)
{
CyFx3LogInit();
while(1)
{
switch(CyFx3KeyScan())
{
case KEY_LONG:
{
CyU3PDebugPrint(6,"key long!\r\n");
}break;
case KEY_SHORT:
{
CyU3PDebugPrint(6,"key short!\r\n");
}break;
default:break;
}
CyU3PThreadSleep(10);
}
}
void CyFxApplicationDefine(void)
{
void *LedStackStart = CyU3PMemAlloc(LED_THREAD_STACK_SIZE);
if(LedStackStart != NULL)
{
CyU3PThreadCreate((CyU3PThread* ) &LedThreadHandler,
(char* ) "21:Led Thread 1",
(CyU3PThreadEntry_t) LedThread,
(uint32_t ) 0,
(void* ) LedStackStart,
(uint32_t ) LED_THREAD_STACK_SIZE,
(uint32_t ) LED_THREAD_PRIORITY,
(uint32_t ) LED_THREAD_PRIORITY,
(uint32_t ) CYU3P_NO_TIME_SLICE,
(uint32_t ) CYU3P_AUTO_START);
}
void *KeyStackStart = CyU3PMemAlloc(LED_THREAD_STACK_SIZE);
if(KeyStackStart != NULL)
{
CyU3PThreadCreate((CyU3PThread* ) &KeyThreadHandler,
(char* ) "22:Key Thread 2",
(CyU3PThreadEntry_t) KeyThread,
(uint32_t ) 0,
(void* ) KeyStackStart,
(uint32_t ) KEY_THREAD_STACK_SIZE,
(uint32_t ) KEY_THREAD_PRIORITY,
(uint32_t ) KEY_THREAD_PRIORITY,
(uint32_t ) CYU3P_NO_TIME_SLICE,
(uint32_t ) CYU3P_AUTO_START);
}
}
int main(void)
{
CyU3PReturnStatus_t CyFx3Status;
//初始化FX3设备
CyFx3Status = CyU3PDeviceInit(NULL);
if(CyFx3Status != CY_U3P_SUCCESS)
{
goto HandleFatalError;
}
//初始化FX3内核缓存
CyFx3Status = CyU3PDeviceCacheControl(CyTrue,CyTrue,CyTrue);
if(CyFx3Status != CY_U3P_SUCCESS)
{
goto HandleFatalError;
}
//配置IO矩阵(16位数据总线 + UART + GPIO)
CyU3PIoMatrixConfig_t MatrixcConfig = {
.isDQ32Bit = CyFalse,
.s0Mode = CY_U3P_SPORT_INACTIVE,
.s1Mode = CY_U3P_SPORT_INACTIVE,
.useUart = CyTrue,
.useI2C = CyFalse,
.useI2S = CyFalse,
.useSpi = CyFalse,
.lppMode = CY_U3P_IO_MATRIX_LPP_UART_ONLY,
.gpioSimpleEn[0] = 0, //GPIO0~GPIO31
.gpioSimpleEn[1] = (0x01 << (KEY_GPIO_PIN - 32)), //GPIO32~GPIO60 使能GPIO45引脚
/*GPIO54为串口的CTS引脚 所有不用配置*/
.gpioComplexEn[0] = 0,
.gpioComplexEn[1] = 0,
};
CyFx3Status = CyU3PDeviceConfigureIOMatrix(&MatrixcConfig);
if (CyFx3Status != CY_U3P_SUCCESS)
{
goto HandleFatalError;
}
//初始化RTOS内核
CyU3PKernelEntry();
HandleFatalError:
//复位
CyU3PDeviceReset(CyTrue);
}
三、验证
烧录验证