打印
[51单片机]

从业将近十年!手把手教你单片机程序框架(连载)

[复制链接]
楼主: jianhong_wu
手机看帖
扫描二维码
随时随地手机跟帖
121
举起来。

使用特权

评论回复
122
菜鸟同学| | 2014-3-16 12:33 | 只看该作者
jianhong_wu 发表于 2014-3-8 08:31
坦白地讲,这将近十年的时间里,我的收入很普通,比大多数的电子工程师的收入还要低,银行存款也没有100W ...

加油,像前辈看齐。
我说直接点,你说了一大堆,饶了一大圈。你说的大多我猜测都是你的想象或者渲染过的,你可能想法比较理想。面对现实,然后改变!,100W就像你说的分分钟的问题。就像说现在的情况有靠朋友的嫌疑,人情债是要还的,礼尚往来。

使用特权

评论回复
123
renwocai| | 2014-3-16 20:12 | 只看该作者
支持下楼主,像你这样肯拿出干货出来交流的越来越少了,要总结经验,组织文字,还要前后连贯系统化,最后一个字一个字打出来,真是不容易。关键是,这一切都是无偿的且具有较高水平的,实属难得。我印象中能跟本教程类似水平且篇幅较长的只有《从单片机初学者到工程师》一文。经常潜水,好帖来冒一泡

使用特权

评论回复
评论
dong_abc 2014-3-16 23:24 回复TA
你应该看看农民讲习所的教程。当然,现在不建议搞单片机了。 
124
xjjspace| | 2014-3-17 00:36 | 只看该作者
顶一下。

使用特权

评论回复
125
jianhong_wu|  楼主 | 2014-3-17 00:55 | 只看该作者
本帖最后由 jianhong_wu 于 2014-3-17 01:04 编辑
菜鸟同学 发表于 2014-3-16 12:33
加油,像前辈看齐。
我说直接点,你说了一大堆,饶了一大圈。你说的大多我猜测都是你的想象或者渲染过的 ...

(1)我讲的东西都是我的真实情况和真实想法,没必要渲染。因为我明白,只有真实的东西才能打动别人。说谎的成本其实非常高,因为每说一个谎就要用许多慌去圆一个谎,这样的人其实不聪明。
(2)靠朋友靠老婆其实并不丢脸。我做事情的思路是这样的,能靠父母就尽量靠父母,能靠朋友就尽量靠朋友,能靠老婆就尽量靠老婆,最后实在不行才靠自己。这样的思路可以把社会上现有的资源最大化的利用起来,更加节约资源,提高办事效率。

使用特权

评论回复
126
jianhong_wu|  楼主 | 2014-3-17 00:59 | 只看该作者
renwocai 发表于 2014-3-16 20:12
支持下楼主,像你这样肯拿出干货出来交流的越来越少了,要总结经验,组织文字,还要前后连贯系统化,最后一 ...

谢谢你的夸奖。其实我这个贴才刚刚开始,后面还有大量的东西要分享,我不着急,一个星期写一两遍已经是我的生活习惯,计划写个五六年吧,直到感觉江郎才尽为止。

使用特权

评论回复
127
explorersxing| | 2014-3-17 13:35 | 只看该作者
谢谢楼主

使用特权

评论回复
128
prince_王| | 2014-3-17 14:14 | 只看该作者
支持鸿哥,我等入门有望了

使用特权

评论回复
129
Li-ion| | 2014-3-17 14:59 | 只看该作者
多谢分享

使用特权

评论回复
130
21junyinzhic| | 2014-3-17 23:02 | 只看该作者
楼主真好的人,讲的也是实在话,学习了!一路辛苦了!谢谢给我们这些新手们学习的机会!

使用特权

评论回复
131
sze8| | 2014-3-18 14:53 | 只看该作者
:) 慢慢看

使用特权

评论回复
132
binghang| | 2014-3-19 01:32 | 只看该作者
楼主太厉害了  学习!学习!

使用特权

评论回复
133
xiaox314| | 2014-3-19 10:43 | 只看该作者
分享精神可嘉~

使用特权

评论回复
134
nova00| | 2014-3-20 21:24 | 只看该作者
好贴留名,赞一个

使用特权

评论回复
135
hbc0602| | 2014-3-21 00:25 | 只看该作者
我也是个初学者,我有个疑惑:如果我定时器定为2ms,像楼主说的那样,定义一堆标志位来累计定时中断次数去做不同的事情,每次进入中断先关掉定时器,做完相关的变量计算后再重新启动定时器。这样如果关掉和启动定时器中间代码量很多,那定时2ms不是不准了吗?比如2ms进入中断,关掉后处理中间的代码花费了一定的时间。虽然每次还是2ms进入中断,但是实际等待的时间不止2ms了。。。
还有,如果用定时器来做延时,那么每次用来延时的累计变量和标志位都不应该相同吧?比如调用子函数1要延时10ms,调用子函数2要延时20ms,如果用同一变量来判断是不能实现的...而且如果用了定时器来做延时,也不能写delay函数(用for循环的自减来消耗时间)了吧?这deley函数执行的过程中定时器中断已经进入N遍了...有些动作会被漏掉。
拜托指教...

使用特权

评论回复
136
jianhong_wu|  楼主 | 2014-3-21 01:15 | 只看该作者
hbc0602 发表于 2014-3-21 00:25
我也是个初学者,我有个疑惑:如果我定时器定为2ms,像楼主说的那样,定义一堆标志位来累计定时中断次数去 ...

(1)你看到我在定时中断里代码很多,实际上这些代码执行的时间很短。即使这个时间稍微长点也没关系,虽然不能按照你所想的每2ms来中断一次,可能是5ms,但是每次进入中断到退出中断的时间是固定有规律的,这样我们可以通过最后修正累计定时中断次数来达到我们想要的时间,当然,我一开始就主张没必要企图让单片机做太高精度的时间,对于绝大多数的项目,这样大概的时间是绰绰有余的。
(2)delay函数一般应用在驱动时序的短延时,甚至在一些驱动时序中(比如IIC),可以先关闭所有的中断再去执行驱动时序。在我的程序框架中,delay函数的大延时几乎不会应用在主函数的while(1)循环里。
(3)至于定时器的延时和delay延时的关系,其实我已经在例程里循序渐进地讲得很清楚,你如果有兴趣,你应该从我的第一节开始学起,自己动手做做实验。你只有了解了我switch状态机程序框架的核心思路,你自然就会明白它们的关系。

使用特权

评论回复
评论
20210707yhliu 2021-7-11 23:28 回复TA
你只有了解了我switch状态机程序框架的核心思路,你自然就会明白它们的关系。 看了楼主的SWITCH的用法, 感觉就算是多看几本书,也不如这些鲜明的示例受教。 感谢作者的分享! 
137
jianhong_wu|  楼主 | 2014-3-21 01:19 | 只看该作者
第三十五节:带数码管显示的象棋比赛专用计时器。

开场白:
2014年春节的时候,一帮朋友举行小规模的象棋比赛,有一些朋友下棋的速度实在是太慢了,为了限制比赛时间,我专门用朱兆祺的51学习板做了一个棋类比赛专用计时器给他们用。这一节要教会大家两个知识点:
第一个:按键服务程序操作的精髓在于根据当前系统处于什么窗口状态下就执行什么操作。紧紧围绕着不同的窗口ucWd来执行不同的操作。
第二个:继续加深熟悉鸿哥首次提出的“一二级菜单显示理论”:凡是人机界面显示,不管是数码管还是液晶屏,都可以把显示的内容分成不同的窗口来显示,每个显示的窗口中又可以分成不同的局部显示。其中窗口就是一级菜单,用ucWd变量表示。局部就是二级菜单,用ucPart来表示。不同的窗口,会有不同的更新显示变量ucWdXUpdate来对应,表示整屏全部更新显示。不同的局部,也会有不同的更新显示变量ucWdXPartYUpdate来对应,表示局部更新显示。

具体内容,请看源代码讲解。

(1)硬件平台:基于朱兆祺51单片机学习板。
刚上电开机时,红棋加时键对应S1键,红棋减时键对应S2键.。
刚上电开机时,黑棋加时键对应S3键,黑棋减时键对应S4键.。
比赛中途暂停双方计时的暂停按键对应S6键。刚上电时,复位双方默认20分时间的复位按键对应S7按键。
红棋的抢时按键对应S13键,黑棋的抢时按键对应S16按键。

(2)实现功能:
棋类计时器有点像抢答器,本质上有两个计时器。比赛的时候对弈的两个棋友各用一个不同的按键抢时间,红棋走一步棋后,就按一下自己的抢时按键,这个时候红棋的计时器停止计时,而黑棋的计时器开始计时,黑棋走了一步棋后,按一下自己的计时器,黑棋停止计时,红棋继续计时,依次循环,谁的时间最先用完谁就输,蜂鸣器也会发出长鸣的声音提示时间到。
上电开机默认双方各有20分钟的时间,左边显示的是红棋的时间,右边显示的是黑棋的时间。此时可以通过S1,S2.,S3,S4的加减按键来设置各自的最大倒计时时间。此时如果按下复位按键S7,会自动把双方的时间设置为默认的20分钟。
设置好最大倒计时的时间后,此时任意一方按下各自的抢时按键(S13或者S16),则自己的计时器停止计时,而对方开始倒计时。此时数码管显示的是对方的时间,而自己的时间屏蔽不显示。
在开始倒计时的时候,如果中途有棋友要接听电话或者忙别的事情,需要暂时暂停一下双方的时间,这个时候可以按S6暂停按键来暂停双方的计时,忙完后再次按下暂停按键会继续倒计时。任何一方的时间走完,都会蜂鸣器长鸣提示。
(3)源代码讲解如下:
第三十五节源代码讲解.rar (4.72 KB)
总结陈词:
这节讲了象棋比赛专用计时器的项目程序。为了继续加深读者理解按键和显示是如何有规律关联起来的,下节会继续讲一个相关的小项目程序。欲知详情,请听下回分解-----带数码管显示的加法简易计算器。

(未完待续,下节更精彩,不要走开哦)

使用特权

评论回复
138
hbc0602| | 2014-3-21 08:26 | 只看该作者
jianhong_wu 发表于 2014-3-21 01:15
(1)你看到我在定时中断里代码很多,实际上这些代码执行的时间很短。即使这个时间稍微长点也没关系,虽 ...

谢谢回复,我正在慢慢学习你的教程,因为遇到这些问题想不明白所以提问。
我是疑惑不管delay函数是否放在while(1)大循环里,怎么让它和定时中断“和平相处”。你说的如果把所有中断都停掉再去执行驱动时序,那定时器这段时间因为停摆不是会错过一些任务的执行了?(比如键盘扫描)。
还有一个问题没有提及,就是如果用定时器来做delay延时,因为不同的时候调用delay可能会需要长短不一的延时,而我上一个提问中说到,不能只定义一个累积定时中断变量,而是每个delay必须有一个独立定义的变量和标志位。是这样吗?

使用特权

评论回复
评论
阿新学单片机 2018-9-1 11:39 回复TA
@阿新学单片机 :不好意思鸿哥,我里理解错了,你那个1200是一秒中里面处理的( if(uiRedTimeCnt>const_1s) { uiRedTimeCnt=0; if(uiRedTotal>0) { uiRedTotal--;) 
阿新学单片机 2018-9-1 11:34 回复TA
你好鸿哥:我在你这里学了不少东西,真的感谢你的无私奉献。今天我在学习35课时候感觉有个疑惑(#define const_1s 422 //产生一秒钟的时间基准,unsigned int uiRedTotal=1200; //红棋的总时间),产生20分钟的延时应该是20*60*422=506400,不应该是1200吧,求解答,谢谢! 
阿新学单片机 2018-9-1 11:33 回复TA
你好鸿哥:我在你这里学了不少东西,真的感谢你的无私奉献。今天我在学习35课时候感觉有个疑惑(#define const_1s 422 //产生一秒钟的时间基准,unsigned int uiRedTotal=1200; //红棋的总时间),产生20分钟的延时应该是20*60*422=506400,不应该是1200吧,求解答,谢谢! 
139
jianhong_wu|  楼主 | 2014-3-21 12:14 | 只看该作者
hbc0602 发表于 2014-3-21 08:26
谢谢回复,我正在慢慢学习你的教程,因为遇到这些问题想不明白所以提问。
我是疑惑不管delay函数是否放在 ...

(1)即使不关闭中断,delay函数和定时中断是天生“和平共处”的,你不用过于担心。因为定时中断的时间间隔是固定的,即使在执行delay函数的时候被中断了一会,也不会有影响,只要你根据实际延时时间的需求来修改delay函数内部的执行指令次数就可以。这个时候不要严格按照时间计算公式去算,要凭感觉和实际反馈的时间来调整。
(2)即使关闭了中断,也不会错过一些任务执行(比如按键扫描)。因为delay函数是用在偶尔的驱动时序上,在系统上不做长延时用。因此关闭定时中断的时间是很短的。
(3)定时器的叫计数延时,没错,不同的计数延时要不同的变量。而delay延时是死延时,不要把计数延时跟delay延时混为一谈。不要企图用定时器来做delay延时,否则就跟死延时delay没有什么差别的。计数延时是基于整个系统框架的,delay延时只是局限于某个内部驱动时序,需要一气呵成,不能执行其他非中断任务。而定时器延时可以边延时边干其它的事情,是并行处理的。

使用特权

评论回复
140
lanchong1980| | 2014-3-21 13:29 | 只看该作者
很厉害,果然很厉害

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则