网站建设 南昌动漫设计与制作工资

pingmian/2025/10/12 8:37:20/文章来源:
网站建设 南昌,动漫设计与制作工资,佛山茂名网站建设,做平台网站怎么赚钱目录 一 背景说明 二 参考资料 三 MultiButton开源库移植 四 设计实现--驱动按键 五 设计实现--界面处理 一 背景说明 需要做一个通过不同按键控制多级界面切换以及界面动作的程序。 查阅相关资料#xff0c;发现网上大多数的应用都比较繁琐#xff0c;且对于多级界面的…目录 一 背景说明 二 参考资料 三 MultiButton开源库移植 四 设计实现--驱动按键 五 设计实现--界面处理 一 背景说明 需要做一个通过不同按键控制多级界面切换以及界面动作的程序。 查阅相关资料发现网上大多数的应用都比较繁琐且对于多级界面的切换逻辑可读性较差。所幸找到一篇使用开源库 MultiButton 来驱动按键并控制多级界面切换的博文。按图索骥实现了预期的需求。 开源库 MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块作者 0x1abin。这个项目非常精简只有两个文件可无限量扩展按键按键事件的回调异步处理方式可以简化程序结构去除冗余的按键处理硬编码让你的按键业务逻辑更清晰。 MultiButton 支持如下的按钮事件 MultiButton的状态机如下 二 参考资料 【1】MultiButton开源库mirrors / 0x1abin / MultiButton · GitCode 【2】MultiButton博文MultiButton | 一个小巧简单易用的事件驱动型按键驱动模块-CSDN博客 【3】MultiTimer开源库mirrors / 0x1abin / MultiTimer · GitCode 【4】MultiTimer博文【嵌入式开源库】MultiTimer 的使用一款可无限扩展的软件定时器_multi_timer-CSDN博客 【5】MultiButtonMultiTimer菜单操作博文开源按键组件MultiButton支持菜单操作(事件驱动型)-阿里云开发者社区 【注】我下面的实现没有用到MultiTimer仅单列出来备查。 三 MultiButton开源库移植 从上面的开源库或者github下载该开源库主要用到就两个文件 multi_button.c/multi_button.h 。将这两个文件直接添加到自己的工程中并关联头文件。 到这边编译应该没有问题。 四 设计实现--驱动按键 【1】首先初始化自己用到的几个按键GPIO口 void KNOB_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin KNOB_1_PIN | KNOB_2_PIN | KNOB_3_PIN | KNOB_4_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(KNOB_PORT, GPIO_InitStructure); } 【2】由于这边用到了四个按键申请四个按键结构 struct Button knob_1; struct Button knob_2; struct Button knob_3; struct Button knob_4; 【3】编写回调函数绑定按键的GPIO电平读取接口 u8 knobRead(u8 button_id) {switch(button_id){case 0:return GPIO_ReadInputDataBit(KNOB_PORT,KNOB_1_PIN);case 1:return GPIO_ReadInputDataBit(KNOB_PORT,KNOB_2_PIN);case 2:return GPIO_ReadInputDataBit(KNOB_PORT,KNOB_3_PIN);case 3:return GPIO_ReadInputDataBit(KNOB_PORT,KNOB_4_PIN);default:return 0;} } 【4】关联 MultiButton 使用上面的按键结构以及回调函数初始化按键对象 button_init(knob_1, knobRead, 0, 0); button_init(knob_2, knobRead, 0, 1); button_init(knob_3, knobRead, 0, 2); button_init(knob_4, knobRead, 0, 3); 【5】注册按键事件根据实际需要注册按键事件不必一次性全注册我这边只用到点按和长按所以只注册了 SINGLE_CLICK 和 LONG_PRESS_START 两个事件。 其中的回调函数 knobCallback_1/2/3/4 先空着后面需要结合界面切换来实现 button_attach(knob_1, SINGLE_CLICK, knobCallback_1); button_attach(knob_1, LONG_PRESS_START, knobCallback_1); button_attach(knob_2, SINGLE_CLICK, knobCallback_2); button_attach(knob_2, LONG_PRESS_START, knobCallback_2); button_attach(knob_3, SINGLE_CLICK, knobCallback_3); button_attach(knob_3, LONG_PRESS_START, knobCallback_3); button_attach(knob_4, SINGLE_CLICK, knobCallback_4); button_attach(knob_4, LONG_PRESS_START, knobCallback_4); 【6】启动按键 button_start(knob_1); button_start(knob_2); button_start(knob_3); button_start(knob_4); 【7】将上面【4】【5】【6】的三个步骤整个成一个按键注册接口 void KNOB_Reg(void) {button_init(knob_1, knobRead, 0, 0);button_init(knob_2, knobRead, 0, 1);button_init(knob_3, knobRead, 0, 2);button_init(knob_4, knobRead, 0, 3);button_attach(knob_1, SINGLE_CLICK, knobCallback_1);button_attach(knob_1, LONG_PRESS_START, knobCallback_1);button_attach(knob_2, SINGLE_CLICK, knobCallback_2);button_attach(knob_2, LONG_PRESS_START, knobCallback_2);button_attach(knob_3, SINGLE_CLICK, knobCallback_3);button_attach(knob_3, LONG_PRESS_START, knobCallback_3);button_attach(knob_4, SINGLE_CLICK, knobCallback_4);button_attach(knob_4, LONG_PRESS_START, knobCallback_4);button_start(knob_1);button_start(knob_2);button_start(knob_3);button_start(knob_4); } 【8】至此按键驱动还不能生效还需要添加一个心跳一般采用5ms间隔定时器来循环调用这个心跳函数定时器相关函数如下 //Timer14 5ms定时器 #define TIMER14_ARR (500-1) #define TIMER14_PSC (960-1)void Timer14_Config(void) {TIM_TimeBaseInitTypeDef TIM_StructInit;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM14, ENABLE);//使能定时器时钟//定时器基础配置TIM_StructInit.TIM_Period TIMER14_ARR; //自动重装值TIM_StructInit.TIM_Prescaler TIMER14_PSC; //预分频系数TIM_StructInit.TIM_ClockDivision TIM_CKD_DIV1; //时钟分频TIM_StructInit.TIM_CounterMode TIM_CounterMode_Up;//向上计数TIM_StructInit.TIM_RepetitionCounter 0; //不重复计数TIM_TimeBaseInit(TIM14, TIM_StructInit);//NVIC中断配置NVIC_InitStructure.NVIC_IRQChannel TIM14_IRQn;NVIC_InitStructure.NVIC_IRQChannelPriority 3; //数字越小优先级越高NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStructure);TIM_ClearFlag(TIM14, TIM_FLAG_Update);TIM_ITConfig(TIM14, TIM_IT_Update, ENABLE); //使能更新中断TIM_Cmd(TIM14, ENABLE); }extern void button_ticks(void); void TIM14_IRQHandler(void) {if(TIM_GetITStatus(TIM14, TIM_IT_Update) ! RESET){button_ticks(); //旋钮驱动心跳TIM_ClearITPendingBit(TIM14, TIM_IT_Update);} } 【9】在主函数的初始化中加上上面几个接口 void main(void) {//定时器初始化Timer14_Config();//旋钮初始化/注册KNOB_Init();KNOB_Reg();while(1){//...} }至此MultiButton 开源库移植完毕并将所用的四个按钮关联到 MultiButton 按键事件待扩展。 五 设计实现--界面处理 【1】新建头文件新增界面相关的结构体定义等 typedef enum tagMenuTree //菜单树 {MENU_MAIN 0,MEUN_LOG }MENU_TREE;typedef enum tagEventCode //事件值 {NULL_EVENT 0,KNOB_1_SHORT 1,KNOB_1_LONG 2,KNOB_2_SHORT 3,KNOB_2_LONG 4,KNOB_3_SHORT 5,KNOB_3_LONG 6,KNOB_4_SHORT 7,KNOB_4_LONG 8 }EVENT_CODE;typedef struct tagMenuInfo //界面信息 {u8 cur_page; //正在执行的界面u8 knb_evnt; //当前触发的事件 }MENU_INFO; extern MENU_INFO menu;extern void Menu_Init(MENU_INFO *handle, u8 p_page, u8 p_evnt); extern void Set_Menu(MENU_INFO *handle, u8 p_page); extern u8 Get_Menu(MENU_INFO *handle); extern void Set_Event_Code(MENU_INFO *handle, u8 p_evnt); extern int Get_Event_Code(MENU_INFO *handle); extern void Menu_Handler(MENU_INFO *handle); 【2】新建源文件新增界面相关的接口函数等 /************************************************************************** * 函数名称 Menu_Init * 功能描述 菜单初始化 **************************************************************************/ void Menu_Init(MENU_INFO *handle, u8 p_page, u8 p_evnt) {memset(handle, 0, sizeof(MENU_INFO));handle-cur_page p_page;handle-knb_evnt p_evnt; }/************************************************************************** * 函数名称 Set_Menu/Get_Menu * 功能描述 菜单跳转/获取当前菜单 **************************************************************************/ void Set_Menu(MENU_INFO *handle, u8 p_page) {handle-cur_page p_page; }u8 Get_Menu(MENU_INFO *handle) {return handle-cur_page; }/************************************************************************** * 函数名称 Set_Event_Code/Get_Event_Code * 功能描述 设置当前事件值/获取当前事件值 **************************************************************************/ void Set_Event_Code(MENU_INFO *handle, u8 p_evnt) {handle-knb_evnt p_evnt; }int Get_Event_Code(MENU_INFO *handle) {return handle-knb_evnt; } 【3】结合上述菜单处理函数关联“设计实现--驱动按键”中的【5】完善 knobCallback_1/2/3/4 的实现。 主要逻辑就是将按键的动作通过回调传递给菜单结构 menu 单列出knobCallback_1其他按钮的回调一样实现 void knobCallback_1(void *p_btn) {u8 btn_event_val; btn_event_val get_button_event((struct Button *)p_btn); switch(btn_event_val){case SINGLE_CLICK:Set_Event_Code(menu, KNOB_1_SHORT);break ;case LONG_PRESS_START:Set_Event_Code(menu, KNOB_1_LONG);break ;default:break ;} } 【4】菜单处理函数 Menu_Handler 的实现 void Menu_Handler(MENU_INFO *handle) {switch(handle-cur_page){case MENU_MAIN:menuMainHandle(handle-knb_evnt);break ;case MEUN_LOG:menuLogHandle(handle-knb_evnt);break ;default:break ;}Set_Event_Code(handle, NULL_EVENT); //及时将事件清除防止重复触发 } 其中menuMainHandle/menuLogHandle 就是每个界面的具体实现了 void menuMainHandle(u8 p_evnt) {cleanAll(); //清屏//主界面显示switch(p_evnt){case KNOB_1_SHORT:break ;case KNOB_1_LONG:Set_Menu(menu, MEUN_LOG); //进入登录界面break ;default:break;} } void menuLogHandle(u8 p_evnt) {cleanAll(); //清屏//登录界面的显示switch(p_evnt){case KNOB_2_SHORT:break ;case KNOB_2_LONG:Set_Menu(menu, MENU_MAIN); //返回主界面break ;default:break;} } 【5】在主函数的初始化中加上上面界面初始化接口同时界面处理函数置于主循环中执行 void main(void) {//定时器初始化Timer14_Config();//旋钮初始化/注册KNOB_Init();KNOB_Reg();//界面初始化Menu_Init(menu, MENU_MAIN, NULL_EVENT);while(1){Menu_Handler(menu); //界面处理函数LCD_Update(); //用缓存刷新屏幕//...} }至此完成了通过 MultiButton 开源库驱动按键并控制多级界面切换的工作。 上述DEMO中上电默认进入主界面可以通过长按 knob_1 进入登陆界面。在登陆界面中通过长按 knob_2 返回主界面长按的时间可以在 multi_button.h 中设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度网站地图文件小型企业网站建站

一、报名阶段 1. 了解查看招聘信息:查看各类事业编岗位的招聘信息,包括岗位职责、招聘条件、报名时间等。 2. 填写报名表:按照要求填写报名表,包括个人信息、教育背景、工作经历等内容。 3. 提交报名材料:将报名表及…

什么网站从做系统wordpress动画主题

一、.pyc是什么? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在。如果是解释型语言,那…

西安手机网站建设公司seo营销型网站推广

HttpExchange是SpringBoot3的新特性. Spring Boot3 提供了新的 HTTP 的访问能力,封装了Http底层细节. 通过接口简化 HTTP远程访问,类似 Feign 功能。 SpringBoot 中定义接口提供 HTTP 服务 --> 框架生成的代理对象实现此接口 --> 框架生成的代理…

宁乡市住房和城乡建设局网站平面设计去哪里找工作

https://en.wikipedia.org/wiki/Kalman_filter 一、提要 在卡尔曼滤波的相关技术文献中,其数学表达看起来都非常晦涩和不透明。这很糟糕,如果您以正确的方式看待卡尔曼滤波器,它实际上非常简单易懂。这里的叙述简单,先决条件也很简单;您所需要的只是对概率和矩阵的基本了解…

贷款网站源码下载淘宝客网站开发定制

NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写 NPOI下载地址:http://npoi.codeplex.com/ 以下代码仅供参考,请根…

网站服务器租用资质啥叫优化

题意:给你一串数字,最少一个,最多七个,问用这里面的数字能组成多少素数,不重复。 思路:之前还遍历10000000的每一个素数,结果超时,后来发现直接dfs就可以了,只是标记一下做过的数。 …

邢台哪儿能做网站做网络推广好吗

怎样删除GitHub上的项目 第一步:双击GitHub的项目workhard(举例) 第二步:确认项目可以删除,双击settings 第三步:找到 Delete this repository按钮并单击 第四步:在弹出的模态框框中输入需要删除的项目名字&#xff…

ps做网站主页的效果图wordpress主题Linkedin

文章目录 1. 引言2. 实验原理2.1 散列表2.2 线性探测法 3. 实验内容3.1 实验题目(一)输入要求(二)输出要求 3.2 算法实现三、实验设计3.3 代码整合 4. 实验结果 1. 引言 本实验将通过C语言实现基于线性探测法的散列表 2. 实验原理…

交互式网站开发关于景区网站规划建设方案书

安装android studio到最后一步的时候遇见了这个问题 。 android studio安装详见Android Studio 安装 经过查阅多篇博客 把他们的解决方案放在一起一顿操作猛如虎,然后就成了。。。 2篇原文链接我放在这里: Android Studio新建工程时SDK缺少extra-an…

深圳龙岗网站建设哪家好公司深圳华强北鬼市

文章目录 1.内存管理介绍2.常见的几种内存管理机制3.快表和多级页表快表多级页表总结 4.分页机制和分段机制的共同点和区别5.逻辑(虚拟)地址和物理地址6.CPU 寻址了解吗?为什么需要虚拟地址空间? 1.内存管理介绍 操作系统的内存管理主要是做什么? 操作系统的内存…

企业建设官方网站作用及意义wordpress系列教程

昨天收邮件,得知要参加一个产品部的会议,猜想,也许是因为我做的这个产品demo问题。于是昨天忙活到凌晨3点半,结果早上一来才知道又被调戏了。发邮件的MM把邮件误发给我了。悲催啊有木有,困啊有木有!自己还是…

制作公司工作网站创意网站布局

虽然 AAudio 试图提供一种直接的硬件访问途径,但在某些场景下,如处理兼容性问题、使用系统服务(如 AudioFlinger)或者在某些设备上,使用 AudioTrack 可能是最有效或最合适的途径。这并不违背 AAudio 的初衷,因为它的目标是提供高性能的音频处理,而不是避免使用系统服务。…

.电子商务网站建设的核心是网站买东西第三方怎么做

PortalRun 概述PortalRun 函数MarkPortalActive 函数PotalSetIoState 函数FillPortalStore 函数DoPortalRunFetch 函数PortalRunSelect 函数PortalRunMulti 函数MarkPortalDone 函数 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的…

网站备案修改域名校园文化宣传主题网站的建设

本文记录一下在linux上将视频转换成动态gif图片的方法。首先,需要在Linux系统上安装FFmpeg,我会用这个工具去解压从视频中解压出视频帧。下面的指令会解压出独立的视频帧,将它们保存为GIF图片。确保使用诸如("out%04d.gif")的输出文…

中国做民宿的网站青岛济南网页设计公司

一、题目 1、题目描述 假设你是一个专业的狗仔,参加了一个 n 人派对,其中每个人被从 0 到 n - 1 标号。在这个派对人群当中可能存在一位 “名人”。所谓 “名人” 的定义是:其他所有 n - 1 个人都认识他/她,而他/她并不认识其他任何人。 现在你想要确认这个 “名人” 是…

h5网站建设包括什么义乌哪里有学做网站的

一、前言接上一篇 .NET Core微服务 权限系统工作流(一)权限系统 ,再来一发工作流,我在接触这块开发的时候一直好奇它的实现方式,翻看各种工作流引擎代码,探究其实现方式,个人总结出来一个核心要…

南昌哪家做网站好珠海软件开发公司

第二十七课:数据结构入门 - 数组与链表 学习目标: 理解数组的基本概念和操作。掌握链表的基本结构与特点。学会在C中定义和操作数组和链表。了解数组和链表的基本使用场景。 学习内容: 数组(Array) 概念&#xff1a…

苏州和城乡建设局网站小程序做跳转微网站

近期,电影《孤注一掷》在社交媒体上引起了广泛的讨论,社会各界对于电信网络诈骗案件的关注度日益提升。真实世界中的电诈涉及金额之大、团伙成员之多,往往比电影更甚。为此,国家不断加大对电信诈骗的打击力度,出台《反…

顺义网站优化邯郸做网站多少钱

1、类成员函数访问修饰const,申明和定义中须保持一致; class IntCell{... ; int read( ) const;...} int IntCell::read( ) const { return storedValue } 转载于:https://www.cnblogs.com/wllwqdeai/p/10691130.html

网站建站推广是啥意思dede网站本地访问速度慢

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 一、start_armboot函数简介 uboot第一阶段,start.S文件中进行一系列的SoC内部硬件的初始化,然后长跳转到start_armboot 函数中。 uboot第二阶段,start_armboot函数…