回复
#2020征文-开发板#更加优雅的使用OLED板的按键
独涤
发布于 2020-12-21 18:51
浏览
0收藏
开发板OLED板下面有两个按键,上手开发板第一件事肯定是调试输入输出手段。串口几乎不需要调试什么,上手就能用。这个按键就成了第一个下手的目标。
起初没把这俩按键当回事,以为只是直接接在GPIO上的,顶多设置一下触发点平就行了。拿到原理图才发现,这俩按键居然是这样接的。
也就是说必须使用ADC才能确认按下的是哪一个键。开发板官方给出了OLED板的demo,其中也包含了对屏幕下面两个按键的使用。但是查看代码发现,是使用死循环不断进行ADC转换来捕捉按键操作的。这样做会导致系统功耗上升,并且会持续占用CPU。
其实我们可以更加优雅的使用这俩按键,使用按键终端触发按键事件,再由按键线程完成按键事件的处理。这样做在平时不按按键时,系统CPU处于IDLE状态、ADC也处于停止状态。功耗、CPU都能降下来。甚至你可以配置进入低功耗模式。
代码不多
// 全局信号量,记录按键事件
osSemaphoreId_t g_keySem;
void KeyPressed(char *arg) {
(void)arg;
//释放一个信号量,注意这里是中断上下文,最好别调用太多东西
osSemaphoreRelease(g_keySem);
}
void handlePressKeyTask(void* arg) {
(void)arg;
while(true) {
// 这里去消费按键事件
osStatus_t status = osSemaphoreAcquire(g_keySem,65535);
if(status != 0) {
continue;
}
while(true) {
unsigned short data = 0;
AdcRead(analog_KEY_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0);
float voltage = (float)data * 1.8 * 4 / 4096;
if(voltage < 0.8f) {
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_DrawString("Key1 Pressed!", Font_7x10, White);
ssd1306_UpdateScreen();
} else if(voltage < 2.0f) {
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_DrawString("Key2 Pressed!", Font_7x10, White);
ssd1306_UpdateScreen();
} else {
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_DrawString("Released!", Font_7x10, White);
ssd1306_UpdateScreen();
break;
}
}
}
}
void initKey() {
// 端口设置为GPIO
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
// 设置为输入
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_GPIO_DIR_IN);
// 设置在下降沿中断。(其实我想设置下降沿和上升沿中断的,然而接口居然不允许)
osSemaphoreAttr_t semAttr = {
.name = "KeyPressSemi",
.attr_bits = 0,
.cb_mem = NULL,
.cb_size = 0
};
g_keySem = osSemaphoreNew(8, 0, &semAttr);
GpioRegisterIsRFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, KeyPressed, NULL);
// 这里启动一个task处理按键事件
osThreadAttr_t attr;
attr.name = "KeyHandleTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 2048;
attr.priority = osPriorityNormal;
if (osThreadNew(handlePressKeyTask, NULL, &attr) == NULL) {
printf("[%s]Falied to create KeyHandleTask!\n", __func__);
}
}
分类
已于2020-12-21 18:51:41修改
赞
收藏
回复
相关推荐