找回密码
 立即注册
查看: 702|回复: 9

学习Ai8051U的感悟

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 15:55:45 | 显示全部楼层 |阅读模式


我是做分布式软件系统研发的,之前一直用嵌入式linux作为终端,随时负责的项目越来越大,后期需要接触stm的arm系列101 407 429等芯片,我们研发有专门的嵌入式开发,为了和嵌入式团队有共同的交流基础,因此我又捡起来看看芯片,因为我之前也是学过单片机和汇编的,再加上本身编程起来的,所以比较轻车熟路。
我在网上买了个89C52的测试板子,由配套数据,觉得挺有意思,但是在面对复杂的端运算可能就不行了,无意见发现stc官网改版了,于是看看有什么新内容,才发现stc今年7月份发布了Ai8051U的芯片,注册之后,客服小姐姐直接顺丰邮寄,直接到手,这里要说下客服小姐姐小张,挺热情的,耐心沟通,让我们这些大哥哥很开心。说下ai8051U芯片非常小巧和W5500差不多,但是性能和功能上真是划时代的,stcmcu的竟然如此先进,基本上常见的功能都涵盖其中。我学习了冲哥的第一课,里面介绍的内容,已经满足一般端控制的要求,芯片运行速度快,例子提供的涵盖经常使用的场景,非常全面。同时我还在网上查了,Ai8051U还支持rtos,简直不可思议,stc真的式未来嵌入式的狂飙。
之前又朋友问我学些stc还是stm,我跟他们说,stm的推广比较早,提供的配套工具,组件比较多,指令集和构架比较复杂,但是stc的性价比更为高效,学会stc已经可以解决多半问题场景了,并且网上的学习资料和配套业余stm不相上下,对应一个初学者我极力推荐stc的芯片。但是今天看到Ai8051U的退出,让我感觉到,stm的老对手又回来了,学习stc还是stm这个我现在还真不好回答了,因为stc的芯片价格低,大多场景的时候stc和stm的处理时间其实也难分高下,选择stc更为合理。

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 15:56:59 | 显示全部楼层

学习Ai8051U第二集



今天继续学习Ai8051U的第二集,冲哥讲解的非常细致,很多名字都是平时能接触到的,相信这集视频大家也是受益匪浅的。视频最后的运行了一个跑马灯的程序,很是巧合,我第一次接触51芯片就是跑马灯,当时我们老师还在讲如何点亮一个led,我就自己研究出来跑马灯了,老师大为震惊,让我当了课代表,哈哈,真是一个有趣的回忆,这么多年我一直从事互联网和工业系统的研发,后来做公共安全的警务系统,但是内心中一直是对硬件开发感兴趣,梦想着和电影里的天才少年一样做出一个机器人,但是时光飞逝,一直没有时间从事嵌入式的专业,而且最近再学习人工智能方面的知识,也和嵌入式冲突,恰好在同事推荐了这个Ai8051U的新番,又可以拿到实验箱,觉得挺有意思,所以坚持每天看一集,写下感悟。

说下这个试验箱吧,之前也见过不少试验箱,但是结构比较复杂,就算能编程,到最后和绘图制板子还是两回事。可以这个Ai8051U的试验板子结构简单,功能齐全,紧跟潮流,可以这样说,如果把这个试验箱搞懂,那Ai8051U的功能也就掌握近半了。尤其是这块板子可接入三块屏幕,其中TFT、LCD是大家常见的,所以说,我真的被这个小巧的板子吸引了。

之前有个朋友说,他不喜欢stc,因为stc的首页太丑了,可对我来说,我挺喜欢stc的这个首页,有点像“椰树”牌椰汁,就是简单,就是这么好记、好用、好办! 如果换个首页我还觉得不习惯,因为我做计算机多年,深知越是简单的东西,越是爆发力越强。比如之前的Java简单,结果Java颠覆了整个互联网,载入后来出来的Go语言,语法都没几个,结果短短时间颠覆了半个语言圈,目前最近12月份,已经派到前5名了。总之,我听喜欢stc的设计,加油!!!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 16:00:58 | 显示全部楼层

学习Ai8051U第三集-上难度了,给无从下手的同学普及下算法和原理
本文带图连接 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=13521



今天本来还想继续感慨,没想到冲哥讲的上难度了,内容到不复杂,前面都是些Keil的配置和C语言的语法知识,但到了后期讲到P0M0、P0M1,P4M0、P4M1的时候,我相信大家都有些疑惑,而且PPT上写的是P0M1、P0M0,正好和冲哥写的是反向的,这都是为什么呢?
下面我给大家从软件层面补习一下!
首先回答第一个问题:
1.提问:“明明只是要控制P00的节点引脚,为什么还要控制P40的引脚?”
1.回答:我们在操作C8051(或则C89C52)芯片的时候,一般都是P^0的写法,即操作哪组灯就编写哪组,但是Ai8051U的控制逻辑不同,请看下图:

那个VCC就是供电电压,你可以认为就是电池的正极,那个红框就是开关,即如果要让电流流到下面就要打通P40(就是P4.0),所以先给P40打开,然后三极管才能通,之后打开P00才可以构成回路,那个P00(就是P0.0)就是负极,之后大家就知道了,即形成了回路,灯就亮了。
2.提问:“为什么要设置P40=0;P00=0呢?为什么不设置成P40=1;P00=1呢?”
2.回答:因为赋值为0代表为负极接入,即VCC是正极3.3V,流入到P40、P00时候,他俩肯定得是电池的负极啊。而如果给P40=1、P00=1,则表示接入正极,即VCC、P40、P00都为3.3V,那正极对正极就没电流了,因此P40=0;P00=0。这时有的朋友就问了,这个电路图哪有什么正极和负极啊,我们初中、高中学的物理都是一个完整的回路,这个根本就看不出来啊!没错这图表达的意思比较简要,实际上的接法和你的初高中原理是一样的,只是内部复杂了一些,所以芯片的引脚接法图根本就没画全,误导你觉得芯片电路很难度,我就这么告诉你,芯片就是你初中学的电路并联、串联啥的,别想太难就好了。
3.提问:“关于P0M0、P0M1,到底是啥?!并且下图是如何计算的?”

3.回答:P0M0、P0M1(类似的还有P1M0,P1M1;P2M0,P2M1以此类推)是通过这两个属性配置P0组引脚电位、逻辑状态的配置项,即P0组有8个引脚,每个引脚有四种电位逻辑状态,分别是“准双向口”,“推挽输出”,“高阻输入”,“开漏输出”。
就拿P00来说,P00有4中状态,
假如P0组的引脚只有两种状态,那么仅需要P0M0就够用了,P0M0是一个字节(8位),即二进制为 0000 0000,其中每一位标志一个引脚状态,如下:
0:表示“准双向口”
1:表示“推挽输出”
举例 P0M0为 0100 0000 则表示 P06 为 “推挽输出”,其他7个都是“准双向口”。(因为二进制的bit排序是从右到左的,此低到高的)
而事实偏偏P0的引脚有四种状态,单靠P0M0就不够了,所以还需要加1位,也就是出现P0M1,其中P0M1用在第二位、高位上,也就是如下:

00:表示“准双向口”
01:表示“推挽输出”

10:表示“高阻输入”
11:表示“开漏输出”
其中最左的一位就是由P0M1表示的,最右一位是由P0M0表示的,M1、M0也正符合二进制的从右到左,低到高的顺序,所以冲哥的PPT里面的代码写的是 “P0M1=0;P0M0=1”,而不是“P0M0=0;P0M1=1”,估计是原创是想让大家了解高低位的顺序,而故意为之。
在冲哥的视频里面也体现了这个说法,如下图:

其中左面红框里就说明了M1是代表高位,并放到了左边。

好的,感谢stc这么有意义的一课,继续坚持!!!

附件说明:

OK最后我们说一下,这四种状态代表什么(网上找的例图,可能又不准确的地方,还请指正):

准双向口
准双向I/O模式与标准51相比,虽然在内部结构上不同,但是在用法上相同,比如要作为输入时,都必须先写“1”置成高电平,然后才能去读引脚的电平状态。
准双向口,也就是说不是真正的双向口,真正意义上的双向口是需要通过设置专门的“输入输出方向寄存器”将IO口设为输入模式或者输出模式,才能实现对应的输入输出功能。而准双向口则不需要设置,作为输出时直接向口线寄存器写;作为输入时则需要先向IO口写1再去读。准双向口的内部电路结构如下如所示:

由图可以看出当口线寄存器为1时,左边的场效应管断开,右边的场效应管导通,于是输出被电源上拉为1,输出高电平;当口线寄存器为0时,左边的管子导通,右边的管子截止,输出管脚相当于直接通过左边的管子接地,输出低电平。在读取数据时,如果口线寄存器的值为1,当管脚接低电平时,采集到时输入数据为1,反之为0,这种情况下是可以正确的读取数据的,但是如果口线寄存器的值为0 ,则左边的场效应管导通,输出相当于直接与地线相连,此时无论外部输入为高电平还是低电平,采集到的输入数据都是0,这样就不能正确的读取数据了。所以对于准双向口,作为输入口使用时,必须先向该IO口写1,再读取,这就是准双向口的特点。


推挽输出
不论输出高电平还是低电平都能驱动较大的电流,比如输出高电平时可以直接点亮LED(要串联几百欧限流电阻),而在准双向I/O模式下很难办到。

与准双向口类似,只是右边的场效应管为强上拉作用,因而输出电流较大,适用于需要大电流驱动的场合。在使用推挽结构时,要注意不要将两个IO口短接,因为如果一个IO口为高电平而另外一个为低电平时,会有很大的电流流入芯片,可能烧坏芯片。



高阻输入
高阻输入模式的特点是只能作为输入使用,但是可以获得比较高的输入阻抗,这在模拟比较器和ADC应用中是必需的。如下图


当IO口处于高阻态时,我们也将其称为浮空输入状态,此时其电平是不确定的,既不是高电平也不是低电平。我们可以想象成,单片机在检测IO口的电平高低时,相当于在CPU里面有一个类似电压表的东西,并且这个电压表内阻很大,假设内阻为100MΩ(示意图如下)。在这里,我们可以把这个电压表的内阻称为这个IO口此时的输入电阻。

现在设想,当我不小心用手碰到了IO端口,而由于人体本身就是阻值很大的导体,周围有很多电磁波干扰,手上可能存在一些很微弱的电流,这个时候,电压表的读数就会发生变化,单片机读取的电平高低就会变。高阻态表现出来的结果就是外界。

开漏输出
开漏模式与准双向模式相似,但是没有内部上拉电阻,输出0时为低电平,输出1时为高阻状态。开漏模式的优点是电气兼容性好,可以提高输出高电位的电压值,如通过电阻接12V,则输出的高电平就是12V了,如果外部上拉电阻接3V电源,就能和3V逻辑器件接口,如果上拉电阻接5V电源,又可以与5V逻辑器件接口。此外,开漏模式还可以方便地实现“线与”逻辑功能。
开漏(open drain),这里的“漏”指的是场效应管的漏极(drain),对应于三极管的集电极(collector),开漏就是指场效应管的漏极保持开路,直接接出作为输出口,如下图所示:

从图中可以看出,当口线寄存器为0时,管子导通,输出直接通过管子接地,输出低电平;当口线寄存器为1时,管子截止,输出脚相当于悬空,为高阻态,因此开漏输出接口不能够正确的输出高低电平。对于开漏输出结构,输出必须接上拉电阻,才能够正常使用,如下图所示:

外接了上拉电阻后,当口线寄存器为0时,输出被电源上拉为高电平,口线寄存器为0时,输出口通过管子直接接地,为低电平,这样就可以正确的读取外部数据了。
很多芯片都提供开漏输出结构,这是因为开漏输出结构有很多优点:
a. 充分利用外部电路的驱动能力,减小芯片内部的驱动,从而降低芯片的功耗,提高芯片工作稳定性
b. 可以通过改变上拉电源的电压,改变信号的传输电平,比如某芯片的输出为3.3V电平,其输出口的上拉电源可以为5V,这样就很方便的实现了电平转换。
当然,开漏输出也存在明显的缺点:在输出脉冲信号时,在脉冲的上升沿,电源通过上拉无源电阻对负载充电,其速度较慢,导致上升时间变长,因而会导致脉冲上升沿变坏,上拉电阻阻值越大,充电时间就越长,因此其速度越慢,而阻值较小时,其功耗又会变大,因此在设计时要兼顾速度和功耗。而对于下降沿,电源通过芯片内部的场效应管放电,其速度较快,所以上拉电阻对脉冲的下降沿影响不大,某些情况下可以考虑用下降沿输出。


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 16:02:01 | 显示全部楼层

Ai8051U第四集 解答几个小问题

今天又学习了一集,冲总讲的很细致,话说今天讲了个不停电就可以下载程序到板子,是不是很方便,具体内容我觉得挺好。
那么下面讲一下编写单片机的一些小常识:
1.为什么单片机用while,我们平时在上位机编写程序的时候,尽可能避免while(1) 这样的四循环,而冲总这边为什么都是while死循环呢。

1.答:接着上集接着讲,为什么单片机编写的时候要弄个while呢?因为我们编写单片机实际上已经很底层了,我们平时编写程序实际上都是基于操作系统编写,而嵌入式是基于硬件开发,换句话讲,我们在真真正正的操作一台晶体管样的机器,操作的流程最终就是结束,因此如果我们用C语言的顺序结构,那么程序将会退出单片机,也就是程序运行一次不执行了,因此我们需要用到while(true) 这个死循环来让这个机器一直运作。那有的朋友就问了,这么个死循环不得把cpu干烧啊?其实不然,我们平时编程如果遇到while死循环在会在上位机疯狂运转,那是因为上位机是多进程的,你写个死循环计算机会和其它进程抢占资源,上位机会尽可能的让你的while最快执行,所以特别浪费cpu调度,导致cpu很忙;而这个嵌入式的默认while其实是个总循环,他一直都按顺序执行,只不过不停止罢了,不存在抢占调度的问题,及时有抢占问题,那也有中断器去帮助弄,到时候while(true)也得靠边等着,因此完全不用担心while导致cpu很忙。


2.问题:@STCISP#怎么修改?

2.答这个其实就是个防呆功能,实现很简单,就是你”@STCISP#“,和之前已经下到板子里的程序命令一直就可以,也就是你之前是”@STCISP#“,那么你写的程序的Command也必须是”@STCISP#“。如果你想改,比如STC123,那你改完了之后,先用USB HI*方式先断电重写一遍,此后你再写入的话,你就用自定义命令“STC123”,就可以实现不断电写入程序了(我现在手头没有板子,至少我认为是这样的)。

3.为什么会出现程序写入错误?

3.答:这个冲总已经讲过了,这个实际上是和编译器之间有关系,简单说,我们编程界有个不成文的规定,“就是如果你不用那你就别写,写上属于浪费资源。”,那么冲总在编译的时候,这些代码就会被提醒出来,告诉你“写这么多都不用啊?!”,我们可以回头看下错误信息:
“uncalled function ignored for overlay process” 可以翻译为:“对于覆盖进程,未调用的函数被忽略”。
这句话通常出现在编程或软件开发的上下文中,特别是在处理代码覆盖(code coverage)或软件更新/覆盖安装(overlay installation)时。它意味着在特定的覆盖处理过程中,那些没有被调用的函数或代码段被系统或工具忽略了,因为它们对当前的操作或测试没有影响。简而言之,就是那些未使用的代码在当前的覆盖处理中被视为不重要或不需要考虑的部分。
但是计算机还是很诚恳的提醒出来,哪些不用的代码,并且你不给他说个所以然来,他是不让编译通过的(及时代码写的没问题,也不行),所以冲总最后用小魔术刷点了以下,告诉电脑可以这么做,才编译通过了。

好了最后 感谢冲总 今天的视频,学到了很多了,希望stcai越做越好!

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 16:03:23 | 显示全部楼层
Ai8051U第五集 小伙伴们都睡着了吧

本文带图链接 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=13579

  想起学习计算机语言的时候,我都一个接触的Pascal语言,现在都忘了具体写法,用现在的看法,Pascal语言有点像伪语言,据说是1968年开始的,1970发布,后来查询资料发现 C语言竟然也是1970年发布。
今天冲总给大家普及了以下基本语法,感觉讲了很多,由于时间的限制,实际上关于C语言的设计思想没有讲,只讲了基本的变量类型和基本符号类型用法。关键是这里面好多内容都和我上大学的时候讲的一样,上来就一顿输出,对于没有了解过C语言的朋友,只能抓紧用本记啊。
  那么有的同学会问,学习一门语言到底怎么学?那我就经验之谈了。
首先,我们要了解我们学的是什么语言,什么语言学习的难度、知识储备、应用场景、特性都不一样,不然为什么会出汇编、C、C++、VB、C#、Java、JavaScript、ActionScript、Go、Python、SQL、Rust等等,以下我罗列几个:
1.机器语言:0、1两种组合,人和机器最早的交流,那时候老师们都是拿着打孔纸,基本上早先人都用不上,因为机器太少,属于短缺资源,这类语言可以学习,但是主要应用于计算,例如算个炮弹轨迹、破解个密码,造个原子弹啊等等,所以没有迫不得已没人会使用它。
2.汇编语言:属于底层语言,也是迄今为止你能听到的最早的语言(但实际上也不算爷爷),目前这种语言仍然在使用,主要解决调试、驱动、要求极高的算法等等,这种语言虽然比0、1强,但是也比较难用,因为它都是在操作寄存器,你用它就是各种倒弄,把数据从这弄到那,又弄到那等等,忙的不亦乐乎,连最基本的字符串用的费劲,跟别谈什么文字处理了,总之,汇编不难,非常简单,难在沟通还是太费劲。
3.C语言,属于中级语言,他是专门解决“汇编语言”的弊端的,它的设计初衷就是书写上让人类能看懂,例如3+2=?这样的操作,用C语言仅仅是printf(3+2);就可以了,但是要用汇编那就得

mov ax, 3
mov bx, 2
add ax, bx //结果为5
存储在AX中//关键是写完这些,还没往屏幕上输出呢


C语言的出现使得人类编程得到飞速的发展,开始用汇编语言编写了C语言编译器、后来用C语言重新编写了自己编译器,同时用自己的编译器编写了自己的所有扩展功能,自己创造自己,从那时起C语言肩负着革命性的进步,相比汇编语言C语言属于结构化语言,既可以把数据结构化管理(因为语言最终都是处理数据),这种进步在当时已经非常了得了!!!,由此unix,linux,window都是由C语言开发的,但是也仅仅是结构化,所以人们从汇编脱离出来,计算机由原来处理国家关键问题,转而处理民用问题,因此编写逻辑的需求日益增大,所以C语言开始不够用了。

4.C++ 属于高级语言,起到承上启下的作用,由于C语言是结构化语言,因此工程师们有发明了C++语言,又称C plus,看名字就比C强,但是C++是完全兼容C的,你也可以人为是基于C,增加了面向对象的逻辑写法。你可能面试的时候会被问道:“抽象、封装、集成、多态”这样的问题,这些都是从C++开始的,就拿单纯的“抽象”,好多C语言工程师都玩不明白呢,为什么呢?因为C语言注重实现功能,写法更贴近硬件,而C++注重思想(面向对象的思想),换句话说C++更符合人类表达的业务需求,但是为什么符合人们的思想结果更难学呢?这就归功于“多态”的出现,即思想太多了,都乱套了,再加上C++本身就是C的扩展,C的老毛病(指针溢出、内存溢出)也都整一起了,写的老复杂了,问题老多了,所以C语言虽然好,但是不好驾驭。C++什么都能干,例如现在的音视频处理、图形计算、编译器、QT、嵌入式等等,都用C++,因为他继承了C的优势,同时还有抽象封装的思想,但是就是因为能力大,所以不好控制,你想想你们公司的能人,是不是脾气也不好。


5.Java,属于高级语言,话说用C++的同事头发都掉光了,后来用Java的头发都长回来了,Java语言和C++一样都是面向对象语言,但是没有C++强大,速度也没有C++快,但是人们就说它厉害,你说为啥?!我们中国易经曾说过,物极必反,C++太强了,强到什么都可以做,而Java呢只会C++的一部分,即处理数据、面向对象其它的一改不会,如果太复杂了,还得用JNI(与C配合)来救场,但是你说怪不怪,今天大型互联网公司都有Java的踪影,除了不能被替代的,Java都把C++的许多事替代了。这也说明了能当上领导的,觉得不是最强者,都是半斤八两,那如果遇到解决不了的问题呢? 那找强人救场呗。


6.GO语言,这个语言我得好好说说,话说今天Java地位都这么厉害了,结果还被GO敲了竹杠,真是江上自有人才出,前浪拍在沙滩上啊!先写到这吧

先感谢 冲总的课程,真的很用心讲,下面的图大家可以背背,我是从课程里截取的,以后总能用到。




说到Go语言那也是2006-01-02 15:04:05诞生,与2009正式上线发布,我觉得这真的很不错,你可以认为他就是加强C,而不是C++,也不是Java,咱们书接上文,Java都说了是个非常好的语言,但是说实话,Java虽然简单,但是写起来总有一种感觉,就是“Java把你当成没懂事的孩子,对你百般照顾,又是百般约束。”,又像是“一个温柔体贴的女孩,对你事事关心,小心翼翼,纠缠不已”,Java的编写生涯就像是过家家,刚开始很好,逐渐的研发了这种生活,最后还刷不掉...,没错不只是Java凡是后期能构建大型项目的语言都有这个毛病,只是用Java的太多了,这门语言的特色让你潜意识不舒服。而和我一样的亢奋程序员甚多,只是没办法,但是偏偏有人不适应,而且还不是一般人,他们厌倦了当前的语言,重新开发了一种新语言GO。我是用GO语言得有10年了,中途还用工重新写了JavaScript ES3的解析引擎,还用其开发好几个大型项目,朋友你知道吗,Kubernetes和Docker都是用GO开发的,Google的云服务、集群服务都是GO在默默支持,你能想象一个在Java风靡全球的世界里,GO还敲了Java竹杠,这世界太疯狂,都咋了,目前GO已经在编程语言排行榜排名前五了,难以置信,但是也在情理之中。
用了10多年的GO,和Java相比,GO就是那种“你需要她,她就来,你希望他离开,她就从容离开,即使你睡了她,他也不会让你负责。有种说不的感觉,GO就是一个高冷的少妇,又是一个人情的少女,她懂你,会让你很爽,但又不会犯错,无法形容!”,


为什么会是这种感觉,因为这是我们程序员的初中,语言不是我们主体,思想才是主体,当我们把手放到键盘的那一刻,就是将思想立即兑现,而不是弄什么配置、导入什么包、又是编译、又是梳理什么流程...,没错他们做到了。

让我熟悉下这几位天才打工人都是谁:
由请第一位:
Rob Pike(罗勃·派克)
  • Go 语言项目总负责人
  • Unix 的团队成员
  • UTF-8 编码创始人
  • 参与了[color=var(--vt-c-brand)]贝尔实验室和[color=var(--vt-c-brand)]Inferno操作系统的 Plan 9 的创建,以及[color=var(--vt-c-brand)]Limbo 编程语言
  • 1980年奥运会射箭的银牌得主
  • 业余天文学家


Ken Thompson(肯·汤普逊)

  • Unix 之父(他和 C 语言之父丹尼斯·里奇一起开发了 Unix 操作系统)
  • C 语言创始人(C 语言之父和他,在他开发的 B 语言基础上开发了 C 语言)
  • 1983 年获图灵奖
  • UTF-8 编码创始人


Robert Griesemer(罗伯特·格瑞史莫)


Google V8 JavaScript 引擎、Chubby 和 Java HotSpot JVM 的主要贡献者。


我们来看看 Rob Pike 他2023年演讲的一段文字,我给他翻译中文了(截取)
首先,对于编程语言来说,什么是好什么是坏,很大程度上是主观而非客观的,很多人对Go或任何其他语言,乃至一些非常细节的特性发表了很多争议。

还有很多关于诸如换行符放在哪里,nil的工作原理,使用大写字母进行导出,垃圾收集,错误处理等方面的讨论。虽然可以讨论的方面很多,但几乎都已说过了。

但我要谈论的不仅仅是语言本身,因为这门语言并不是这个项目的全部。我们的目标并不是创建一种新的编程语言,而是创建一种更好的编写软件方式。无论是什么语言,我们每个人可能都会认为我们使用的语言有一些问题,但问题根源并非来自这些语言的特性,而是因为使用这些语言创建软件的过程。

新语言的创建为探索其他思想提供了一条新路径,但这只是促成因素,而不是最终目的。如果不是因为当初我在工作中构建二进制文件需要45分钟之长,Go就不会诞生,但这45分钟并不是因为编译器慢(实际上编译器并不慢),也不是因为编写代码所使用的语言很糟糕(实际上语言本身也不差),慢的原因来自其他因素。

而这些因素正是我们想要解决的问题:构建现代服务器软件的复杂性,控制依赖性,大型编程团队的人员不断变动,如何易于维护、高效测试、有效利用多核CPU和网络等等。

简而言之,Go不仅仅是一种编程语言。当然,Go也确实是一种编程语言,这是它的定义,但它的目的是提供一种更好的方法来开发高质量的软件,至少优于我们14年前的环境。

而这仍然是今天的目标:Go是一个旨在降低构建生产软件的难度并提高效率的项目。

文章的最后,我有些感慨,三位天才依旧是程序员,不是工作不好,而是梦想太大!大到改变世界。这也是我看好stcai的工作人员们,希望你们推出更好,更便宜的好芯片!!!




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 16:04:45 | 显示全部楼层
Ai8051U第六集 小伙伴继续来扩展知识了

本文带图链接
今天冲总讲的挺好,把编写按钮触发的问题都讲了下,但是总感觉冲总在做最后一次实验的时候,貌似程序没下进去(也可能是视频的声音有延迟,导致按下声音不同步,导致看上去灯变化延迟)。
对于初学者,即使物理学的挺好,也会对高低电平的知识有误区,因为大家都认为高低电平的组合可能是方形波,但是实际上高低电平是有一定范围的。下图我从视频截图了,说明了高低电平的范围。
以VCC3.3伏为例,打开了施密特触发器,高电平应该是1.18V<=X<=3.3;低电平应该是0<=x<=0.99;


1.问题:什么是施密特触发器呢?
1.回答:
    施密特触发器是由美国科学家奥托·赫伯特·施密特(Otto Herbert Schmitt)于1934年发明,当时他只是一个研究生,施密特触发器可作为波形整形电路,能将模拟信号波形整形为数字电路能够处理的方波波形,而且由于施密特触发器具有滞回特性,所以可用于抗干扰,其应用包括在开回路配置中用于抗扰,以及在闭回路正回授/负回授配置中用于实现多谐振荡器施密特触发器(英语:Schmitt trigger)是包含正反馈比较器电路,这里大家要记住trigger这个单词上位机经常用到,你会发现做触发经常提到“触发器”,例如数据库、布局响应都会提到。
     对于标准施密特触发器,当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;当输入在正负向阈值电压之间,输出不改变,也就是说输出由高电准位翻转为低电准位,或是由低电准位翻转为高电准位时所对应的阈值电压是不同的。只有当输入电压发生足够的变化时,输出才会变化,因此将这种元件命名为触发器。这种双阈值动作被称为迟滞现象,表明施密特触发器有记忆性。从本质上来说,施密特触发器是一种双稳态多谐振荡器施密特触发器可作为波形整形电路,能将模拟信号波形整形为数字电路能够处理的方波波形,而且由于施密特触发器具有滞回特性,所以可用于抗干扰,其应用包括在开回路配置中用于抗扰,以及在闭回路正回授/负回授配置中用于实现多谐振荡器
2.问题:打开施密特触发器有什么作用?
2.回答:单片机上关于打开和关闭施密特触发器的主要区别体现在以下几个方面:
一、功能实现上的区别
  • 打开施密特触发器:

    • 当单片机需要读取I/O引脚的电平状态时,施密特触发器能够将电压信号转换为0或1,并存储在输入数据寄存器中。
    • 施密特触发器具有两个临界电压(正向阈值电压和负向阈值电压),形成一个滞后区域,有效防止在滞后范围内的噪声干扰电路的正常工作。
    • 施密特触发器可以作为波形整形电路,将模拟信号波形转换为数字电路能够处理的方波波形。
  • 关闭施密特触发器:

    • 关闭施密特触发器后,单片机将直接读取I/O引脚的原始电压信号,而不再经过施密特触发器的整形和滤波。
    • 此时,单片机对输入信号的噪声抑制能力降低,可能导致输入信号波动较大时,单片机的输出电平频繁跳变。

二、系统性能上的区别
  • 打开施密特触发器

    • 由于施密特触发器具有滞回特性,能够抗干扰,因此可以提高系统的稳定性和可靠性。
    • 在一些需要精确控制输入电平的应用中,施密特触发器能够提供更加稳定的输入信号。
  • 关闭施密特触发器:

    • 关闭施密特触发器后,系统的抗干扰能力降低,可能导致系统在某些噪声较大的环境下无法正常工作。
    • 同时,由于输入信号没有经过整形和滤波,可能会导致单片机的处理速度降低,因为需要处理更多的噪声信号。

三、功耗上的区别
  • 打开施密特触发器:

    • 施密特触发器在工作时会消耗一定的功耗,但相对于整个系统的功耗来说,这部分功耗通常是可以接受的。
  • 关闭施密特触发器:

    • 关闭施密特触发器后,虽然可以减少施密特触发器本身的功耗,但可能会因为输入信号的波动而增加单片机的处理功耗,因为单片机需要更频繁地处理输入信号的变化。

四、应用场景上的区别
  • 打开施密特触发器:

    • 施密特触发器适用于需要抗干扰、波形整形或精确控制输入电平的应用场景,如遥控接收线路、传感器输入电路等。
  • 关闭施密特触发器:

    • 关闭施密特触发器可能适用于一些对功耗要求较高、对输入信号波动不敏感或需要高速处理输入信号的应用场景。但需要注意的是,在这种情况下,需要采取其他措施来抑制输入信号的噪声和波动。

综上所述,单片机上打开和关闭施密特触发器在功能实现、系统性能、功耗和应用场景等方面都存在明显的区别。在实际应用中,需要根据具体需求和系统要求来做出合理的选择。

3.问题:什么是C语言的标准,比如视频提到的C99?
3.回答:到目前位置C语言为了寻求规范,例如书写规范,已经发布了多个规范,如:C89 C90 C99 C11 C17,其中C89和C90可以认为是一个,因为C89是C语言最早发布的标准,后来国际上引用C89重新以国际的名义发布了C90,可以认为C89是1989年发布,然后国际1990抄来重新发布,仅仅发布的机构不同,后来经过认为的使用发现了一些问题,所以发布了C99,也是目前被众多编译器支持的标准,但是也有人说C11是被广泛支持的标准,这个看具体情况,用就完了。那到最近发布的就是C17,由于大家都很忙,C17支持的并不好。

4.问题:上图的_nop_() 是啥意思?
4.回答:_nop_ 是延迟函数,即空操作函数,汇编语言里也有nop的指令,意思说一个机器周期的啥也不干就是一个_nop_(),例如:
假设单片机 12M 晶振,晶振周期1/12微秒,一个机器周期包含12个晶振周期,所以12M晶振时机器周期 = 12x(1/12)us = 1us,所以12M 晶振中一个 nop 表示延时1us;6M 晶振中延时2us,24M 晶振中延时 0.5 us
那么上面的delay20ms函数,为何使用两个nop加上while的组合呢,我个人认为,单靠while来消耗时间不能精确到20ms,所以需要和nop配合才能到20ms,我不知道说的对不对,还请懂得大神聊聊啊。
对于下面的注释作用,其实就是确保nop和while的执行在预期的时间范围内,如果不打开,那nop和while的时间就不敢保证20ms了。



最后说一下关于while的使用,按钮中使用while让程序停止,实在是实属无奈,由于使用这种会导致cpu被卡住,所以导致程序不连贯,所以我们一般使用中断的方式来解决这个问题,下一集冲总就会讲解其中,我们敬请期待。

bye bye

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-14 16:05:47 | 显示全部楼层
Ai8051U第七集 公式解答
本文带图链接
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=13637



本节课感谢冲总的热情讲解,内容不多,但是有难度的,好在冲总用半节课的时间给我们仔细讲解。
先回忆下本节课需要注意的内容:
1.Keil中,汉字采用ANSI编码,由于Keil是英文编写的,本身英文不适用0xfd,但是汉字就是用这个内容,所以编写的时候如果不对外可以采用英文内容,但是如果是汉字那就注意,需要在包含0xfd的汉字中使用转移,例如"数\xfd",具体包含0xfd的问题如下:

2.Ai8051U的定时器原理如下:



首先说下TM0PS,0号预分频寄存器,预分频计算器定义如下:预分频寄存器‌是用于对时钟频率进行预分频的寄存器,其作用是降低时钟源频率。预分频寄存器通常被称为定时器预分频寄存器(如TIMERx_PSC),其位数为16位,可以将时钟源进行1到65536的分频‌。
其中下面的公式可能通讯不太明白,我们先说下频率的计算方法(频率就是1s中能做多少次,例如你说话1s种能说10个字,那你吐字频率就是10hz,即频率=次数/时间,其中时间单位为秒s)。
那么我们说一个人假如说话吐字的频率是10hz(每秒10个字),那它说100个字就是100/10hz=10s,因此我们再看上面的图,从左到右计算方式,可以理解为下面的公式,其中第二个就是在设定那么多的参数后,实际得到终端的时间需要等多少秒。


由于上面的电路是串联关系,彼此互相影响,所以每次消耗次数,应该是相乘。

那么上面的公式根据数据始终的触发流程,可以这样说明 折腾多长时间(定时时间)=折腾的次数/时钟频率(hz),即可以认为 定时时间(s)= (TM0PS的折腾次数+至少折腾1次)*(总共能折腾的次数-已经折腾多少次)*T/时钟频率。
如果T为12的话则最终得到的就是 定时时间(s) = TM0PS的折腾次数+至少折腾1次)* 还需要折腾多少次*折腾12次/时钟频率hz。

好了,感谢冲总每次细致的讲解,今天就说到这吧。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-1-23 15:35:43 | 显示全部楼层
我这篇发的比较晚,Ai8051U的试验箱老早就收到了,大概时写完心得的第四天,用ems加急发过来的,客服小姐姐小张非常不错,之前以为比较小,没想到挺大的,做工也非常好。
我陆续买了很多硬件,准备一起测试。
最后感谢深圳国芯。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:69
  • 最近打卡:2025-05-03 09:34:20
已绑定手机

2

主题

20

回帖

334

积分

中级会员

积分
334
发表于 2025-1-26 10:13:03 | 显示全部楼层
看了你的比我详细多了,理解也比我更透彻
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-29 11:41:00
已绑定手机

11

主题

16

回帖

183

积分

注册会员

积分
183
发表于 2025-2-5 11:00:56 | 显示全部楼层
原帖带图:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=14119
来到Ai8051U的第八集,这一集感觉比较长,我看本节课程讲了大量的C语言的语法,例如定义、for循环、结构体、头文件实现等等。
首先冲总先讲解了同学在开发过程中遇到的错误,这些错误对于新手都是经常犯的,必经之路,所以不必惊慌。问题的根源就是没有熟练掌握这门语言,解决方法也比较简单,就是平时多加联系,其实编写程序也是一种习惯,跟我平时说话一样,刚开始的小时候总会考虑那说错了,经常说就不会用脑考虑了。
接着讲解了计时器终端的的方式,采用了一个定时器实现了三个等的不同频率闪烁,并且引入了数组的概念,以及数组的遍历(循环遍历),这里面要强调一点,数组的第一个元素索引是0,为什么不是1,因为计算机的计数是二进制的,用0开始没什么不好,而我们习惯了用1开始,自然觉得用1比较好,但是你知道,计算机不用0开始,那会浪费一个资源,这对计算机的楚楚可怜的资源来讲太浪费了,因此计算机的索引采用从0开始。


接着冲总采用了新的排灯方案

这块多说一句,这里冲总采用了一个8x8的行列式,就是我们平时说的matrix(矩阵),学习计算机后期会经常需要矩阵的操作,例如3D投影的变化,所以没有数据基础的朋友,可以学习下高等代数,里面会有这方面的讲解,但是对于平常就业来讲,矩阵基本上是用不上的,因为现在座IT大部分都是数据库的增删改查,做个列表等等,所以要求计算机的水平比较低,而如果坐数据分析,复杂的UI交互这些就不行了,所以计算机学习并不简单,关键看你怎么用。
另外请看下图:

这里面有两个知识点,第一个是P0的8个引脚可以批量操作,第二个是字节可以通过~符号取反。
接着,冲总又讲解了按钮导致的死锁问题如何处理,这里的经验值得借鉴。

接着介绍了结构体的概念,这个非常重要,C语言在编写规模大的程序时候,不能仅仅采用散量,为了保证数据的封装性,建议采用结构体(struct)封装数据,如下图:

定义方法:
typedef struct{
  //定义变量名称及类型
  //定义方法名称及类型
} 自定义结构的名称;

这种方法实际上是重新定义结构体,如果是单纯定义结构体,可以使用这种:

struct 自定义结构体的名称{

  //定义变量名称及类型
  //定义方法名称及类型

};
但是这种方法定义不知道这款单片机的编译器是否支持

例外下载器的版本配置要注意版本:


最后介绍几个关键词 typedef typeof sizeof

在C语言中,typeof、typedef 和 sizeof 是三个不同的关键字,它们各自有不同的用途和作用。下面我将分别解释每个关键字的作用和用法。

1. sizeof

sizeof 是一个操作符,用于获取数据类型或变量所占的字节大小。它可以用于基本数据类型、结构体、联合体、数组等。

用法示例:

#include <stdio.h>

int main() {
    int a = 10;
    printf("Size of int: %lu bytes\n", sizeof(int));
    printf("Size of a: %lu bytes\n", sizeof(a));
    return 0;
}
2. typedef

typedef 用于为现有的类型定义一个新的名称(别名)。这常用于简化复杂数据类型的声明,或者为基本数据类型定义更有意义的名称。

用法示例:

#include <stdio.h>

typedef unsigned int uint;
typedef struct {
    int x;
    int y;
} Point;

int main() {
    uint a = 10;
    Point p = {1, 2};
    printf("Value of a: %u\n", a);
    printf("Point p: (%d, %d)\n", p.x, p.y);
    return 0;
}
3. typeof (GNU C Extension)

typeof 是GNU C扩展中的一个操作符,用于获取表达式的类型,并可以用来定义该类型的变量。这在某些情况下非常有用,尤其是在需要基于表达式类型定义变量时。注意,typeof 不是标准C的一部分,但在支持GNU C扩展的编译器(如GCC)中可用。

用法示例:

#include <stdio.h>

int main() {
    int a = 10;
    typeof(a) b = 20; // 使用typeof定义与a相同类型的变量b
    printf("Value of a: %d\n", a);
    printf("Value of b: %d\n", b);
    return 0;
}

注意: 使用 typeof 需要编译器支持GNU C扩展,例如GCC。如果你使用的是标准的C编译器(如Clang或MSVC),你需要使用其他方法来实现类似的功能,例如使用 _Generic 或者在C++中使用 decltype。

总结:

sizeof 用于获取数据类型的字节大小。

typedef 用于为类型定义新的名称。

typeof(GNU C扩展)用于获取表达式的类型并基于此类型定义变量,但不是标准C的一部分。在标准C中,你可能需要其他方法来实现类似的功能。


好的 最后感谢冲总的讲解。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-4 01:09 , Processed in 0.165497 second(s), 102 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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