背景(一)

寒假里做了一个灯带控制器:

理想情况下我应该在一个星期内完成这个项目,但实际上它耗费了我几乎一整个寒假,因为涉及到很多未曾尝试的方案。在这种不是很赶时间的、可以自定目标、自由发挥的项目中,我喜欢这么做。

简要介绍一下这个项目。硬件部分:

  • 12V直流电源供电,开关降压到4V,LDO降压到3.3V,三路供电;

  • 使用STM32G030KBT6单片机,基于Cortex-M0+;

  • 12V灯带用异步降压驱动;

  • WS2812B灯带的数据用SPI信号加上一定的逻辑运算生成;

  • OLED屏通过I²C连接单片机;

  • 无定位旋转编码器连接定时器的两个通道。

软件部分:

  • 用多项式拟合把ADC读到的值转换成温度;

  • 指令与数据调度、两级流水线式OLED更新策略;

  • 完全自主设计的简单GUI,包括绘图与控制逻辑。

大约一半时间花在两种灯带的方案验证上,我制作了两块PCB才最终确定以上硬件方案;另有一部分时间花在STM32和HAL的调试上,但这本来就在我的STM32学习计划中;剩下的主要是OLED和GUI,以及写不出来时的摸鱼行为。

我赶在去学校当天的上午完成了项目,在砍掉一点完成度的前提下。有那么几个小时,我很后悔把整个寒假都花在了这个项目上,没有学该学的数学、写该写的博客。但是现在回想起来,这个项目让我对单片机开发有了新的认识。

背景(二)

曾经AVR单片机教程唯一的读者要开始独立做项目了,这是对我文章质量的一次考验。从我们之间的交流来看,我没有通过这次考验——

  • 我说从供电开始思考:通常USB可以提供5V1A,如果需要5V2A,就应该考虑从12V1A转换。她问如何转换,于是我给她介绍了降压转换器。那么如何确定电流呢?主要耗电器件是32个LED。按我的思路,也可以说是绝大多数业内人士的思路,每个灯不会超过20mA,加起来640mA,其余器件耗电忽略,1A肯定是够的。而她的思路是,算出每个LED的等效电阻,并联起来,再计算电流。她又问,如果电源是5V2A,但负载只有5V1A,会烧坏吗?

  • 然后决定用什么灯。两年半以前我送给她一个礼物,用32个LED组成一颗心,灯是红蓝交错的。她想做得比这个高级一点,用32个RGB灯,但这么多灯的连接是个问题,以及RGB三种颜色之间的亮度匹配。又想到WS2812B,它在功能上很强,但是控制稍微麻烦一点。我提示她可以用PWM来生成控制信号,她又搞不清这里的PWM和PWM呼吸灯的区别。

  • 可能是因为在第二期里学过OLED屏和u8g2,在电赛中又用过一遍,又收到了带OLED屏的礼物,她觉得OLED屏很简单,想在项目中也放一块。

暂时不作评价,继续说事。后来又有两人从博客园后台联系我,以成本价拿到了开发板,成为了教程的读者(至此我已经没有多余的开发板了)。一位读者刚开始学C,他常常问我两类我不希望他问的问题(请这位读者不要生气):一类是与单片机无关的纯C语言问题,另一类是与教程进度不符的、我想隐藏的实现细节问题。

他们让我开始反思教程的内容是否充足、顺序编排是否合理。

回顾(一)

他们问我的这些问题,很多也是我曾经困惑的。

预初的那个暑假,我正式学习了C语言。此后,我想写一个C程序来加密文件,把若干字节作为一组处理一下,写进新的文件,就算是加密了。文件长度不一定是整组的,最后一组可能要加入几个空的字节,这种现在看来很基础的控制逻辑,我当时想了很久都写不出来。

我也长期以来不知道电池充电的电流是如何控制的,在我看来把5V电压加到3.7V锂电池上根本不可控啊!后来才知道降压、参考电流、反馈控制之类的。某些营销号还说5V2A充电器给5V1A手机充电会造成损坏,也难怪非专业人士容易受误导了。

高一的那个暑假,我完成了第一个像样的项目,就是前面提到的那颗心。32个LED分别串联470Ω排阻,接到4片级联的74HC595上,用GPIO驱动。放到现在,如果不改变设计目标,我会选择8*4动态扫描的连接方式,还可能用上一片TM16xx来驱动这个阵列。

按下按键切换模式,这个很简单的功能在当时实现得非常乱:先定义一个宏,每次如果按下按键就return,然后在循环中多次调用它。现在我会在定时器中断里处理按键,具体来讲还有多种方法。

这些不懂的问题、不好的实现,都是经验。有些不好的实现,比如上面这个按键,不值得尝试,所以我会在回答相关问题时提供我认为合理的方法。类似的有很多,所以我一直尽力回答每个问题,帮人避雷,也好让我审视一下自己的方法。

回顾(二)

AVR单片机教程的一期介绍了简单外设的用法。我假设读者有良好的C语言基础,所以没有把基础单片机和基础C语言结合起来讲,而是在前几讲的作业题中对读者的C功底提出了较高的要求。针对当时读者的问题,我专门写了一篇元教程,强调了要广泛地了解相关知识。

从按键开始我加快了节奏,否则按照一个LED都能写4篇的速度我现在大概刚刚讲到LCD1602。原计划一期结束后还有大量内容,但是我当时已经不大想写了,所以挑了点必要的组成了第二期的6讲。

现在有读者反映第二期太难,其实不是太难而是两期之间有明显断层。在与读者交流的过程中,我还发现有很多我强调过的点还强调得不够:有些是我没讲清楚,有些是读者真的做不到,比如完成作业——我把很多关键的、实际应用中需要的问题放在了作业中,它们容易被忽略,至少没有被足够严肃地对待。

这些问题,以及上面带有责怪情感的读者提问,都是我的失职。

展望

我决定开始写AVR单片机教程第三期。

首先是查漏补缺,这还得再细分几类:

  • 外设。I²C和定时器输入在前两期的正文中没有涉及到,会在第三期补上。

  • 语言。我不应假设读者有良好的C基础,但我真的没法面对完完全全的新手,所以我将补充一些非单片机编程中不常用的特性,以及高级但实用的用法。

    第三期的很多内容用C++讲起来会更加方便,所以我会简单介绍那些需要用的C++语法,它们也是我在自己项目中常用的C++功能子集。

  • 作业。如前所述,很多重要的内容都在作业里,我将提供解题思路和优化建议。

然后是结构:

  • 与C++绑定起来的对象的概念,包括基于对象与面向对象;

  • 第二期最后提到的事件驱动范式,原本是单独的一期,将成为第三期的一部分;

  • 有些硬件结构可以启发设计(有的可能最初来自软件),包括双缓冲、FIFO、状态机、流水线等;

  • 大型程序和库的结构。

此外,单片机项目的共同问题,比如供电、制板、测试等,也会集中讲解一下。

由此可见,这一期“AVR单片机教程”实际上可以把前三个字去掉,尽管我们还是基于AVR平台讲解。

我设计了新的开发板,与第一版相比缩小了尺寸,去掉了部分扩展资源,使它更加核心。扩展资源被移动到了单独的模块上,多个模块提供不同方向的器件。目前还在设计,并有开放小批量订购的计划。

希望第三期能为读者建立完善的概念,能让读者学会必要的单片机编程方法,在例子中积累经验,独立设计并制作出与文首项目难度相当的单片机系统。

AVR单片机教程——第三期导语的更多相关文章

  1. AVR单片机教程——旋转编码器

    好久没写这个系列了.今天讲讲旋转编码器. 旋转编码器好像不是单片机玩家很常用的器件,但是我们的开发板上有,原因如下: 旋转编码器挺好用的.电位器能旋转的角度有限,旋转编码器可以无限圈旋转:旋转时不连续 ...

  2. AVR单片机教程——数码管

    先解答之前一个思考题:如果不把引脚配置为输出而写高电平,连接LED会怎样? 实验结果是,LED会亮,但相比于输出高电平的情况,亮度很低.这是为什么呢? 通过上一篇教程我们知道,引脚输入输出模式是由寄存 ...

  3. AVR单片机教程——数字输出

    从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取.这一篇教程要讲的是,控制LED的原理是数字信号的输出.数字IO是单片机编程之有别于桌面编程的各项内容中最简单.最基础的. 在讲数字信 ...

  4. AVR单片机教程——数字输入

    我们已经学习了如何使用按键和拨动开关,不知你有没有好奇 button_down 和 switch_status 等函数是如何实现的.本篇教程带你一探究竟,让我们从按键的原理开始. 在原理图中,按键的符 ...

  5. AVR单片机教程——拨动开关

    在按键的上方有4个拨动开关.开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态. <switch.h> 定义了与开关相关的函数.sw ...

  6. AVR单片机教程——按键动作

    上一篇教程中我们学习了如何读取按键状态.而按键的动作,比如单击,至少需要两个状态才能判定,长按.双击的判定更加复杂.今天我们来学习如何使用库函数判断按键单击,以及其实现原理. 我们要实现的是:当一个按 ...

  7. AVR单片机教程——按键状态

    好久没更新了,今天开始继续,争取日更. 今天我们来讲按键.开发板的右下角有4个按键,按下会有明显的“咔嗒”声.如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上.与之前使用的4个LED ...

  8. AVR单片机教程——随机点亮LED

    之前我们做的闪烁LED和流水灯,灯效都是循环的.这次我们来尝试一些不一样的——每一次随机选择一个LED并点亮. 要实现随机的效果,我们要用C语言标准库中的相关设施: #define RAND_MAX ...

  9. AVR单片机教程——流水灯

    上次我们用 delay 函数与 while 循环实现了一个LED的闪烁.这一次我们把所有LED加入进来,让它们依次闪烁,形成流水灯的效果. 开发板上有4个LED,我们可以用不多的语句把循环体直接描述出 ...

随机推荐

  1. 2019牛客暑期多校训练营(第二场)D Kth Minimum Clique(第k团)

    题意:给你n个点 求第k小的团 思路:暴力bfs+bitset压位 #include <bits/stdc++.h> using namespace std; const int N = ...

  2. Educational Codeforces Round 90 (Rated for Div. 2) B. 01 Game(字符串博弈)

    题目链接:https://codeforces.com/contest/1373/problem/B 题意 给出一个二进制串 $s$,Alica 和 Bob 每次可以选择移去 $s$ 中的一个 $10 ...

  3. 使用eclipse写第一个Java_web的hello_world项目

    1.先创建一个Java_web项目 如果你没有下载过Tomcat服务器,不会配置,建议看一下我得这一篇博客:https://www.cnblogs.com/kongbursi-2292702937/p ...

  4. java swing JDialog 和 java.util.concurrent的使用

    参考链接: Java-Swing的JFrame的一些插件使用详解 java swing JDialog 使用 ScheduledExecutorService定时周期执行指定的任务 swing JDi ...

  5. o2,o3优化

    #pragma GCC optimize(2)//O2优化 #pragma GCC optimize(3,"Ofast","inline")//O3优化

  6. PAT L2-016. 愿天下有情人都是失散多年的兄妹 (BFS)

    L2-016. 愿天下有情人都是失散多年的兄妹 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 呵呵.大家都知道五服以内不得通婚 ...

  7. HDU2837 Calculation(指数循环节)题解

    题意: 已知\(f(0)=1,f(n)=(n\%10)^{f(n/10)}\),求\(f(n)\mod m\) 思路: 由扩展欧拉定理可知:当\(b>=m\)时,\(a^b\equiv a^{b ...

  8. mybatis(一)常见ORM框架及JDBC操作工具类

      转载:https://www.cnblogs.com/wuzhenzhao/p/11075569.html 在Java 程序里面去连接数据库,最原始的办法是使用JDBC 的API.我们先来回顾一下 ...

  9. Mysql(三)------事务的特性、事务并发、事务读一致性问题

    1 什么是数据库的事务? 1.1 事务的典型场景 在项目里面,什么地方会开启事务,或者配置了事务?无论是在方法上加注解,还 是配置切面 <tx:advice id="txAdvice& ...

  10. CSS 检测 IE 浏览器

    CSS 检测 IE 浏览器 <!--[if IE]> <link href="ie.css" rel="stylesheet"> < ...