YOLObing 发表于 2024-12-12 18:52:52

AI8051U学习心得打卡记录+基于AI8051U开源创意电子设计大赛

<h1>缘起</h1>
<p>虽然大学读的是自动化专业,嵌入式单片机之类也算是专业课程,但毕业后并未从事相关工作,也就逐渐荒废。读书时记得是从8086开始学习汇编,然后学习C语言,自学了郭天祥老师的8051单片机,STM32学了点灯就毕业没管他了然后就止步于此,实在惭愧。</p>
<p>但对嵌入式一直怀有兴趣,苦于无从事相关工作,学习无从下手。前年开始接触到立创开源平台,接触到开源项目,又了解到嘉立创的免费打样服务,对于我这样的爱好者真是福音,重新对嵌入式软硬件燃起了兴趣。</p>
<p>这次也是参加了嘉立创和国芯一起举办的基于AI8051u开源创意电子设计大赛,跟着实验箱照着画了块开发板,这几天也在加紧焊接,争取尽早结项。</p>
<p>接下来一段时间就跟着冲哥的视频,一起来学习AI8051u这款芯片,体会国芯的强大之处,也希望学有所成。</p>
<p><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&amp;tid=11902">《8051U深度入门到32位51大型实战教学视频》</a></p>
<h1>第一集</h1>
<p>首先感谢国芯的支持,之前也是申请到了五颗Ai8051u的样品,今天还收到了这次申请的擎天柱核心板,配合自己制作的开发板,肯定事半功倍。</p>
<p>进入正题,先来一遍口号:哪怕梦想让我们拼得遍体鳞伤,这一次我们也要勇往直前。</p>
<p>本集内容主要介绍了ai8051u的强悍之处</p>
<p><strong>Ai8051U-LQFP48  比普通 M0/M3,比 32F103C8T6 强太多的地方:</strong><br />
1,Ai8051U有TFPU@120MHz, 算力比他强, uS级硬件三角函数/浮点运算器;<br />
2,Ai8051U的抗干扰比他强;<br />
3,  Ai8051U的内部复位是专业级的复位电路,彻底省外部复位;<br />
4,  Ai8051U的内部时钟完全满足串口通信要求,4组串口;<br />
5,Ai8051U-LQFP48有 QSPI, i8080/M6800-TFT 接口,32F103C8T6没有;<br />
6,  Ai8051U的PWM支持硬件移相@120MHz<br />
7,Ai8051U是 34K SRAM, DMA 支持 外设直接到外设,P2P<br />
8,Ai8051U是 自带硬件USB, 1个芯片就能直接USB连接电脑仿真/下载,全球唯一</p>
<p>价格也是相当亲民。</p>
<p>并通过六个示例视频演示了几个功能,更加直观地展示了这颗芯片的强大:</p>
<p>1、屏幕显示(刷新速度快,8080并口)</p>
<p>2、触摸屏程序,手写屏</p>
<p>3、IIS录放音,需要外接扬声器,音量可调最高80</p>
<p>4、PWM-DMA功能,ws2812点阵显示时钟。最高可支持到1000多颗灯同时控制,牛</p>
<p>5、频谱分析仪,需要用到FFT绘图,可以查看频率数据</p>
<p>6、手写计算器,这个看起来就很厉害,也是这颗芯片强大的体现</p>
<p>7、最后演示了猫和老鼠的视频播放,串行flash编程功能的演示。</p>
<p>Ai8051U,USB 型 1T 8051,支持32位和8位指令集, RMB2.3<br />
<strong>管脚兼容天王级别的:  89C52RC,  12C5A60S2</strong><br />
要兼容 8位8051指令集,  可以用 Keil C51/IAR/SDCC 编译器<br />
===就相当于更强大的 8H8K64U要兼容 32位8051指令集,可以用 Keil C251 编译器,双核兼容设计<br />
<strong>===就相当于更强大的 32G12K128, 32G8K64</strong><br />
34K SRAM(2K edata, 32K xdata), 64K Flash<br />
TFPU@120MHz, 硬件浮点/硬件三角函数 运算器DMA支持PWM, DMA支持外设直接到外设, P2P<br />
120MHz-PWM支持硬件移相,16位PWM; 真12位ADC<br />
USB, 4组串口,12位ADC, 轨到轨比较器<br />
QSPI, SPI, I2S, I2C,  TFT-i8080/M6800 接口<br />
PDIP40,LQFP44,LQFP48</p>
<h2>擎天柱</h2>
<p>刚收到擎天柱就迫不及待上电测试,自带流水灯程序,测试正常后把预留的各个IO口led指示灯焊接上,方便后面点灯和测试,点了排灯,插针今晚焊上</p>
<p><img src="data/attachment/forum/202412/12/185114h9haha1hofanhuqj.jpg" alt="1d4ac15fb9b67c684c691802ea1305a.jpg" title="1d4ac15fb9b67c684c691802ea1305a.jpg" /></p>

YOLObing 发表于 2024-12-12 20:37:36

<h1>第二集</h1>
<h2>本集主要介绍了实验箱各部分的名称,作用等</h2>
<p><img src="data/attachment/forum/202412/12/201622mm3kzl833tk4k30m.png" alt="1734005769369.png" title="1734005769369.png" /></p>
<p><img src="data/attachment/forum/202412/12/201700h6kc5k777gmkrm76.png" alt="1734005805082.png" title="1734005805082.png" /></p>
<p>**从图上五花八门的功能就可以看出这个实验箱的强大,堪称百宝箱了,开发利器啊<img alt="ciya" class="emoji" src="https://www.stcaimcu.com/static/image/smiley/default/ciya.gif" title="ciya" /> **</p>
<p>硬件讲完就轮到软件部分,冲哥视频很贴心地给出了具体步骤和操作方法,属于是手把手教了。</p>
<p>第一步:下载安装keil C251编程软件,简单填写信息便可下载</p>
<p>第二步:下载ISP软件,时刻保持最新版,此软件也是包罗万象,功能强大,后面再深入学习。</p>
<p>第三步:添加头文件。有了ISP软件,便可为keil编程软件添加STC单片机的头文件,不然就无法选择芯片和编程了</p>
<p>第四步:下载中断插件拓展,直接双击便可自动安装</p>
<p>第五步:下载代码包和手册。里面有程序源码和实验箱的说明手册,我也快速浏览了下说明书,基本了解了实验的硬件组成和下载仿真方法,ISP下载程序的方法和手头的擎天柱一样,均是按下P32/INT0后按下POWER电源开关(按下断电)等待软件识别到HID后便可松开P32,便可继续下载。当然这只是其中一个下载方式</p>
<p><img src="data/attachment/forum/202412/12/203701c85ku5tx7xhxuygx.png" alt="1734007016846.png" title="1734007016846.png" /></p>

YOLObing 发表于 2024-12-12 22:39:27

<h1>第三集</h1>
<h2>本集主要介绍了如何新建工程,添加头文件,编写代码并编译下载</h2>
<h3>1、创建新工程,参考芯片手册6.5,打开keil软件,新建工程文件,选择芯片,新建main.c文件并添加进工程</h3>
<p><img src="data/attachment/forum/202412/12/220743dpnlnr8n8cnieihp.png" alt="1734012455375.png" title="1734012455375.png" /></p>
<p><img src="data/attachment/forum/202412/12/220900c8671mecsi008uu1.png" alt="1734012531240.png" title="1734012531240.png" /></p>
<h3>2、配置工程,点击小锤子进入工程配置</h3>
<p>配置“CPU mode” 为source(c521 native)模式,勾选4 byte interrupt frame size;</p>
<p>配置“memory model”为XSmall模式;</p>
<p>配置“code rom size”为large或huge模式;</p>
<p>同时设置output选项卡里勾选“create HEX file”,选择“HEX-80”</p>
<p><img src="data/attachment/forum/202412/12/221534woxzso15vnn73vnx.png" alt="1734012930170.png" title="1734012930170.png" /></p>
<p><img src="data/attachment/forum/202412/12/221556r3ncnssb4phbphez.png" alt="1734012950794.png" title="1734012950794.png" /></p>
<h3>3 添加头文件</h3>
<p>头文件到万能的ISP软件找到头文件选项卡,选择对应芯片型号并下载保存到文件夹目录下,然后程序便可引用头文件,推荐使用“”引用,系统编译时会先从文件目录下查找头文件,方便他人使用程序</p>
<p><img src="data/attachment/forum/202412/12/221916t3glyq1z2orbogpx.png" alt="1734013150290.png" title="1734013150290.png" /></p>
<p>添加引用头文件,并写入一个空循环程序,编译正常无报错,代表工程新建完成无错误,接下来就可以愉快地编写程序了</p>
<p><img src="data/attachment/forum/202412/12/222721qnirpfferkwtazit.png" alt="1734013634130.png" title="1734013634130.png" /></p>
<h3>点灯:我们先直接敲入代码,编译并下载观察现象再学习每句程序表示什么意思</h3>
<p>实验现象</p>
<p><img src="data/attachment/forum/202412/12/223052nc4j92j1a7pe92ww.jpg" alt="085f782bbc698e2c409cd2a77f11e07.jpg" title="085f782bbc698e2c409cd2a77f11e07.jpg" /></p>
<p>可以看到擎天柱的P40和P00 引脚的led灯亮起来了。冲哥视频里则是LED00灯亮起来,查看实验箱原理图可知</p>
<p><img src="data/attachment/forum/202412/12/223303zmspjm4pdxv2ce24.png" alt="1734013976310.png" title="1734013976310.png" /></p>
<p><strong>要点亮实验箱上的led00,首先需要将P40引脚电平拉低,三极管导通,然后拉低P00引脚电平,进而led00形成回路,电流流过点亮。</strong></p>
<p><img src="data/attachment/forum/202412/12/223502t81k2nxq81nqd1dk.png" alt="1734014093505.png" title="1734014093505.png" /></p>
<p><img src="data/attachment/forum/202412/12/223516qaatptw7h8tqq8hh.png" alt="1734011823990.png" title="1734011823990.png" /></p>
<p><strong>查看芯片手册,可以看到程序一开始先把p0和p4端口配置为准双向口,然后拉低对应引脚电平。</strong></p>
<p><strong>冲哥视频也展示了ISP软件的io口配置功能,我们可以直接选择各个io口需要配置的模式,然后软件便会生出代码,只需复制即可,有点STM32CUBE MX的意思了,太强大了</strong></p>
<p><img src="data/attachment/forum/202412/12/223823xghwo6zqwh5wzw5w.png" alt="1734014297600.png" title="1734014297600.png" /></p>

YOLObing 发表于 2024-12-16 18:52:10

<h1>自己照开源的实验箱copy的开发板也完成了,可以尝试更多实验了<img src="data/attachment/forum/202412/16/185054ii7xohkvckpkvsw4.jpg" alt="36826ccd4182040f62da206f9f70c38.jpg" title="36826ccd4182040f62da206f9f70c38.jpg" /></h1>

YOLObing 发表于 2024-12-16 20:01:01

<h1>第四集 USB不停电下载</h1>
<h2>本集主要介绍了另外一种下载程序的方法</h2>
<p>1、实验对比演示,不停电下载需要有类似引导代码的程序段,主要打开了USB中断和中断处理函数</p>
<p>2、下载所需文件,到官网下载库函数及例程,介绍CDC和HID的区分</p>
<p>3、移植关键部分:添加头文件;lib+h库实现USB初始化函数;命令参数,默认为STCISP,可以自定义修改;</p>
<p>打开P_SW2寄存器和IE2寄存器(只打开一个位,通过位与操作)</p>
<p>这样,我们就拥有了一个自持不断电下载的DMEO程序,以后可以直接复制此工程,然后再添加新代码,这样修改重新编译下载时就可以不停电下载了。</p>
<p>开始实战,视频演示的是轮询模式下STC-CDC的程序移植,尝试一下中断模式下STC-CDC的程序移植</p>
<p>首先还是复制上次的led工程文件到新文件夹中,然后添加lib和h库文件</p>
<p><img src="data/attachment/forum/202412/16/193451a81b17147j4a1010.png" alt="image.png" title="image.png" /></p>
<p>添加lib文件到工程目录下,并复制相应代码到DEMO工程下,程序简单点亮第1、3、5、7个led灯,第一次依旧用hid模式下载,成功点亮,修改代码,点亮第2,4,6,8个led灯,成功实现不停电下载功能</p>
<p><img src="data/attachment/forum/202412/16/195817xwjjjo22yorjjhcf.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/16/195845to6ggboysadjtbaz.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/16/195948y7ekwd4dl1c2y1d1.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/16/200023id88ajxkx00e0h0s.jpg" alt="a2718e563f0e284b61a82f683fbe4d4.jpg" title="a2718e563f0e284b61a82f683fbe4d4.jpg" /></p>
<p><img src="data/attachment/forum/202412/16/200038g2y1vz1zu9c3uc7s.jpg" alt="61e15c9d2520435293a3dfe450a75e9.jpg" title="61e15c9d2520435293a3dfe450a75e9.jpg" /></p>
<p>不停电下载成功</p>

YOLObing 发表于 2024-12-16 20:51:04

<h1>第五集 C语言基础</h1>
<h2>主要内容,恶补C语言,编程语言是基础</h2>
<p>1、C语言-printf函数的实现;</p>
<p>2、数的进制:二进制,十进制,十六进制;</p>
<p>3、数据的基本类型;</p>
<p>4、C语言的常用运算符。</p>
<h3>1、C语言-printf函数的实现;</h3>
<p>取消注释,便可打开printf的功能。</p>
<p>#define PRINTF_HID            //printf输出直接重定向到USB口(早期命名方式)</p>
<p><img src="data/attachment/forum/202412/16/201949se69edk1pp7hu71t.png" alt="image.png" title="image.png" /></p>
<p>printf函数称为格式输出函数,其关键字最末一个字母f即为“格式”(format)之意。其功能是按用户指定的格式,把指定的数据显示到显示器屏幕上。</p>
<h2>printf函数调用的一般形式</h2>
<p>printf函数是一个标准库函数,它的函数原型在头文件“stdio.h”中。但作为一个特例,不要求在使用 printf 函数之前必须包含stdio.h文件。printf函数调用的一般形式为:<br />
printf(“格式控制字符串”, 输出表列)<br />
其中格式控制字符串用于指定输出格式。格式控制串可由格式字符串和非格式字符串两种组成。格式字符串是以%开头的字符串,在%后面跟有各种格式字符,以说明输出数据的类型、形式、长度、小数位数等。如:</p>
<ul>
<li>“%d”表示按十进制整型输出;</li>
<li>“%ld”表示按十进制长整型输出;</li>
<li>“%c”表示按字符型输出等。</li>
</ul>
<p>非格式字符串原样输出,在显示中起提示作用。输出表列中给出了各个输出项,要求格式字符串和各输出项在数量和类型上应该一一对应。</p>
<h2>格式字符串</h2>
<ol>
<li>类型<br />
类型字符用以表示输出数据的类型,其格式符和意义如下表所示:</li>
</ol>
<table>
<thead>
<tr>
<th>格式字符</th>
<th>意义</th>
</tr>
</thead>
<tbody>
<tr>
<td>d</td>
<td>以十进制形式输出带符号整数(正数不输出符号)</td>
</tr>
<tr>
<td>o</td>
<td>以八进制形式输出无符号整数(不输出前缀0)</td>
</tr>
<tr>
<td>x,X</td>
<td>以十六进制形式输出无符号整数(不输出前缀Ox)</td>
</tr>
<tr>
<td>u</td>
<td>以十进制形式输出无符号整数</td>
</tr>
<tr>
<td>f</td>
<td>以小数形式输出单、双精度实数</td>
</tr>
<tr>
<td>e,E</td>
<td>以指数形式输出单、双精度实数</td>
</tr>
<tr>
<td>g,G</td>
<td>以%f或%e中较短的输出宽度输出单、双精度实数</td>
</tr>
<tr>
<td>c</td>
<td>输出单个字符</td>
</tr>
<tr>
<td>s</td>
<td>输出字符串</td>
</tr>
</tbody>
</table>
<ol start="2">
<li>标志<br />
标志字符为 -、+、# 和空格四种,其意义下表所示:</li>
</ol>
<table>
<thead>
<tr>
<th>标 志</th>
<th>意义</th>
</tr>
</thead>
<tbody>
<tr>
<td>–</td>
<td>结果左对齐,右边填空格</td>
</tr>
<tr>
<td>+</td>
<td>输出符号(正号或负号)</td>
</tr>
<tr>
<td>空格</td>
<td>输出值为正时冠以空格,为负时冠以负号</td>
</tr>
<tr>
<td>#</td>
<td>对c、s、d、u类无影响;<br/>对o类,在输出时加前缀o;<br/>对x类,在输出时加前缀0x;<br/>对e、g、f 类当结果有小数时才给出小数点。</td>
</tr>
</tbody>
</table>
<ol start="3">
<li>输出最小宽度<br />
用十进制整数来表示输出的最少位数。若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。</li>
<li>精度<br />
精度格式符以“.”开头,后跟十进制整数。本项的意义是:如果输出数字,则表示小数的位数;如果输出的是字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。</li>
<li>长度<br />
长度格式符为h、l两种,h表示按短整型量输出,l表示按长整型量输出。</li>
</ol>
<h3>2、数的进制:二进制,十进制,十六进制;</h3>
<p><img src="data/attachment/forum/202412/16/202818x7v8mm02027xkw80.png" alt="" /></p>
<h3>3、数据的基本类型;</h3>
<p>如果需要使用64位变量,需要在程序文件添加声明#program float64</p>
<p><img src="data/attachment/forum/202412/16/203235avsd0zq08lfdf2qf.png" alt="image.png" title="image.png" /></p>
<h3>4、C语言的常用运算符。</h3>
<p><img src="data/attachment/forum/202412/16/204253pflw5kmpuufooow7.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/16/204439ds4psqfupyu1qkpp.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/16/204842lovhcvo6azou45l4.png" alt="image.png" title="image.png" /></p>

YOLObing 发表于 2024-12-17 15:34:43

<h1>第六集 I/O输入输出</h1>
<h2>主要内容 讲解什么事GPIO</h2>
<h3>什么是GPIO?</h3>
<p>GPIO是<strong>通用输入输出端口</strong>的简称,是指计算机或芯片上的一组引脚,可以通过软件来控制其输入和输出电信号。GPIO引脚可以与外部设备连接,实现通讯、控制和数据采集的功能。GPIO引脚有两种输出模式,推挽和开漏,推挽模式是根据P-MOS和N-MOS管的工作方式命名的,可以提高负载能力和开关速度。</p>
<p>ai8051uI/O工作模式共有四种:</p>
<h4>准双向口:</h4>
<p>灌电流20ma和拉电流270-150ua,内部有三个上拉晶体管,强,极弱,弱。</p>
<p>弱上拉在端口寄存器为1,且引脚本身为1打开提供基本驱动电流。在寄存器为1但被外部拉至低时,弱上拉关闭极弱上拉打开。</p>
<p>当端口锁存为1,极弱打开。当引脚悬空时,极弱上拉产生很弱的电流上拉为高电平。</p>
<p>当端口锁存器由0-1跳变时,这个强上拉用来加快转换速度,打开约2个时钟。</p>
<p>准双向口带有一个施密特触发输入和一个干扰抑制电路,读外部状态前,要先锁存为1,才可读到外部正确状态。</p>
<p><img src="data/attachment/forum/202412/17/151033rj63ztb255y6yciq.png" alt="image.png" title="image.png" /></p>
<h4>推挽输出</h4>
<p>下拉结构和开漏及准双向口相同,但锁存器为1时提高持续的强上拉。一般用于需要更大驱动电流的情况。</p>
<p><img src="data/attachment/forum/202412/17/151047ii4gf85jij2g8mfl.png" alt="image.png" title="image.png" /></p>
<h4>高阻输入</h4>
<p>既不能流入也不能流出,带有一个施密特及干扰抑制电路</p>
<p><img src="data/attachment/forum/202412/17/151234ap0og9p8ychh94q4.png" alt="image.png" title="image.png" /></p>
<h4>开漏模式</h4>
<p>对外设置输出为1,等同于高阻输入。</p>
<p>开漏即可读也可对外输出高低电平,如要读或对外输出高电平,需外加上拉电阻。</p>
<p>当锁存器为0时,开漏模式下关闭所有上拉晶体管。</p>
<p><img src="data/attachment/forum/202412/17/151459c9d4wf244j29uw8x.png" alt="image.png" title="image.png" /></p>
<h4>高于1.09V为高电平</h4>
<h4>低于0.99V低电平</h4>
<h2>按键输入检测</h2>
<p>按键一端通过一个300R的电阻与引脚连接,一端与地连接,当按键按下时,引脚被拉至低电平,没按下时通过内部上拉晶体管上拉至高电平。</p>
<p>任务一:按下P32按钮灯亮,松开P32按钮灯灭;(判断引脚电平)</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=73751"></video>
<p>任务二:按下P32按钮灯灭,松开P32按钮灯亮;(判断引脚电平)</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=73752"></video>
<p>任务三:按一下P32按钮灯亮,再按一下P32按钮灯灭;(需增加软件消抖//20ms和判断按键是否送开代码//while循环)</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=73767"></video>
<p>练习:</p>
<p>1、按一下P32按钮灯亮,按一下P33按钮灯灭;</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=73755"></video>
<p>2、按一下亮一颗灯,再按一下亮两颗,一直到八颗灯亮,再按下全熄灭循环反复。使用了左移位指令&lt;&lt;</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=73766"></video>
<p><a href="forum.php?mod=attachment&amp;aid=73768" title="attachment"><img src="/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg" alt="upload" /> 附件:main.c</a></p>

YOLObing 发表于 2024-12-17 22:55:15

<h1>第七集 定时器中断</h1>
<h2>中断</h2>
<p>首先之前的延时函数实现方式是CPU卡在延时函数等待,无法及时处理其他任务,中断很好地解决了此问题。开启中断后,会在后台执行定时器地计数,CPU此时可以去处理其他程序,当计数器溢出时会产生中断,cpu便可进入中断处理函数执行相应代码。</p>
<p>如视频例程所示,ISP软件生成相应定时器初始化函数和中断处理函数后,将其粘贴到主函数之前,然后在程序主循环之前调用初始化函数,手敲代码实现任务一功能。</p>
<p><img src="data/attachment/forum/202412/17/231113d9k9tmi8ie6u1mks.png" alt="image.png" title="image.png" /></p>
<h2>定时器就是计数器!</h2>
<p>定时器/计数器核心部件是一个加法计数器,其本质是对脉冲计数,此脉冲可以来自系统时钟,则为定时方式;假如来自外部引脚,则为计数方式。</p>
<p>本集主要讲解定时器/计数器0的模式0的使用方法。从手册重点学习下此模式。</p>
<p>首先,定时器/计数器0有4中工作模式,由模式寄存器(TMOD)中的T0_M1/T0_M0控制</p>
<p><img src="data/attachment/forum/202412/17/222221bn3x189ztmm9xymf.png" alt="image.png" title="image.png" /></p>
<p>重点关注下定时器0模式0的流程图:</p>
<p><img src="data/attachment/forum/202412/17/222327ol7ycmg0tgecgnx2.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/17/222639je6lm3911b19s199.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/17/222649lvnpdci5nsnlscil.png" alt="image.png" title="image.png" /></p>
<p>TR0为运行控制位,置位时定时器才能运行计数</p>
<p><img src="data/attachment/forum/202412/17/222817p8tht7q64hu1htx0.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/17/222827wa74oaa0q405twoo.png" alt="image.png" title="image.png" /></p>
<p>C/T=0时,计数器连接到系统时钟的分频输出,工作在定时方式。系统时钟</p>
<p>经过TM0PS(此寄存器可以写入0-255)预分频(系统时钟除以TM0PS+1)后,通过AUXR.7/T0x12置位或复位选择12分配或不分频。</p>
<p><img src="data/attachment/forum/202412/17/224240zzki3dd5ld2mv82k.png" alt="image.png" title="image.png" /></p>
<p><img src="data/attachment/forum/202412/17/223430ta07aiwvwv0qwwiq.png" alt="image.png" title="image.png" /></p>
<p>C/T=1时,计数器连接到外部脉冲输入P3.4/T0,工作在计数方式。</p>
<p>当GATE=1时,允许外部输入INT0控制定时器0地启停,从而实现脉宽测量。</p>
<p>定时器0有两个隐藏地寄存器RL_TH0和RH_TH0,与TL0/TH0分别共有一个地址,写入内容会同时写入隐藏寄存器,当定时器溢出时,隐藏寄存器地值会写入TL0/TH0,实现重装载。</p>
<p>TF0为中断标志位,定时器溢出会置位TF0,CPU响应后由硬件复位。</p>
<p>时钟计算公式:</p>
<p><img src="data/attachment/forum/202412/18/194117p8qj1vq8qu7m1vl5.png" alt="image.png" title="image.png" /></p>
<p>使用ISP软件生成定时器初始化函数</p>
<p>void Timer0_Init(void)                //3秒@24.000MHz<br />
{<br />
TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )<br />
AUXR &amp;= 0x7F;                        //定时器时钟12T模式<br />
TMOD &amp;= 0xF0;                        //设置定时器模式<br />
TL0 = 0x3F;                                //设置定时初始值<br />
TH0 = 0x01;                                //设置定时初始值<br />
TF0 = 0;                                //清除TF0标志<br />
TR0 = 1;                                //定时器0开始计时<br />
ET0 = 1;                                //使能定时器0中断<br />
}</p>
<h2>本集的另一个内容是讲解函数的定义、声明、调用</h2>
<p>一个标准的函数:</p>
<p>返回值类型   函数名 (入口参数)</p>
<p>{</p>
<pre><code>//函数体

//函数执行的代码

return 返回值;
</code></pre>
<p>}</p>
<p>在调用之前需要声明,声明格式为返回值类型   函数名 (入口参数);</p>
<p>调用格式为函数名 (入口参数);</p>
<h2>编程练习</h2>
<p>任务一:按下P32点亮led00,延时1s后熄灭</p>
<p>在按键判断中点亮led灯,并打开定时器,然后在定时器中断中熄灭led灯,并关闭定时器。</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74015"></video>
<p>任务二:按下P32后,led00和led01交替闪烁,再按一下,熄灭。</p>
<p>程序原理:判断按键按下后,判断按键状态为0时打开定时器,在定时器中断处理函数中反转标志位,再将标志位正反分别赋给led。为1时,关闭定时器,熄灭led灯。</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74016"></video>
<p>课后小练:</p>
<p>1、按下按钮1,串口显示“双倍功德时间”,再按下显示“单倍功德时间”;</p>
<p>2、按下按键2,双倍功德时间下串口显示“功德+2 当前功德:xxx”;</p>
<p>3、按下按键2,单倍功德时间下串口显示“功德+1 当前功德:xxx”;</p>
<p>4、功德+1时,led点亮1秒后熄灭表示功德成功点亮;</p>
<p>5、功德+2时,led点亮2秒后熄灭表示功德成功点亮;</p>
<p>实现效果</p>
<p><img src="data/attachment/forum/202412/18/205631m5fm27jzoeo5zafh.png" alt="image.png" title="image.png" /></p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74028"></video>
<p><a href="forum.php?mod=attachment&amp;aid=74029" title="attachment"><img src="/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg" alt="upload" /> 附件:main.c</a></p>

YOLObing 发表于 2024-12-18 23:00:01

<h1>第八集 定时器周期性调度任务</h1>
<h2>首先解答了论坛上常见的问题和错误;</h2>
<h2>1、周期性任务介绍;</h2>
<p>任务一:使用一个定时器,led1每300ms取反一次,led2每600ms取反一次,led3每900ms取反一次</p>
<p>第一种实现方式:</p>
<p>初始化一个1ms的定时器,设置三个计数变量对应三个灯,每计数到300次,600次,900次led灯取反一次,并清零计数变量。</p>
<p>然后引入数组的概念:数组是一个固定长度的存储相同数据类型的数据结构,数组中的元素被存储在一段连续的内存空间中。</p>
<p><strong>数组中的每一个数据叫做数组元素 <code>Element</code>,数组中的每个元素都有一个序号,这个序号从 <code>0</code> 开始,称为下标 <code>Index</code></strong>,例如,<code>a</code> 表示第 <code>0</code>个元素,<code>a</code> 表示第 <code>3</code>个元素。数组是一个整体,它的内存是连续的,内存示意图:</p>
<p><img src="data/attachment/forum/" alt="" /><img src="data/attachment/forum/" alt="" /></p>
<p>通过数组可以方便地将三个计数变量集中在一次操作。</p>
<p>数组给每个元素计数时需要使用到for循环:</p>
<pre><code>u8 i = 0;

for(i=0;i&lt;3;i++)
{
        count_ms ++;
}
</code></pre>
<p>for 循环语句的一般形式为:</p>
<p>for (表达式1; 表达式2; 表达式3)<br />
{<br />
语句;<br />
}</p>
<p>它的执行过程:</p>
<p>求解表达式1。<br />
求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步。<br />
求解表达式3。<br />
转回上面第2步继续执行。<br />
循环结束,执行 for 语句下面的语句。</p>
<p>实践效果</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74050"></video>
<p><a href="forum.php?mod=attachment&amp;aid=74051" title="attachment"><img src="/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg" alt="upload" /> 附件:main.c</a></p>
<p>任务二 使用数组点亮流水灯</p>
<p>创建一个数组,共8个元素,每个元素代表每次点亮哪个led灯,然后按需将数组赋值给P0端口实现流水灯</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74058"></video>
<p><a href="forum.php?mod=attachment&amp;aid=74059" title="attachment"><img src="/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg" alt="upload" /> 附件:main.c</a></p>
<p>任务二 按一下按钮,led按数组移动一下,为了观察到是否会影响其他程序运行,每隔1s打印一个信息。</p>
<h3>按键按下不使用while循环判断按键是否松开(程序会一直等待),而使用计时方式,如按下开始计时50ms后判定为按键按下事件,小于这个时间视为抖动</h3>
<p>实验效果</p>
<p><img src="data/attachment/forum/202412/18/225738emgp2g2rqxcoxpx1.png" alt="image.png" title="image.png" /></p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74061"></video>
<p><a href="forum.php?mod=attachment&amp;aid=74062" title="attachment"><img src="/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg" alt="upload" /> 附件:main.c</a></p>
<h2>2、文件的创建(.c和.h)</h2>
<p>分三步:1、新建文件并保存;config.c和config.h</p>
<p>2、添加到工程;</p>
<p>3、添加引用路径</p>
<h2>3、结构体的介绍;</h2>
<p>结构体(struct)是由一系列具有相同类型或不同类型的数据构成的<strong>数据集</strong>合,也叫结构。</p>
<p>这个声明描述了一个由两个字符数组和一个float变量组成的结构体。</p>
<pre><code>struct book
{
char title;//一个字符串表示的titile 题目 ;
char author;//一个字符串表示的author作者 ;
float value;//一个浮点型表示的value价格;
};//注意分号不能少,这也相当于一条语句;
</code></pre>
<p>3、接下来就是一个花括号,括起了结构体成员列表,及每个成员变量,使用的都是其自己的声明方式来描述,用分号来结束描述;</p>
<p>1、首先使用关键字struct,它表示接下来是一个结构体。</p>
<p>2、后面是一个可选的标志(book),它是用来引用该结构体的快速标记。</p>
<p>因此我们以后就可以这样创建数据对象</p>
<p>struct book <strong>library</strong>;</p>
<p>3、接下来就是一个花括号,括起了结构体成员列表,及每个成员变量,使用的都是其自己的声明方式来描述,用分号来结束描述;</p>
<p>4、在结束花括号后的分号表示结构体设计定义的结束。</p>
<h2>4、结构体数组的周期性任务调度;</h2>
页: [1]
查看完整版本: AI8051U学习心得打卡记录+基于AI8051U开源创意电子设计大赛