无际老师的单片机框架,深受启发,避免弯路!

最近在朋友圈收到了一个隐藏大佬的信息,可能是受到了我个人影响,无私奉献自己20年以来单片机的学习心得,以下是我们聊天截图:

无际老师的单片机框架,深受启发,避免弯路!

无际老师的单片机框架,深受启发,避免弯路!

无际老师的单片机框架,深受启发,避免弯路!

无际老师的单片机框架,深受启发,避免弯路!

全文共4787字。 我每一个字都读了一遍,我真的有同样的感觉!

今天我也分享给大家,希望对大家有所帮助。

以下是他的原文:

————————————————– ——————-

最近读了无极老师的单片机框架,深受启发。

同时,我也不禁感叹自己的学习历程。 记得从开始学习单片机到现在详细使用已经快20年了。 我借这个平台谈谈我的学习心得,以便让广大单片机爱好者能够更好的掌握。 学会这个技术,少走弯路。

一、关于基础知识

由于我本科专业是雷达,基础课程包括模拟电路、数字电路、高频电路、微波原理等电子基础知识,以及自动控制原理、信号、分析等科目。

那时候的学习是一头雾水,只能解决书本上的一些习题,却解决不了具体的问题,尤其是应用。 脱离实践的知识是抽象的。

现在回想起来,也许是因为当时忍不住去研究具体的理论,才让大脑对知识进一步抽象,变得更加深刻。

幸运的是,当时我对这些科目并没有任何抵触情绪。 当我接触到真实的电子设备后,我发现确实是理论知识的基础才有助于工作更好的实施。

尤其是在大学二年级,我无意中通过单片机选修课打开了嵌入式技术的大门,将想象中的自动控制从抽象变成了具体。 对此我要感谢老师和教授。

那么这些基础课程对单片机会有什么影响呢? 我来说说我自己的看法。

1.1 硬件

我们目前接触到的计算机大部分都是数字计算机(这是针对模拟计算机而言的)。 在数字电路课程中,我们学习了组合逻辑电路和时序逻辑电路。 所谓的组合逻辑电路实现基于电路的操作。

这就形成了计算机运算的基础,而时序逻辑电路使计算机具有了“记忆”,也就是所谓状态的历史关联性,它形成了计算机存储和程序运算的基础。

我们从数字电路的角度来看待微控制器或某个微控制器外设。 它利用各种同步信号(包括时钟、触发器等)来改变或获取特定存储空间中的数据。

例如:在单片机内部,PC指针由时钟信号驱动,从指定的RAM空间或程序ROM空间顺序读取指令。 然后微控制器内部的CPU核通过解码指令来实现相关动作。

所有外部设备,包括传感器、存储器、输入输出设备等,都通过建立时序序列与单片机进行通信,并通过读写外设内部存储空间来完成相关功能。

如果通过指定的时序完成DS18B20的读写,就可以完成温度的读取,并通过SPI口将每个像素点的颜色信息写入到指定的显示空间地址,与ILI341 LCD通信,完成显示器。 通过设置 AD 寄存器启动 AD 转换并通过寄存器读回等等。

1.2. 软件

当我第一次学习微控制器时,我使用的是汇编语言。 现在我除了BootLoader之外很少使用汇编,但正是汇编语言的学习让我真正理解了计算机底层逻辑工作原理。

特殊寄存器、累加器、B寄存器、程序状态字、程序计数器PC,它们如何相互配合完成运算,立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址等寻址方式也是基础C语言指针。 (顺便说一句:当我尝试参加计算机三级考试时,我第一次在PC组装测试上卡住了。学习单片机后,我满分通过了)。

同时,正是对汇编的学习,让我对中断处理有了深刻的认识。 当中断发生时,需要“保护现场”。 这时候需要入栈,当场景恢复时,需要出栈操作。 这就是后面操作系统中提到的任务切换的实际动作。

综上所述,打好学科基础是非常有必要的。

我们在大学里学到的知识在学校里可能会脱离现实,仅限于解决问题。 但是,当你积累了大量的理论知识后,你在实际工作中就会有明确的理论支撑,并且可以让你更快地熟悉工作。

2.关于开发板

初学者面临的第一个问题是如何选择开发板。 我认为应该遵循经济适用的原则。

现在争议很多:要不要先学51、到底要不要学51、直接从stm8还是stm32开始学习、要不要用arduino、用arduino会不会被人看不起、arduino是否适合初级在校学生,是否有必要不要买Raspberry Pi。 ESP32现在很流行。 你想学习ESP32吗? stm32选择点原子好还是野火好?

当然,有人说,与其买开发板,不如买一块核心板,然后从面包板开始构建。

我想想学习单片机的人目的不同,无法给出一个通用的答案。 只要在个人经济承受能力范围内,购买外围齐全的开发板也是一个不错的选择。

如果您愿意,可以从核心板或穿孔板开始。 只要我们学点东西,淘宝上有很多开发板,而且都附带很多教程。

然而,这里的教程都集中在某个功能和外设上,例如单个外设的按钮、串行端口和其他例程。 目的是让学习者掌握某类外设的应用,并根据自己的需要进行综合。

另一种是像无极老师,他把自己的项目案例制作成开发板,进行针对性教学,从外设到架构一起学习。 我们稍后会讨论架构。

一般电子爱好者都会有很多开发板。 就我而言,我使用51、AVR、LGT、arduino、STM8、STM32、ESP8266、ESP32等开发板。

外设也多种多样,只要能满足需要的就是最好的。 尤其对于个人来说,只是用来学习的,而不是用来做产品的。 他们基本上不考虑芯片的成本,也不关心那几分钱。 产品层级下的利润放大效应。

使用起来是否方便取决于芯片的支持是否完善。 比如STM32之所以流行了这么多年,就是基于其良好的开发生态系统。 从STD到HAL到cubuMX,从jlink到stlink,跟踪调试非常方便。 它已经完成了从STD到HAL再到cubuMX的一切。 面向寄存器的编程到面向函数的编程。

以前使用51、AVR单片机时,都是逐个寄存器写入,多采用位操作等,但是到了STM32、STM8单片机,厂家提供了标准库。

你只需要知道配置哪个功能即可,除非必要,否则不会配置具体的底层寄存器。 尤其是对于32位单片机来说,一点点配置起来会相当麻烦(暂且不谈效率问题)。

对于只需要更多关注功能实现的开发者,ST推出了STM32cubeMX,方便配置初始化。

当然,类似功能的软件还有很多。 不专门写驱动的工程师现在越来越少涉及底层了。 关于ST的标准标准外设库,可以看我写的这篇文章。

另一件需要考虑的事情是开发环境。 比如现在最常用的就是51、stm32等的Keil环境,当然还有AVR开发的WinGCC、AVRStudio等,还有Arduino等芯片的图形化编程引擎,比如Mixly、等等,现在也有了51单片机的图形化编程引擎。

图形编程引擎的使用降低了编写代码的成本。 人们只需要拖动一些类似于积木的图形就可以完成程序编写。 Arduino的广泛应用也归功于此,为很多有想法的开发者提供了一种快速简便的方法。 原型制作渠道。

还有编程语言的选择。 大多数开发语言仍然使用C语言。 由于C语言底层运算能力好,效率高,所以学习C语言仍然是主菜。

如今,ESP8266和ESP32等较新的芯片也支持基于Python的编程。 Python编程大多调用现成的库来实现功能。

在使用ESP8266的时候,我也接触到了可以使用LUA语言编程的固件。 您可以将LUA脚本发送到ESP8266来运行它。 对于需要实现简单功能但又不想编写大量代码的人来说,这是一个很好的渠道。

3.关于编程

当您第一次点亮开发板上的 LED 时,编程之旅就开始了。

如果几行代码能够成功编译并上传,我们就可以认为成功了。

但通过我的实践,我认为单片机编程有几个阶段:

3.1 功能实现

这里所谓的功能实现,是指运行各种接口,调整各种外设,从而能够对外部世界有一个客观的认识。

这主要涉及GPIO、中断、定时器、网守、I2C、串口、SPI、CAN、AD、DA等常用功能或总线。

这些接口可用于操作常见的外设,如按钮、LCD、LED、时钟芯片、看门狗芯片、AD芯片、存储芯片等常见外设芯片。

这就是学习单片机的基本操作。 学会了这些功能,基本上就可以上手了。

在这个阶段一定要学习:

① 独立阅读芯片手册

这里的芯片手册包括单片机芯片和外围芯片。 可以通过阅读手册来查询实现功能的寄存器、实现芯片功能的寄存器以及接口协议。 这样,即使遇到从未见过的芯片,也可以编写驱动程序。 芯片使能。

②学习调试

可以使用示波器、万用表、stlinks、jlinks、协议分析仪等外围仪器来检查芯片的工作状态,并且可以使用IDE提供的调试功能设置断点来调试程序。

③积累常用电路

微控制器是一种结合软件和硬件的技能。 作为一名工程师,不仅要能够通过软件实现功能,还要积累硬件电路实现,比如5v、3.3v电源、各种芯片的外围电路等。

在这个阶段,有必要建立对寄存器的客观对象的理解。 正如本文第一点提到的,所有功能实现都是为了读写寄存器。 所有外设都是操作寄存器。

3.2. 功能整合

通过前一阶段的学习,你已经掌握了程序的编写和单一功能的实现。 例如,可以实现串口与PC之间的简单收发通信,能够读取外围传感器发送的物理量信息,能够在各种显示器上显示所需的信息。 字符图形。

第二阶段必须实现上述功能的集成,如通过按钮点亮LED、通过串口点亮LED并显示在液晶屏上、读取DS18B20或SHT11传感器并显示所需数据在液晶屏上,通过定时 制作一个简单的闹钟。

现阶段,底层寄存器的操作基本分离,工程师更关注功能实现。

在此阶段需要满足以下条件:

①功能耦合

简单来说,就是将一个外设获取的信息可靠、及时地传输到另一个功能模块。 例如,如果按键中断获得了按键按下的信号,那么这个信号应该如何传递给另一个函数呢? ,如:点亮LED,可能有直接调用LED函数、全局变量、回调函数等。

②简单模式

这个阶段大部分程序结构(暂时不提架构)都是顺序执行的,比如

同时(1)

函数1();

func2();

funcn();

程序可以通过简单的条件判断序列向下执行。

此类程序往往具有这样的循环结构:读取输入->判断条件->信息处理->信息输出->再次读取信息。

这里还可以学习基于状态机的模式实现函数。 状态机也是一种非常强大的编程模式。

()

③C语言高级运算

对于使用C语言开发的工程师来说,这个阶段必须掌握并熟练使用头文件、宏定义、结构体、联合体、指针(包括变量指针、函数指针和指向指针的指针等)、数组(一维和多维和高维)、链表、malloc等C语言中比较高阶的操作。

3.3 架构设计

当功能需求越来越复杂,通过第二阶段无法满足时,就必须考虑程序架构了。 嵌入式系统的要求是实时性能和对外部输入更有效的响应。

如何才能更高效地利用芯片,而不是被延迟等软件延迟填满? 当程序实际延迟时,它会重复完成累积的任务,而其他任务仍在等待。

这就需要一种能够高效利用内核时间并实时响应系统输入的架构。 当然,前后台模式的程序也可以实现,但成熟的架构应该是可移植和通用的。

这里有两种选择:一是使用各种嵌入式操作系统,比如RT-Thread、ucOS、FreeRTOS等。

另一种是采用无极老师的程序架构,具有任务调度功能。

这种架构下的编程将重要的工作转移到了任务规划和任务通信上。

①任务规划

在操作系统中,所谓任务规划就是将面向过程编程中的各个功能变成一个相对独立的任务(或线程),其中只完成一个功能,如:LED显示任务、键盘扫描任务、显示任务。

每个任务只完成自己的功能。 例如,显示任务仅显示在LED或LCD上。 具体显示是其他任务通过通信机制告诉的。

如果系统是基于优先级的操作系统(而不是基于时间片轮询的操作系统),则还存在优先级问题。

即每个任务获得的CPU权限级别。 例如,如果需要同时执行多个任务,则应先运行优先级高的任务。 在这些任务中,实时性强的任务应该最先得到系统的响应,因此应该有较高的优先级。

②任务间的通信设计

任务之间的通信用于维持任务之间的同步和信息传递,通常包括信号量、邮箱、信号等。这里我们要考虑采用哪种合适的方法来同步任务或向另一个任务传递信息,比如当按下一个按钮后,使用信号量同步任务还是使用邮箱传递,是否将显示信息放入邮箱中同步到显示任务还是通过信号量发送等。

以上内容可以参考周立功的ucos教程来学习。

对于不采用嵌入式操作系统的前后端模式的调度系统来说,关键在于系统调度。 系统调度的本质就是切换不同线程使用的各种寄存器和局部变量。 当任务A切换到任务B时,需要将任务A的系统状态保存到堆栈中,将任务B的系统状态从堆栈中取出并继续执行,如此循环。

任务调度还涉及到原子锁操作、任务调度效率、优先级确定等,都需要考虑。 这里要设计无极老师的框架,这是一个经过实践检验的结构。 如果你有兴趣开发自己的调度框架,可以先阅读ucOS等优秀成熟的嵌入式系统内核,然后从任务调度的核心开始。

对于一个成熟的产品或项目来说,可靠的电路设计和稳健的流程是必要的保证。 当一个程序进入实际制作阶段时,必须采用各种手段来保证其稳定性。

大家常说的单片机不仅指单片机芯片本身,还指其背后的嵌入式系统。 嵌入式系统博大精深。 本文我仅根据自己的学习经历和单片机知识谈一些看法。 还请各位朋友批评指正。

单片机

为啥要用“树莓派”?:实现树莓融合的利器

2024-5-6 18:06:49

单片机

北京工业职业技术学院专业、北京市特色高水平专业时代机遇

2024-5-6 19:02:39

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索