cybertovsky

  • 2022-05-06
  • 回复了主题帖: 【平头哥RVB2601创意应用开发】8 超过一定数量的字母没被击落,显示游戏结束

    lugl4313820 发表于 2022-5-6 16:47 配个游戏柄就好玩了,可以调下降速度吗?
    下降速度可以调的

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】8 超过一定数量的字母没被击落,显示游戏结束

    超过一定数量的字母没有被击落而自然落下,则显示游戏结束。这其实就类似塔防。 为了实现这个功能,首先要设置一个变量,记录数量: int enemy_go_home=0; 其次,还需要设置一个lvgl标签,用于显示有多少个字母掉落而没有被击落: lv_obj_t *enemy_go_home_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(enemy_go_home_label, 80, 0); lv_obj_set_size(enemy_go_home_label, 30, 30); lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home); 那么,如何区分字母是否被击落呢? 很简单,在结构体里增加一个代表是否被击落的状态: struct Obj{ char name[20]; char code[20]; lv_obj_t *label; int x; int y; int die;//1代表被击落,0代表没有被击落 } 然后设置字母数组的时候,让die为0。 当字母被击落时,让die变为1: for(int i=0;i<size;i++){ if("这里判断输入的摩尔电码是否等于数组中定义的摩尔电码符号"){ objs[i].die = 1;//如果是,就让die等于1 } } 当然上面有个伪代码,就是为了让逻辑清晰,实际上代码是这样的: for(int i=0;i<size;i++){ if(objs[i].die==0){//如果没有被击中(已被击落的就不去判断了) if(objs[i].y>0 && objs[i].y<64){//在可视区间 if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); objs[i].die = 1;//标记被击中 score++; lv_label_set_text_fmt(score_label, "score: %d", score); } } } } 之后,只要在让字母落下的循环中,让没有被击落的字母超过屏幕高度时,计数+1即可: //如果没有被击中,而且落下去了 if(objs[i].y>64){ enemy_go_home+=1; lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home); objs[i].die=1; } 然后,在主循环中,通过数量大于等于5个来实现游戏结束: if(enemy_go_home>=5){ for(int i=0;i<size;i++){ lv_label_set_text(objs[i].label, ""); } lv_label_set_text(text_gameover, "GameOver"); status = 3; //game over } 以下是gui_game_task的全部代码: static void gui_game_task(void *arg){ time_t t; srand((unsigned) time(&t)); int looptime = 0; int score=0;//分数初始为0 int status=0;//初始状态为 0 游戏中 1 胜利 2 失败 3 lv_obj_t *text_gameover = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(text_gameover, 28, 30); lv_obj_set_size(text_gameover, 128, 60); lv_label_set_text(text_gameover, ""); //输入的标签 lv_obj_t *text_input = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(text_input, 100, 50); lv_obj_set_size(text_input, 80, 20); lv_label_set_text(text_input, ""); lv_obj_t *score_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(score_label, 0, 0); lv_obj_set_size(score_label, 128, 30); lv_label_set_text_fmt(score_label, "score: %d", score); int enemy_go_home=0;//没有被击落的字母就是敌人,这是敌人落下(家门口)的数量 // enemy go home count lv_obj_t *enemy_go_home_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(enemy_go_home_label, 80, 0); lv_obj_set_size(enemy_go_home_label, 30, 30); lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home); int size = 36; struct Obj{ char name[20]; char code[20]; lv_obj_t *label; int x; int y; int die; }objs[36]={ {"A",".-"}, {"B","-..."}, {"C","-.-."}, {"D","-.."}, {"E","."}, {"F","..-."}, {"G","--."}, {"H","...."}, {"I",".."}, {"J",".---"}, {"K","-.-"}, {"L",".-.."}, {"M","--"}, {"N","-."}, {"O","---"}, {"P",".--."}, {"Q","--.-"}, {"R",".-."}, {"S","..."}, {"T","-"}, {"U","..-"}, {"V","...-"}, {"W",".--"}, {"X","-..-"}, {"Y","-.--"}, {"Z","--.."}, {"0","-----"}, {"1",".----"}, {"2","..---"}, {"3","...--"}, {"4","....-"}, {"5","....."}, {"6","-...."}, {"7","--..."}, {"8","---.."}, {"9","----."}, }; for(int i=0;i<size;i++){ objs[i].label=lv_label_create(lv_scr_act(), NULL); objs[i].x=10 + rand() % (128-30); objs[i].y=-1*(rand() % size)-30; objs[i].die=0; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 20, 20); lv_label_set_text(objs[i].label, objs[i].name); } for (int i = 0; i < size; ++i){ for (int j = i + 1; j < size; ++j){ if (objs[i].y < objs[j].y){ struct Obj temp = objs[i]; objs[i] = objs[j]; objs[j] = temp; } } } for(int i=0;i<size;i++){ objs[i].y=-1*30*i; } status=1; while (1) { /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); if(status==1){ looptime+=1; if(looptime % 10 ==0){ for(int i=0;i<size;i++){ if(objs[i].die==0){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); //如果没有被击中,而且落下去了 if(objs[i].y>64){ enemy_go_home+=1; lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home); objs[i].die=1; } } } if(enemy_go_home>=5){ for(int i=0;i<size;i++){ lv_label_set_text(objs[i].label, ""); } lv_label_set_text(text_gameover, "GameOver"); status = 3; //game over } // if(objs[size-1].y>64){ // lv_label_set_text(text_gameover, "GameOver"); // status = 3; //game over // } } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==0){ nopress_time++; if(nopress_time>30){ //check_input(); for(int i=0;i<size;i++){ //如果没有被击中 if(objs[i].die==0){ if(objs[i].y>0 && objs[i].y<64){ //在可视区间 if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); objs[i].die = 1;//标记被击中 score++; lv_label_set_text_fmt(score_label, "score: %d", score); } } } } strcpy(input,""); lv_label_set_text(text_input,"");//输入效果清空 //check win //if status == playing if(score==size){ //status == "win" } } } if(button1_pressed==1){ nopress_time=0; printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); strcat(input,"-"); }else{ //短按 printf("."); strcat(input,"."); } lv_label_set_text(text_input,input);//输入效果 time_for_pressed=0;//恢复计数 button1_pressed = 0; } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; strcpy(input,""); lv_label_set_text(text_input,"");//输入效果清空 } } aos_msleep(5); lv_tick_inc(1); } } 效果如下:  

  • 发表了日志: 【平头哥RVB2601创意应用开发】8 超过一定数量的字母没被击落,显示游戏结束

  • 回复了主题帖: 【平头哥RVB2601创意应用开发】7 随机字母落下的效果

    nemon 发表于 2022-5-5 14:56 摩尔斯电码?

  • 2022-04-30
  • 回复了主题帖: 【平头哥RVB2601创意应用开发】7 随机字母落下的效果

    lugl4313820 发表于 2022-4-30 06:59 游戏机快成功了吧,历害了!
    嗯,快了。

  • 发表了日志: 【平头哥RVB2601创意应用开发】7 随机字母落下的效果

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】7 随机字母落下的效果

    上一期实现了字母落下,摩尔斯电码输入消除字母后分数显示。 这一期要实现随机字母下落。怎么办呢? 简单粗暴的方法,是对数组进行排序。 重温一下,结构体数组: int size = 36; struct Obj{ char name[20]; char code[20]; lv_obj_t *label; int x; int y; }objs[36]={ {"A",".-"}, {"B","-..."}, {"C","-.-."}, {"D","-.."}, {"E","."}, {"F","..-."}, {"G","--."}, {"H","...."}, {"I",".."}, {"J",".---"}, {"K","-.-"}, {"L",".-.."}, {"M","--"}, {"N","-."}, {"O","---"}, {"P",".--."}, {"Q","--.-"}, {"R",".-."}, {"S","..."}, {"T","-"}, {"U","..-"}, {"V","...-"}, {"W",".--"}, {"X","-..-"}, {"Y","-.--"}, {"Z","--.."}, {"0","-----"}, {"1",".----"}, {"2","..---"}, {"3","...--"}, {"4","....-"}, {"5","....."}, {"6","-...."}, {"7","--..."}, {"8","---.."}, {"9","----."}, }; 之后,对其循环,把lvgl的label标签对象加上去,注意下面我注释的内容: for(int i=0;i<size;i++){ objs[i].label=lv_label_create(lv_scr_act(), NULL); objs[i].x=10 + rand() % (128-30); objs[i].y=-1*(rand() % size)-30; //这里重点是这个随机数,不是为了y轴坐标,而是用来排序的! lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 20, 20); lv_label_set_text(objs[i].label, objs[i].name); } 之后,再用循环,完成排序: for (int i = 0; i < size; ++i){ for (int j = i + 1; j < size; ++j){ if (objs[i].y < objs[j].y){ struct Obj temp = objs[i]; objs[i] = objs[j]; objs[j] = temp; } } } 再循环一次,重新排完序的结构体数组重新设置y轴。 for(int i=0;i<size;i++){ objs[i].y=-1*30*i; } 至于下落,还是老样子,在while中循环,每隔一定时间,让结构体的y轴+1: for(int i=0;i<size;i++){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); } 另外,本期还优化了上期一段代码,用于分数的显示: 优化前:用strcat拼接字符串实现分数的显示 sprintf(value, "%d", score); strcat(text_score,value); lv_label_set_text(score_label,text_score); 优化后,用lv_label_set_text_fmt方法,可以自己设置模板文本: lv_label_set_text_fmt(score_label, "score: %d", score); 最后: gui_game_task全部代码: static void gui_game_task(void *arg) { lv_init(); oled_init(); time_t t; srand((unsigned) time(&t)); int looptime = 0; int score=0;//分数初始为0 int status=0;//初始状态为 0 游戏中 1 胜利 2 失败 3 lv_obj_t *text_gameover = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(text_gameover, 28, 30); lv_obj_set_size(text_gameover, 128, 60); lv_label_set_text(text_gameover, ""); //输入的标签 lv_obj_t *text_input = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(text_input, 100, 50); lv_obj_set_size(text_input, 80, 20); lv_label_set_text(text_input, ""); lv_obj_t *score_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(score_label, 0, 0); lv_obj_set_size(score_label, 128, 30); lv_label_set_text_fmt(score_label, "score: %d", score); int size = 36; struct Obj{ char name[20]; char code[20]; lv_obj_t *label; int x; int y; }objs[36]={ {"A",".-"}, {"B","-..."}, {"C","-.-."}, {"D","-.."}, {"E","."}, {"F","..-."}, {"G","--."}, {"H","...."}, {"I",".."}, {"J",".---"}, {"K","-.-"}, {"L",".-.."}, {"M","--"}, {"N","-."}, {"O","---"}, {"P",".--."}, {"Q","--.-"}, {"R",".-."}, {"S","..."}, {"T","-"}, {"U","..-"}, {"V","...-"}, {"W",".--"}, {"X","-..-"}, {"Y","-.--"}, {"Z","--.."}, {"0","-----"}, {"1",".----"}, {"2","..---"}, {"3","...--"}, {"4","....-"}, {"5","....."}, {"6","-...."}, {"7","--..."}, {"8","---.."}, {"9","----."}, }; for(int i=0;i<size;i++){ objs[i].label=lv_label_create(lv_scr_act(), NULL); objs[i].x=10 + rand() % (128-30); objs[i].y=-1*(rand() % size)-30; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 20, 20); lv_label_set_text(objs[i].label, objs[i].name); } for (int i = 0; i < size; ++i){ for (int j = i + 1; j < size; ++j){ if (objs[i].y < objs[j].y){ struct Obj temp = objs[i]; objs[i] = objs[j]; objs[j] = temp; } } } for(int i=0;i<size;i++){ objs[i].y=-1*30*i; } status=1; while (1) { /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); if(status==1){ looptime+=1; if(looptime % 15 ==0){ for(int i=0;i<size;i++){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); } if(objs[size-1].y>64){ lv_label_set_text(text_gameover, "GameOver"); status = 3; //game over } } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==0){ nopress_time++; if(nopress_time>30){ //check_input(); for(int i=0;i<size;i++){ if(objs[i].y>0 && objs[i].y<64){ //在可视区间 if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); char value[10]; char text_score[20]="score:"; score++; lv_label_set_text_fmt(score_label, "score: %d", score); } } } strcpy(input,""); lv_label_set_text(text_input,"");//输入效果清空 //check win //if status == playing if(score==size){ //status == "win" } } } if(button1_pressed==1){ nopress_time=0; printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); strcat(input,"-"); }else{ //短按 printf("."); strcat(input,"."); } lv_label_set_text(text_input,input);//输入效果 time_for_pressed=0;//恢复计数 button1_pressed = 0; } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; strcpy(input,""); lv_label_set_text(text_input,"");//输入效果清空 } } aos_msleep(5); lv_tick_inc(1); } } 效果:

  • 2022-04-20
  • 发表了日志: 【平头哥RVB2601创意应用开发】6 分数显示,消除字母后分数+1

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】6 分数显示,消除字母后分数+1

    上一期实现了消除字母,这一期在这基础上加一个分数的lvgl控件。 所以要有一个变量来记录分数: int score=0;//分数初始为0 还有设置一个label标签: lv_obj_t *score_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(score_label, 0, 0); lv_obj_set_size(score_label, 128, 30); lv_label_set_text(score_label,"score:0"); 关键代码其实是消除字母后,让分数+1后的数字转字符: char value[10]; char text_score[20]="score:"; score++; sprintf(value, "%d", score); strcat(text_score,value); lv_label_set_text(score_label,text_score); 其中,数组转字符用的是 sprintf 函数。字符串拼接用的是 strcat 函数。 以下是全部代码(里面有包括用gpio中断但被注释的代码,因为gpio中断不能实现长按): /* * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ /********************* * INCLUDES *********************/ #define _DEFAULT_SOURCE /* needed for usleep() */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <aos/aos.h> #include "aos/cli.h" #include "app_init.h" #include "lvgl.h" #include "lv_label.h" #include "oled.h" /********************* * DEFINES *********************/ #define TAG "app" /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ // GUI static void gui_lvgl_task(void *arg); /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ volatile uint32_t g_debug = 0; volatile uint32_t g_debug_v = 0; static void gui_lvgl_task(void *arg); #include "csi_config.h" #include "board_config.h" #include "drv/gpio_pin.h" #include <drv/pin.h> #include "csi_core.h" static csi_gpio_pin_t key1; static csi_gpio_pin_t key2; int button1_pressed = 0;// button1 是否被按下 int button2_pressed = 0;// button2 是否被按下 int time_for_pressed=0;// 按下的时间计数 int nopress_time=0; //没有按下时 计数 int looptime = 0; char input[12]; int score=0;//分数初始为0 #define GPIO_CHECK_RETURN(ret) \ do { \ if (ret != CSI_OK) { \ return -1; \ } \ } while(0); static void key1_handler(csi_gpio_pin_t *pin, void *arg) { printf("\n"); printf(time_for_pressed); time_for_pressed ++; } static void key2_handler(csi_gpio_pin_t *pin, void *arg) { // time_for_pressed ++; } /** * main */ int main(void) { int ret; board_yoc_init(); // 下面是针对PA11和PA12的中断,之所以注释掉,是因为中短不能实现长按。但是用于一般的按键,比如普通游戏里的方向键什么的是可以的。 // ret = csi_gpio_pin_init(&key1, PA11); // GPIO_CHECK_RETURN(ret); // // /* Attach callback */ // ret = csi_gpio_pin_attach_callback(&key1, key1_handler, NULL); // GPIO_CHECK_RETURN(ret); // // /* Set pull-up mode */ // ret = csi_gpio_pin_mode(&key1, GPIO_MODE_PULLUP); // GPIO_CHECK_RETURN(ret); // // /* Set input mode */ // ret = csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); // GPIO_CHECK_RETURN(ret); // // /* Set falling-edge triger mode */ // ret = csi_gpio_pin_irq_mode(&key1, GPIO_IRQ_MODE_FALLING_EDGE); // GPIO_CHECK_RETURN(ret); // // /* Enable irq */ // ret = csi_gpio_pin_irq_enable(&key1, true); // GPIO_CHECK_RETURN(ret); // // // ret = csi_gpio_pin_init(&key2, PA12); // GPIO_CHECK_RETURN(ret); // // /* Attach callback */ // ret = csi_gpio_pin_attach_callback(&key2, key2_handler, NULL); // GPIO_CHECK_RETURN(ret); // // /* Set pull-up mode */ // ret = csi_gpio_pin_mode(&key2, GPIO_MODE_PULLUP); // GPIO_CHECK_RETURN(ret); // // /* Set input mode */ // ret = csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); // GPIO_CHECK_RETURN(ret); // // /* Set falling-edge triger mode */ // ret = csi_gpio_pin_irq_mode(&key2, GPIO_IRQ_MODE_FALLING_EDGE); // GPIO_CHECK_RETURN(ret); // // /* Enable irq */ // ret = csi_gpio_pin_irq_enable(&key2, true); // GPIO_CHECK_RETURN(ret); aos_task_new("gui", gui_lvgl_task, NULL, 10 * 1024); return 0; } static void gui_lvgl_task(void *arg) { lv_init(); oled_init(); lv_obj_t *score_label = lv_label_create(lv_scr_act(), NULL); lv_obj_set_pos(score_label, 0, 0); lv_obj_set_size(score_label, 128, 30); lv_label_set_text(score_label,"score:0"); struct Obj{ char name[20]; char code[20]; lv_obj_t *label; int x; int y; }objs[2]={ {"A",".-",lv_label_create(lv_scr_act(), NULL),30,-20}, {"B","-...",lv_label_create(lv_scr_act(), NULL),60,-10} }; for(int i=0;i<2;i++){ lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 128, 30); lv_label_set_text(objs[i].label, objs[i].name); } csi_pin_set_mux(PA11, PIN_FUNC_GPIO); csi_pin_set_mux(PA12, PIN_FUNC_GPIO); csi_gpio_pin_init(&key1, PA11); csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); csi_gpio_pin_init(&key2, PA12); csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); while (1) { /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); looptime+=1; if(looptime % 10 ==0){ for(int i=0;i<2;i++){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==0){ nopress_time++; if(nopress_time>30){ //check_input(); for(int i=0;i<2;i++){ if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); char value[10]; char text_score[20]="score:"; score++; sprintf(value, "%d", score); strcat(text_score,value); lv_label_set_text(score_label,text_score); } } strcpy(input,""); } } if(button1_pressed==1){ nopress_time=0; printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); strcat(input,"-"); //lv_textarea_add_text(text,"-"); }else{ //短按 printf("."); strcat(input,"."); //lv_textarea_add_text(text,"."); } time_for_pressed=0;//恢复计数 button1_pressed = 0; } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; strcpy(input,""); //lv_textarea_del_char(text); } } aos_msleep(5); lv_tick_inc(1); } } 演示效果如下:  

  • 2022-04-14
  • 回复了主题帖: 【平头哥RVB2601创意应用开发】5 同时显示字母AB,通过长按短按消除

    lugl4313820 发表于 2022-4-14 06:37 楼主这么晚还在发帖子,辛苦啦! 按键长按短按,是状态机编程思想中最为经典的实现。您用得非常溜。看实 ...
    好的,我一会儿去研究一下中断的用法。

  • 发表了日志: 【平头哥RVB2601创意应用开发】5 同时显示字母AB,通过长按短按消除

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】5 同时显示字母AB,通过长按短按消除

    上一期,已经实现了消除A。这一期,同时显示字母AB,需要用到2个lvgl标签。怎么做呢?我想到了结构体: struct Obj{ char name[20]; char code[20]; char *label; int x; int y; }objs[2]={ {"A",".-",lv_label_create(lv_scr_act(), NULL),10,5}, {"B","-...",lv_label_create(lv_scr_act(), NULL),30,5} }; 这样,就定义了结构体,以及设置了一个只有2个结构体的数组。 接下来,还需要遍历结构体,用于lvgl的设置,包括位置,初始文字等: for(int i=0;i<2;i++){ lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 128, 30); lv_label_set_text(objs[i].label, objs[i].name); } 然后还需要让这两个标签从上往下落,原理就是便利结构体数组,让每个结构体对象的y轴自增: looptime+=1; if(looptime % 10 ==0){ for(int i=0;i<2;i++){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); } } 这样就实现了字母往下落的效果。   接下来,就是如何消除字母,在上一期的基础上,nopress_time>30 时是输入,那么这时就遍历结构体数组,去用input和结构体的code去对比,如果发现一致,就说明匹配上了,然后去把结构体里的label对象设置为""就行了: if(nopress_time>30){ for(int i=0;i<2;i++){ if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); } } strcpy(input,""); } 全部代码如下: /* * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ /********************* * INCLUDES *********************/ #define _DEFAULT_SOURCE /* needed for usleep() */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <aos/aos.h> #include "aos/cli.h" #include "app_init.h" #include "lvgl.h" #include "lv_label.h" #include "oled.h" /********************* * DEFINES *********************/ #define TAG "app" /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ // GUI static void gui_lvgl_task(void *arg); /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ volatile uint32_t g_debug = 0; volatile uint32_t g_debug_v = 0; static void gui_lvgl_task(void *arg); #include "csi_config.h" #include "board_config.h" #include "drv/gpio_pin.h" #include <drv/pin.h> #include "csi_core.h" static csi_gpio_pin_t key1; static csi_gpio_pin_t key2; int button1_pressed = 0;// button1 是否被按下 int button2_pressed = 0;// button2 是否被按下 int time_for_pressed=0;// 按下的时间计数 int nopress_time=0; //没有按下时 计数 int looptime = 0; char input[12]; /** * main */ int main(void) { board_yoc_init(); aos_task_new("gui", gui_lvgl_task, NULL, 10 * 1024); return 0; } static void gui_lvgl_task(void *arg) { lv_init(); oled_init(); struct Obj{ char name[20]; char code[20]; char *label; int x; int y; }objs[2]={ {"A",".-",lv_label_create(lv_scr_act(), NULL),10,5}, {"B","-...",lv_label_create(lv_scr_act(), NULL),30,5} }; for(int i=0;i<2;i++){ lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); lv_obj_set_size(objs[i].label, 128, 30); lv_label_set_text(objs[i].label, objs[i].name); } csi_pin_set_mux(PA11, PIN_FUNC_GPIO); csi_pin_set_mux(PA12, PIN_FUNC_GPIO); csi_gpio_pin_init(&key1, PA11); csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); csi_gpio_pin_init(&key2, PA12); csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); while (1) { /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); looptime+=1; if(looptime % 10 ==0){ for(int i=0;i<2;i++){ objs[i].y+=1; lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y); } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==0){ nopress_time++; if(nopress_time>30){ //check_input(); for(int i=0;i<2;i++){ if(strcmp(input,objs[i].code)==0){ lv_label_set_text(objs[i].label, ""); } } strcpy(input,""); } } if(button1_pressed==1){ nopress_time=0; // printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); strcat(input,"-"); //lv_textarea_add_text(text,"-"); }else{ //短按 printf("."); strcat(input,"."); //lv_textarea_add_text(text,"."); } time_for_pressed=0;//恢复计数 button1_pressed = 0; } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; strcpy(input,""); } } aos_msleep(5); lv_tick_inc(1); } } 演示效果:  

  • 2022-04-07
  • 发表了日志: 【平头哥RVB2601创意应用开发】3 长按短按消除字母A

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】4 长按短按消除字母A

    本帖最后由 cybertovsky 于 2022-4-9 21:20 编辑 上周,实现了字母A的由上至下往下落。 本周,实现长按短按消除字母A。思路是,长按短按组成一个字符串,通过对比字符串,判断输入的十分正确。 通过查询摩尔斯电码得知,字母A的摩尔斯电码是“.-"   因此,用一个名为input的变量,接受输入: char input[12];   对于长按短按,使用字符串拼接函数进行拼接: //长按 strcat(input,"-");   //短按 strcat(input,".");   莫尔斯码判断函数: if(strcmp(input,".-")==0){ lv_label_set_text(text_label, "");//把字母A设为"” strcpy(input,"");//把输入的字符串设置为“” lv_label_set_text(input_label, input);//屏幕显示输入的莫尔斯码的字符串设置为“” }   全部代码如下: /* * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ /********************* * INCLUDES *********************/ #define _DEFAULT_SOURCE /* needed for usleep() */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <aos/aos.h> #include "aos/cli.h" #include "app_init.h" #include "lvgl.h" #include "lv_label.h" #include "oled.h" /********************* * DEFINES *********************/ #define TAG "app" /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ // GUI static void gui_lvgl_task(void *arg); /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ volatile uint32_t g_debug = 0; volatile uint32_t g_debug_v = 0; static void gui_lvgl_task(void *arg); #include "csi_config.h" #include "board_config.h" #include "drv/gpio_pin.h" #include <drv/pin.h> #include "csi_core.h" static csi_gpio_pin_t key1; static csi_gpio_pin_t key2; int button1_pressed = 0;// button1 是否被按下 int button2_pressed = 0;// button2 是否被按下 int time_for_pressed=0;// 按下的时间计数 int nopress_time=0; //没有按下时 计数 lv_obj_t *text_label; lv_obj_t *input_label; int y=-10; int time_for_y=0; char text[200]; char input[12]; /** * main */ int main(void) { board_yoc_init(); aos_task_new("gui", gui_lvgl_task, NULL, 10 * 1024); return 0; } static void gui_label_text_create(void) { text_label = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(text_label, LV_LABEL_LONG_BREAK); lv_label_set_align(text_label, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(text_label, 0, y); lv_obj_set_size(text_label, 128, 30); lv_label_set_text(text_label, "A"); } static void gui_label_input_create(void) { input_label = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(input_label, LV_LABEL_LONG_BREAK); lv_label_set_align(input_label, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(input_label, 0, 50); lv_obj_set_size(input_label, 128, 30); lv_label_set_text(input_label, ""); // lv_label_set_align(input_label, LV_LABEL_ALIGN_RIGHT); } static void text_append(char* c){ strcat(text,c); lv_label_set_text(text_label, text); } static void check_input(void){ if(strcmp(input,".-")==0){ //text_append("A"); lv_label_set_text(text_label, ""); strcpy(input,""); lv_label_set_text(input_label, input); } } static void gui_lvgl_task(void *arg) { lv_init(); /*Initialize for LittlevGL*/ oled_init(); /*Select display 1*/ // demo_create(); gui_label_text_create(); gui_label_input_create(); csi_pin_set_mux(PA11, PIN_FUNC_GPIO); csi_pin_set_mux(PA12, PIN_FUNC_GPIO); csi_gpio_pin_init(&key1, PA11); csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); csi_gpio_pin_init(&key2, PA12); csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); while (1) { /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); time_for_y++; if(time_for_y % 20==0){ y++; } lv_obj_set_pos(text_label, 0, y); if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==0){ nopress_time++; if(nopress_time>30){ check_input(); } } if(button1_pressed==1){ nopress_time=0; // printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); strcat(input,"-"); }else{ //短按 printf("."); strcat(input,"."); } time_for_pressed=0;//恢复计数 button1_pressed = 0; lv_label_set_text(input_label, input); } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; strcat(input,""); } } aos_msleep(5); lv_tick_inc(1); } } 视频效果:  

  • 2022-04-02
  • 回复了主题帖: 【平头哥RVB2601创意应用开发】3 点亮屏幕显示字母A

    nmg 发表于 2022-4-2 09:57 这个背景,是你不设置,它自动就是那样的吗 看着跟要坏了一样
    你是说屏幕的闪烁吗?肉眼看是正常的,手机录后是闪烁的。

  • 2022-04-01
  • 发表了主题帖: 【平头哥RVB2601创意应用开发】3 点亮屏幕显示字母A

      关于在屏幕上显示文字的例子其实有很多。 因为RVB2601支持lvgl,所以我找了一个转换工具 https://lvgl.io/tools/fontconverter 转换后的代码如下: /******************************************************************************* * Size: 60 px * Bpp: 1 * Opts: ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif #ifndef A #define A 1 #endif #if A /*----------------- * BITMAPS *----------------*/ /*Store the image of the glyphs*/ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { /* U+F287 "" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x83, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x3f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x3, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf8, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x3, 0x80, 0x7, 0xff, 0x80, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x1, 0xff, 0xf8, 0x7, 0xc0, 0x0, 0x0, 0x0, 0xf, 0xc0, 0x3f, 0xff, 0x81, 0xf0, 0x0, 0x0, 0x0, 0x1, 0xfe, 0xf, 0xff, 0xf0, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xe0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x7f, 0xe1, 0xff, 0xfc, 0x0, 0x7, 0x80, 0x0, 0x0, 0xf, 0xf0, 0x3f, 0xff, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x1, 0xf8, 0x3, 0xff, 0xc0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x3f, 0xf0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x7, 0x0, 0x1, 0xf8, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc0, 0x7f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x81, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0 }; /*--------------------- * GLYPH DESCRIPTION *--------------------*/ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, {.bitmap_index = 0, .adv_w = 1200, .box_w = 75, .box_h = 45, .ofs_x = 0, .ofs_y = 0} }; /*--------------------- * CHARACTER MAPPING *--------------------*/ /*Collect the unicode lists and glyph_id offsets*/ static const lv_font_fmt_txt_cmap_t cmaps[] = { { .range_start = 62087, .range_length = 1, .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY } }; /*-------------------- * ALL CUSTOM DATA *--------------------*/ #if LV_VERSION_CHECK(8, 0, 0) /*Store all the custom data of the font*/ static lv_font_fmt_txt_glyph_cache_t cache; static const lv_font_fmt_txt_dsc_t font_dsc = { #else static lv_font_fmt_txt_dsc_t font_dsc = { #endif .glyph_bitmap = glyph_bitmap, .glyph_dsc = glyph_dsc, .cmaps = cmaps, .kern_dsc = NULL, .kern_scale = 0, .cmap_num = 1, .bpp = 1, .kern_classes = 0, .bitmap_format = 0, #if LV_VERSION_CHECK(8, 0, 0) .cache = &cache #endif }; /*----------------- * PUBLIC FONT *----------------*/ /*Initialize a public general font descriptor*/ #if LV_VERSION_CHECK(8, 0, 0) const lv_font_t A = { #else lv_font_t A = { #endif .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ .line_height = 45, /*The maximum line height required by the font*/ .base_line = 0, /*Baseline measured from the bottom of the line*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = -21, .underline_thickness = 3, #endif .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ }; #endif /*#if A*/ 这太痛苦了,完全看不懂。 所以,换个方式。 RVB2601有一个rtos的例子,里面用的就是lvgl。可以通过创建标签的方式,显示文字: static void gui_label_create(void) { lv_obj_t *p = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK); lv_label_set_align(p, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(p, 0, 0); lv_obj_set_size(p, 128, 64); lv_label_set_text(p, "A"); } 这样就显示了A。   由于没有找到如何让字母变大。所以暂时先给它居中: static void gui_label_create(void) { lv_obj_t *p = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK); lv_label_set_align(p, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(p, 0, 25); lv_obj_set_size(p, 128, 30); lv_label_set_text(p, "A"); }   居中就好看了很多。 接下来,再让A可以从上往下落,首先定义几个变量: lv_obj_t *p; int y=0; int time_for_y=0; 创建方法里,可以看到,标签的y坐标已经改成了变量y static void gui_label_create(void) { p = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK); lv_label_set_align(p, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(p, 0, y); lv_obj_set_size(p, 128, 30); lv_label_set_text(p, "A"); } 这样,在主循环里: time_for_y++; if(time_for_y % 20==0){ y++; } 就实现了A从上往下落 全部代码,包括上一周的: /* * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ /********************* * INCLUDES *********************/ #define _DEFAULT_SOURCE /* needed for usleep() */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <aos/aos.h> #include "aos/cli.h" #include "app_init.h" #include "lvgl.h" #include "lv_label.h" #include "oled.h" /********************* * DEFINES *********************/ #define TAG "app" /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ // GUI static void gui_lvgl_task(void *arg); /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ volatile uint32_t g_debug = 0; volatile uint32_t g_debug_v = 0; static void gui_lvgl_task(void *arg); #include "csi_config.h" #include "board_config.h" #include "drv/gpio_pin.h" #include <drv/pin.h> static csi_gpio_pin_t key1; static csi_gpio_pin_t key2; int button1_pressed = 0;// button1 是否被按下 int button2_pressed = 0;// button2 是否被按下 int time_for_pressed=0;// 按下的时间计数 lv_obj_t *p; int y=0; int time_for_y=0; #include "csi_core.h" /** * main */ int main(void) { board_yoc_init(); aos_task_new("gui", gui_lvgl_task, NULL, 10 * 1024); return 0; } static void gui_label_create(void) { p = lv_label_create(lv_scr_act(), NULL); lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK); lv_label_set_align(p, LV_LABEL_ALIGN_CENTER); lv_obj_set_pos(p, 0, y); lv_obj_set_size(p, 128, 30); lv_label_set_text(p, "A"); } static void gui_lvgl_task(void *arg) { lv_init(); /*Initialize for LittlevGL*/ oled_init(); /*Select display 1*/ // demo_create(); gui_label_create(); csi_pin_set_mux(PA11, PIN_FUNC_GPIO); csi_pin_set_mux(PA12, PIN_FUNC_GPIO); csi_gpio_pin_init(&key1, PA11); csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); csi_gpio_pin_init(&key2, PA12); csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); while (1) { time_for_y++; if(time_for_y % 20==0){ y++; } lv_obj_set_pos(p, 0, y); /* Periodically call the lv_task handler. * It could be done in a timer interrupt or an OS task too.*/ lv_task_handler(); if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) { //当低电平(按下时) if(button1_pressed==0){ // 如果button1的状态没有被按下,则设为按下 button1_pressed = 1; } if(button1_pressed==1){ //如果button1的状态是按下,则计时 time_for_pressed++; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) { if(button1_pressed==1){ // printf("%d",time_for_pressed); //通过判断time_for_pressed的大小,得出是长按还是短按 if(time_for_pressed>20){ //长按 printf("-"); }else{ //短按 printf("."); } time_for_pressed=0;//恢复计数 button1_pressed = 0; } } if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){ button2_pressed=1; } } if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) { if(button2_pressed==1){ printf("\n"); button2_pressed=0; } } aos_msleep(5); lv_tick_inc(1); } } 最后放一个效果:    

  • 2022-03-24
  • 发表了日志: 【平头哥RVB2601创意应用开发】2 实现长按短按

  • 发表了主题帖: 【平头哥RVB2601创意应用开发】2 实现长按短按

    我做的创意有关摩尔斯电码,因此长按短按是必须要实现的。 我参考了群里和论坛里友人发给我的相关文章,实现了gpio的输入。   下面是主要代码: 引入的头文件,以及一些变量的定义: #include "csi_config.h" #include "board_config.h" #include "drv/gpio_pin.h" #include <drv/pin.h> static csi_gpio_pin_t key1; static csi_gpio_pin_t key2; int button1_pressed = 0;// button1 是否被按下 int button2_pressed = 0;// button2 是否被按下 int time_for_pressed=0;// 按下的时间计数 初始化 csi_pin_set_mux(PA11, PIN_FUNC_GPIO); csi_pin_set_mux(PA12, PIN_FUNC_GPIO); csi_gpio_pin_init(&key1, PA11); csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT); csi_gpio_pin_init(&key2, PA12); csi_gpio_pin_dir(&key2, GPIO_DIRECTION_INPUT); 在 while 中循环处理key1 if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) {//当低电平(按下时)   if(button1_pressed==0){// 如果button1的状态没有被按下,则设为按下       button1_pressed = 1;    }    if(button1_pressed==1){//如果button1的状态是按下,则计时       time_for_pressed++;    } }          if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) {    if(button1_pressed==1){//通过判断time_for_pressed的大小,得出是长按还是短按       if(time_for_pressed>20){//长按          printf("-");       }else{//短按          printf(".");    }       time_for_pressed=0;//恢复计数       button1_pressed = 0;    } } 同样,在 while 中循环处理key2(用于换行) if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) { if(button2_pressed==0){       button2_pressed=1;   } }          if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) {    if(button2_pressed==1){       printf("\n");       button2_pressed=0;    } } 演示视频在 【摩尔斯电码的输入-哔哩哔哩】 https://b23.tv/P9xOnx4  

  • 2022-03-17
  • 发表了主题帖: 【平头哥RVB2601创意应用开发】1 开箱及环境搭建

    本帖最后由 cybertovsky 于 2022-3-17 22:17 编辑 感谢 eeworld ,感谢平头哥 。感谢平头哥小助手,感谢群里和论坛里对我答疑解惑的人。 开箱的过程大家都写了,我就简化一下。纸箱很有质感,简约不简单,它有漂亮的电路纹理,激动的我当即掉落一根头发,可惜头发没对齐就拍下来了。 接下来看板子。黑色的PCB彰显了高贵。我平时自己做板子打样都用廉价绿,所以这个黑色我是真喜欢。 不过在端详了GPIO后我被深深的震撼了,我从没见过GPIO上连这么多跳线帽的。所以真不敢贸然拔下来,也不敢贸然上电。 好在找到用户手册,里面有对跳线帽的介绍:37067137319852441601615475227781dm4cDSePeY.pdf (aliyuncs.com)   接下来找到《RVB2601 开发板快速上手手册》: https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3706713731985244160/resource/37067137319852441601617177423292M8r4ixb6nJ.pdf 根据手册指引就可以了。 为了方便,我把需要下载的链接都放上来: 驱动:资源下载 (t-head.cn) 安装完驱动,能看到两个端口,一个是 CKlink,一个是 UART: 开发IDE:资源下载 (t-head.cn) 安装IDE后,新建一个项目,我第一次见到新建项目是web界面联网然后用git进行clone操作的。眼前一亮。 这时项目就建立好了。 然后build:  如果弹出下面的画面,就等全部Finished后再build一次。  像这样,就build成功了:   之后就可以flash了。   不过,我点击flash后,却卡在了这个地方:   试了很多次无果。感谢刘牧儿和想去海边,拉我入群及指导我如何提交工单。于是我提交了工单,大半夜的,平头哥的工程师很快就给了解决方案:     按照解决方案,一条一条去排除和执行。最后,当我开启了debugServer 资源下载 (t-head.cn) 时,flash终于成功了。 并且打开putty看UART,有输出:    同时,屏幕也亮了:   所以,当然是好评了。  

  • 发表了日志: 【平头哥RVB2601创意应用开发】1 开箱及环境搭建

最近访客

< 1/1 >

统计信息

已有16人来访过

  • 芯积分:40
  • 好友:1
  • 主题:12
  • 回复:11
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言