找回密码
 立即注册
楼主: cl_lemon

跟着视频学习32位8051单片机打卡

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-10-27 09:26:29 | 显示全部楼层
神*** 发表于 2023-10-26 20:15
http://www.stcmcudata.com/STCISP/stc-isp-15xx-v6.92D.zip

谢谢管理员捧场
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-10-27 19:48:16 | 显示全部楼层
第9课 - 数码管的静态使用



在前几课分别介绍了LED、按钮开关、蜂鸣器后,
这一课又拿出了一个新设备:数码管。

这个东西在各种家用电器和仪器上都经常使用,

小到酸奶机,大到空调冰箱。
{7CB4392F-FB5D-4954-9D10-A4FA42F761F2}.png



数码管的应用范围广泛,包含了多段LED,并且价格还很便宜,

4位的2块钱包邮,2、3位的2块钱2个,1位的2块钱3个。
{5EB76873-52D4-4B92-9C7B-8F4377C5FEF6}.png



数码管本质上是多个条形LED的并联,但只并联了一端,以使得每段可以自由控制。
而单片机控制数码管,本质上是控制数码管上的多个引脚的输出,让数码管显示不同的式样,
其实不仅能显示0-9,而是可以根据需要显示数字以外的式样,这取决于程序中的控制。


根据数码管内部的连接,数码管分为共阴和共阳,这两种类型的taobao价格相同(颜色上红色以外倒是贵一些)。
具体使用哪种要看电路的设计。
{2BE65CB9-170D-448E-B105-58DEC5C7C282}.png



多段数码管其实是把多个数码管再次并联,原理与单个数码管的内部多段的并联类似,
以减少针脚的使用。
{288F4846-9764-4D8E-A69A-6E3A073A2745}.png



如上文所述,控制数码管其实就是控制数码管的引脚输出,
为了程序的简单,我们不需要为每个引脚单独设置,
而是使用一个数组描述0-9这些数字,这个数组一旦设计好,
就可以一直使用。
{1D27C7F1-5FA8-4A36-A342-B50B0632BC38}.png

代码上直接把数组的某一个数字赋值给引脚变量,就可以控制数码管的显示。
另外也要设置一下数码管的公共级,如下面程序。
{EA0DC25C-E55F-4555-97F8-E444E347E388}.png



综合按键的使用,就可以用数码管和按键编写一个0-9的增加/减少程序,
功能上类似于定时器、或钟表或档位开关,通过两个按钮对数码管的数字进行增减。
{F9164CAC-DBC1-44F5-99ED-BA52008E1BE8}.png

其实在真正的应用中,数码管的显示只是输出,程序内部需要通过改变的变量,
也就是上面程序中的num,去控制设备的功能,使得设备工作在设定的状态。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-10-30 19:33:30 | 显示全部楼层
第10课 - 数码管的动态显示


这一课的感受是,数码管的动态显示其实是为了用少量的控制线控制多个数码管。
比如如果用操作LED的原理去操作数码管,代码会很简单,
但每一个数码管上的灯都需要独立的引脚去控制,
那么4位数码管就需要4*8=32个引脚,8位数码管就需要8×8=64个引脚,
这会让电路变得极其复杂。
(并且TB看了下,市面上也没有卖这么多引脚的数码管)。


因此实现的方法是让所有数码管共用灯段,但这样一来所有数码管又只能显示同样的内容了,
解决的方法是再采用独立的引脚控制数码管的亮灭,只要让数码管循环点亮,
就能在点亮数码管的时候给它要显示的数字。


如图所示,通过快速的刷新,让人眼感觉不到数码管的循环,从而达到多个数码管的控制。
{1D2B8D3B-56F9-46CF-89BF-22144DC9AB1C}.png




不过,代价就是程序比控制单个数码管要复杂一些了。。。

{192929FB-B3F4-4A07-BC27-D43E287F3078}.png



这里讲师介绍了一种灵活的方法,通过数组来定义控制亮灭的寄存器值,
程序只需直接使用这些算好的数字,可以让程序变得简单。
{EDA4D3D9-9F27-4F14-A656-65CE4827380A}.png



这里就是数码管动态显示的核心过程,通过快速的刷新,
在每轮刷新时只激活其中一个(程序中的第num个)数码管,
达到动态显示。
{ACC76A60-BA89-4650-A7E3-0FE1FBF5BB7A}.png



还有一个巧妙的处理就是显示数字,
不像普通编程时只要用printf就可以完成,
单片机上数码管的数字显示需要我们自己算出每一个数码管上的值,
可以巧妙的用除法和余数得到。
{A6E497CD-744E-4F9C-805C-16A14232419C}.png



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-1 16:07:38 | 显示全部楼层
第11课 - 定时器的使用


这一课的内容比想象的多,要使用一个定时器,不仅会接触到定时器的原理,
还有很多寄存器的设置,和中断,以及中断函数。


第一遍看有些烧脑,但再看一遍时差不多能理解其中的脉络了,
写这个笔记时感觉了解的还是不太贯通,待会准备再看第3遍,去整体回顾一下。


定时器虽然使用起来比较复杂,但其实是一个好东西,
通过它可以实现定时和计数功能,并且STC32G提供了5个定时器,
足够开发时的使用。
{9C758CD0-719B-440C-A07C-5D90354DE5CC}.png


顺便了解了一下51单片机的前身,8051单片机只有2个定时器,
而它的加强版8052也只是多了一个定时器,而对比现在的STC32G,

可以看出科技的进步。


在作为定时器使用时,是通过中断来实现时间提醒的,也就是在设置的时间到达时,
会通过中断当前程序,跳转到中断程序中,来完成时间到达时候的任务。
就像学习时水开了,就需要先中断学习,去把水给灌了,再回来学习,这个灌水就是中断。
{454F2D09-E2BB-4813-8B4C-E4BB11B96333}.png



STC32G的每个定时器并不是完全相同的,比如定时器0提供的功能最多,
定时器1少一些,234更少一些,需要编程时根据需求去合理安排。
{14752827-27EE-4F8B-BA50-2B541E6C5F23}.png



这个是定时器寄存器的控制流程图,
定时器的动作收到下面这么多寄存器的控制,
使用时需要合理设定这些寄存器,才能让定时器按照需要执行动作。
{FF8D5C68-EABB-412F-BF41-AB26E4C8C1A0}.png



在代码上也是按照上图的原理,设置定时器的模式、时间值、中断允许等寄存器,
{68F851FB-785F-4D4C-8E1C-D94FE20F12C4}.png

然后在这个定时器的中断中写入我们需要执行的动作,

这里是进行数码管的刷新。
相比上一课中的刷新方法,使用定时器可以在背后完成刷新动作,
而不需要让主程序参与,主程序可以专注更主要的工作。
{873F9D72-3D2D-4AC2-9E7A-3F059DB23A79}.png



正在感叹定时器的设置很复杂时,课程介绍了一个好东西,
stc提供了自动生成定时器程序的工具,只要在界面上设定需要的参数,
就能自动生成这个单片机上的定时器代码,STC真是比用户更了解用户需求啊。
{7C3EF018-D4F9-4BE6-94C1-88098CF4F4BB}.png




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-1 17:24:15 | 显示全部楼层
第12课 - 计数器的使用



这一课是定时器的延伸,在上一课中讲师介绍到定时器可以作为定时器使用,也可以作为计数器使用,
上一课中介绍的是作为定时器去控制数码管的刷新,这一课就是定时器的另一个功能,作为计数器,
去自动统计外部信号的个数。
{8621C0E7-80E1-4D7D-AFDC-13E8A6F243BE}.png



计数器功能可以用在很多地方,比如电动机的测速,或者生产线的传送带上,统计产品一共生产了多少个。


根据视频内容,我的理解是,定时器本质上就是一个计数器,区别在于它的输入源,
如果输入源是单片机内部的频率信号,那么它就是定时器,
如果输入源是单片机外部的脉冲信号,那么它就是计数器。


使用计数器,同样需要设置跟定时器有关的这些寄存器,
虽然个数也不少,但经过上一章的学习后,
这里已经不是难点了,原理上大同小异。
{43F8C7FF-5F9F-4D5F-A064-58174892F0C1}.png



讲座中举了2个例子,第一个例子是使用试验箱上的按键模拟外部信号,
在按下按键时在数码管上输出按键计数,也就是计数器的最基本功能演示,
设计的思路也是灵活使用中断,进入中断表示外部来了一个触发,
在中断函数中对计数器的计数(TimCount)加1,然后根据TimCount的值去更新数码管的显示就可以了。
{F301136A-6034-44B3-9260-66864D3B03F1}.png



讲座中的第2个例子是大学生电子竞赛中的试题,
使用单片机统计电动机的转速,这也是一个计数器的应用,
跟第一个例子相比,稍微有一点改变,就是显示的不是外部信号的总数,
而是单位时间(2秒)内外部信号的个数。
因为电动机每转一圈会产生固定的触发信号,因此单位时间内的计数个数,
就与转速成正比,再除以每一圈的触发次数,就是电动机的转速了。
{9A9F1596-1436-4E0A-8D23-2A61884B7FCE}.png



这一课也有一个彩蛋,就是stc-isp工具的io口配置工具,
其实在原先的课程中就有这个感叹,每个程序设置io口的时候需要查手册,
而通过这个工具,可以很方便的生成需要的设置代码,
既简单又不容易出错。
{3B2326C4-655B-4969-B3C7-0D8E7AE1E899}.png



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-2 12:04:56 | 显示全部楼层
第13课 - 简单多任务处理(上)



学习到这里时,看标题以为是让单片机能像Windows/Linux那样,同时运行多个程序,
这也太黑科技了,为此专门百度了一下,还真有:
{57FC6125-1AAF-4DF8-AAC3-98C5336047A5}.png

看起来挺有趣的,哪天去学习下。


学习以后,知道教程这里的多任务处理,指的是让单片机同时控制多个外设,
实现一个产品中的多个功能,核心知识在于对功能的划分和封装。


之前章节中的内容,核心是介绍如何控制外设,但如果要控制好外设,
不仅在于外设的控制方法,还在于如何对外设功能进行合理的规划,
使用模块对这些功能进行封装,方便主程序使用,这就是本章的内容。


本章内容相当多,一共有4课,我也分上下两部分进行总结。
前面的2课主要集中于对数码管功能的封装,第二课结尾处提到了封装按键的思路。


封装一个外设,与直接控制外设的思路不同,直接控制外设只需要让外设完成这个程序需要的功能就可以了,
而封装外设,需要考虑到当前和今后需要的功能,把这些功能统一封装起来成一个模块,
方便现在和今后的所有使用。


而教程中实现了更广泛的封装,就是把试验箱中的LED也一起实现了,
这个想法很巧妙,因为本质上LED和数码管是同一回事情。
函数如下:
{B73F1CF9-59E1-4387-A8B4-1F6FC8BFC268}.png

头文件:
{50C7CE22-217E-4399-BD24-01D22F77523C}.png



Keil还提供了一些方便编程的功能,比如可以自动重命名函数,
在这里设置后,Keil会把这个函数的所有位置自动更名,比手工搜索替换方便的多,
也不容易出错。
{9219E401-BEEA-4A70-9D19-D83F9DBED875}.png



另外sbit这个关键字也很好用,可以用来单独设置变量的一位。
{54971F21-CD20-4A5D-B75A-CB29C841A231}.png

{76F50F32-8B5E-4FC2-9C6C-4A2BD69B8B9B}.png



函数中可以用static声明设置一个不变的值,
这个值在函数退出再进入时,可以保持上一次的值,
而不像其他变量那样值被丢掉。
{20462933-BA4E-4B22-A5ED-3BECA9E03F8F}.png



之前的按键是单独实现需要的功能,这里进行模块化时,
需要总结按键应用中可能使用到的所有功能,
如单击、防抖、长按等,把它们一起实现起来,
作为一个统一的模块为主程序提供服务。
{40E8AE94-9B89-4FAA-9D72-3F327449FD89}.png


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-3 17:17:18 | 显示全部楼层
第13课 - 简单多任务处理(下)



这一课的后两个部分,最核心的内容是如何实现对按键的处理。
按键处理看起来简单,只要读取状态,但因为按键存在按下、松开、单击、长按、防抖等多种情况,
实际上是一个非常复杂的过程,可以说是从开篇到现在为止,最复杂的逻辑了。


不过也因为这个逻辑复杂,就更能体现模块的威力,
我们花精力把这些复杂逻辑封装成模块,就能把它们限定到模块内部,
让模块默默承担了所有,带来主程序的简便。


键盘模块主要由KEY_Deal和KEY_ReadState这两个函数组成,
KEY_Deal用来读取所有按键的状态,把当前的状态叠加进按键时间的数组中,

来为KEY_ReadState提供判定依据。
KEY_ReadState查看来自KEY_Deal的按键时间数组,并结合其他LastState的值,
最终判别出按键的状态,并通过返回值返回给调用程序。


先来看KEY_Deal,由于要控制的是8个按键,因此使用i生成了8次循环,
每次处理一个按键。
在循环中,根据按键的按下/松开状态进行不同的处理,
如果按键是按下的,则增加Count数组中的按下时间值,
这里要注意如果按键长时间按下,会导致数字超出范围,因此设定了60000的最大值,
因为这个函数10ms运行一次,所以需要600秒才能到达最大值,已经远远超过了现实中需要长按的时间。
如果按键是松开的,则清除按键的按下时间,并且还要根据按键原先的状态,
去判断这一次是从按下到松开的过程,还是按键本来就是松开的,结果放到LastState中。
{D3674F5F-D128-49D8-ACD9-9474016AFA83}.png



后一个KEY_ReadStare函数的判断分两种情况,
当Count[keynum]>0时,说明按键是按下的,
这时根据按键被按下的时间,返回消抖、单击、单击结束、长按、长按结束这5种状态之一。
当Count[keynum]=0时,说明按键是松开的,

这时根据LastState、也就是按键上一次的状态,返回正在松开、早已松开这2种状态之一。

{029059D0-438D-4E6C-9202-F394C4CB6FBA}.png

使用上述两个函数,主程序可以非常方便的获取按键状态,
而不需要象前几课那样,写很复杂的程序了。


模块需要写的更加正规,因为它会被长时间大量使用,
所以注释不可缺少,下面是课程中示范的一个典型注释,
包含跟这个函数有关的各种信息,这相当于函数的说明书,
使用者只需要看注释,而不需要看函数的内容就能使用函数。
就像我们买了收音机,只需要看说明书就能使用,而不需要拆开看电路板一样。
其中函数的功能、输入、输出说明必不可少,其余内容如作者名称,修改时间和版本,
是为了跟踪函数的履历。
{F4153870-BF0F-4428-8E6F-2E0A4F692D9D}.png



后面的蜂鸣器模块,跟这个按键模块比起来,就是小巫见大巫,

经过了按键模块的学习,蜂鸣器的控制要简单的多,毕竟我们只是让蜂鸣器响指定的时间,
而不是要控制蜂鸣器奏乐(这个应该用到无源蜂鸣器了)。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-7 18:51:31 | 显示全部楼层
本帖最后由 cl_lemon 于 2023-11-7 18:53 编辑

第14课 - 矩阵按键



按键控制在很早之前就学习过,但原先学习的是单独的按键,控制比较容易,
但如果按键数量非常多,就需要很多IO口,假设是键盘这种100多个按键,
单片机的IO口根本不够。


因此引入了矩阵按键,仔细想想,在设计思想上,独立按键到矩阵按键的变化,
相当于独立LED到数码管的变化,都是让多个外设共用IO口,让它们形成行列模式,
然后进行控制。


矩阵按键的电路连接本质上根原先学过的多个数码管也很相似:
{2CA92812-2DA9-496A-B397-563CF0F87232}.png



在编程上首先把行输出低电平、列输出高电平,如果有键按下,相应的列会变为低电平。
然后把列输出低电平、行输出高电平,如果有键按下,相应的行会变为低电平。

再把行和列的结果进行组合判断,就知道是哪个键被按下了。
{F2869B1B-875C-4896-AF36-51363C392411}.png



随后的例子中,是使用矩阵按键实现一个密码箱的功能,
这里把按下的键存入一个数组,然后判断数组中的内容是不是与密码相同。
当然这个只是例子,真正的产品还需要能自由设置密码。
{56CE41BB-D491-4C1F-9D9B-57C5BD54E994}.png



说到矩阵按键的不足,就是没法处理多个键同时按下的情况,
因为多个键同时按下时,不同的按法可能在电路上产生相同的信号,
因此无法使用软件来判断,好在这种情况在实际设备上不多,
对于常见的应用,矩阵按键是能胜任的。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:503
  • 最近打卡:2025-05-04 02:31:50

2

主题

30

回帖

2194

积分

金牌会员

积分
2194
发表于 2023-11-8 11:15:57 | 显示全部楼层
第15课 - 外部中断




与前几课中的控制外设不同,这里学习的不是外设,而是MCU内部的中断。
中断的历史由来已久,从最开始的8051,到PC机,以及ARM,都存在这种器件,
正由于中断的存在,才能让MCU与与输入类型的外设通信时,可以在状态变化时及时处理,
同时避免耗时的轮询。


说到轮询,在前面的课程中就是通过轮询来采集按键输入的,
为此程序需要每间隔一段时间查询所有按键的状态,如果轮询较多,
不仅会减慢处理器的处理,也会增加程序的复杂性。
但使用中断可以避免上面的轮询操作,只要在一开始设置好中断寄存器,
按键会在被按下的时候触发中断,MCU会进入中断程序中进行处理,
如果按键没有状态变化,则处理器不需要进行任何额外的查询,
以节省处理器时间。


另一方面,当处理器忙于一个工作时,可能会在一段时间内无法轮询外设,
这就造成外设的数据处理延时,而中断方式不存在上述缺陷,因此能让外设的输入被及时相应。


STC32G细腻单片机提供的中断比我们想像的多得多,
像IO口,定时器,串口,ADC,USB,DMA,I2C等均可以发出中断,
处理器对中断的支持如下表所示,详细的内容需要参考STC手册。
{1FF70E34-6E47-4144-B212-82295645E2AE}.png



{FD0C7E65-6246-4A36-915C-378238B66802}.png



对中断的设置原理上简单,但因为中断源很多,操作这些中断源,
也牵涉到非常多的寄存器,因此编程时需要仔细参考STC手册,
总之手册是一个好东西,进行STC单片机编程时,没有手册寸步难行。
{C30E5C6D-750C-4193-95EF-7C159B929C41}.png



这一课的例子是使用试验箱中的按键触发INT0外部中断,
然后用中断的方式去进行按键的响应,正如上面说的,
这种方式具有响应及时、程序简单的优势。
大概流程就是:
- 在程序开始时对中断源进行设置
- 在中断ISR中写下中断发生时要进行的处理
{860AA0E7-38D3-4E7F-B8D6-F46E61DA9287}.png



{5E2BB352-5214-4B47-8C08-EE3763C65830}.png



在课程中的实操中,也证明了中断的优点,使用传统的轮询方式时,
程序会在LED转一圈后才检测按键状态,因此造成按键的响应不及时,
但改成中断响应时,按键的结果会随时被响应。
当然我们也可以针对轮询方式进行修改,比如增加轮询的频率,
在进行耗时操作的内部也进行插入轮询代码,或者使用前面学到的定时器去检测按键状态,
但对比下来,中断方式的效率更高,程序也更简便。

回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-4 05:25 , Processed in 0.178132 second(s), 95 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表