uint8_t Key_Scan_double_1(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
static uint8_t flag_key;
static uint8_t count_time;
static uint8_t count_single;
static uint8_t count_key;
static uint8_t double_key;
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )
count_time++,flag_key = 1;
else if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_OFF )
{
count_key = 0;flag_key = 0;count_time = 0;
}
if((0 == count_key)&&(1 == flag_key))
{
double_key++;
count_key = 1;
}
if(1 == double_key)
count_single++;
if((1 == double_key)&&(count_single > TIME))
{
double_key = 0;
count_single = 0;
return KEY_ON;
}
if(2 == double_key)
{
double_key = 0;
count_single = 0;
return KEY_ON_Double;
}
return KEY_OFF;
}
本来可以使用一个传参的方法来决定在多长的时间里面判断是单击还是双击。但是为了可以方便测试,所以定义了一个宏定义。
注意点:1、使用了一个逗号表达式,因为之前不知道逗号表达式,所以特意放了一个。逗号表达式就是,会执行,但是体统会认为是一条语句。
2、就是static的用法了。当static修饰局部变量时,是会有记录作用的,不会一直初始化。但是static修饰全局变量或者函数时,他就被私有化,别的文件是不能调用它的。
3、函数的的执行过程:在设置的那段时间(判断是否双击的时间)里面,函数返回的一直是KEY_OFF,一旦时间到了他就会返回KEY_ON或者KEY_ON_Double,因为这个时候他才会按照double_key的值判断按了几下。所以他只会会在极短的时间里面返回一个值。所以获取函数的值是至关重要的,如果时间太长的话,他一下就返回了KEY_OFF,之前按了的话返回值也是会被覆盖掉的,因为程序执行的时间很快,一般用一个变量先接受就显得至关重要了。如以下两种方式: NUM = Key_Scan_double_1(KEY2_GPIO_PORT,KEY2_GPIO_PIN);if( NUM == KEY_OFF )
和if(Key_Scan_double_1(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_OFF )这两种方式就会有不一样的结果。当一个放在10ms的定时器里面时,可能下一秒在方式2在判断if时会进入函数,可能此时的返回值就是KEY_OFF 。而方式一的好处就是,使用了一个变量先记录这这个值,在进行判断时就不会被覆盖掉原有的值。(重要的思路)。
4、在进行硬件仿真时,每次仿真到一半就会闪退,之前一直找不到原因,后来发现是因为文件路径里面有中文。改一下就好了。这个是调试时的按键信息。
5、J-Link、ST-Link,U-Link和JTAG、SWD、SWIM:前面三种是下载器,后面三种是下载模式。一般使用SWD(串行调试,一般用两根线)更多。JTAG使用四根线。JTAG接口。
参考:https://blog.csdn.net/a183635870/article/details/107041022/