|
如果有需要,我可以把相关的主程序和架构打包上传……不过说实话这些代码随便敲敲就有了,需要锻炼的是一种“精准控制”软件的逻辑的思维。 跑快了的东西我们把它放慢些,跑慢了的东西给它放快些。 对于一个系统来说,“平衡”是很重要的事情。 最后再说一句,while(1)大循环里面不要放“delay();”或者“while(按键被按下);”了…… ![]() |
很抱歉的告诉大家,之前的想法还是太乐观,现在每天忙成狗,完全不确定啥时候能抽时间写完,7月15日要是没有更新的话还请大家谅解。![]() ![]() ![]() 不过我是不会就这么停笔的,只是不知道啥时候有时间写而已。作为打工仔,真的身不由己。 为了不辜负大家的期待,下次更新时我会把文档做成pdf,附带源码,流程图,表格一并上传。 ![]() ![]() ![]() 其实还有很多可以写的地方,但是现在这篇帖子就写这3点——时基,模块化,状态机——已经够大家消化一阵子了。而且,如果帖子的篇幅太长了,其实不利于阅读的。 以后如果还有别的分享,我会另开帖子的,多蹭点管理员的黑币,哈哈。 ![]() ![]() ![]() |
ccdmcu 发表于 2019-8-2 16:22 我不是给了个keyPress()程序么,你再好好看看。 简单来说,有键按下时,时间就会++; 无键按下时,时间就会清零。 但在清零之前会先检查,时间是否大于0,时间值大于0(或者消抖值)说明曾经有键按下过,并且刚刚松开。这时候处理“这次按键”不就好了。 |
| 楼主这文章比那些所谓的教科书好多了,那些教科书按键消抖动不动就是delay(20ms),真是误人子弟,真正出来做到大型项目才知道 DELAY是多么不实际。希望楼主继续更新,最好转成PDF,多点例程,尤其是一些按键的,短按,长按,双击组合键例程。现在绝大部份写按键程序都喜欢delay消抖,while松手检测。郭天详的书也是这么教的,一点不实用 |
laishu12345 发表于 2019-8-9 17:08 确实不会“小于”0,但“等于”0是有可能的喔,所以这样写是没问题的。 至于为什么我写了“<=",而不是”==“呢? 理由是 —— 容错机制: 万一手残了,在定义key_press_time的时候忘记加了unsigned,我们的按键程序照样可以正常工作(只是计数最大值只有原来的一半了) |
本帖最后由 Similarv 于 2019-8-15 10:40 编辑 IdeaMing 发表于 2019-8-14 10:27 这个好说,把基础时基变成10ms(或者20ms),也就是定时器中断10ms(或者20ms)产生一次。 然后就是……
|
IdeaMing 发表于 2019-8-16 16:25 我刚刚特意去查了一下,这玩意仅仅是个温度传感器,而且还特么是数字的,读一次温度居然至少要5Ms?!(还不确定是否会更久) 这样,如果你有示波器的话,请你做这么一个实验,把单片机某个端口设为输出,这个端口平时是低电平,然后用18b20读取温度之前拉高它,读取结束的时候又拉低它,然后用示波器好好的看看这个端口被拉高的时间,你就知道它每次采温需要多长时间了。再结合其他子程序的工作时长,设计你的时基。 其实,这种数字型温度传感器在我们实际做项目的人的眼里,只有华而不实四个字可以评价。如果我们的项目里需要测温,我们一般会采用内部自带adc模块的单片机,测温只要一个热敏电阻就可以搞定。整个测温的时间只需大约10us。不但更便宜,精度更好,效率还是你那个测温模块的500倍!具体方案这里就不赘述了。 |
本帖最后由 Similarv 于 2020-1-13 18:07 编辑 13303022280 发表于 2020-1-7 14:29 你的做法当然也没有问题,不过我是这么做的: 按键就只是做按键检测,并且设置相应的“按键已触发”标志(bit变量);至于按键的功能则是在别处比如状态机中去执行。 例子:当按键按下之后开/关灯 key.c 文件: bit key_flag_light; //当按键触发时为1,否则为0, 此变量是给状态机使用的 static bit key_press_light; //当按键按下时为1,未按下为0,此变量仅在key.c内使用。 函数1-keyScan() -- 功能:检测按键是否按下,若按键按下则将key_press_light置一,否则清零。 函数2-keyDeal() -- 功能:使用某静态变量统计key_press_light的时间;当key_press_light从1变为0的时候,检查静态变量的值是否大于消抖值,若大于消抖时间则将key_flag_light设置为1; state.c文件 函数1-StateMachine() -- 功能:当key_flag_light==1时,取反led_flag_out的值,随后将key_flag_light设置为0. led.c文件 bit led_flag_out; //当该值==1,开灯;当该值==0;关灯 函数1-ledOutput() -- 功能:根据led_flag_out的取值开灯或者关灯 main.c文件 在10ms或者20ms的时基中依次调用 keyScan(); keyDeal(); StateMachine(); 在100ms的时基中调用 ledOutput(); /******/ 稍微修改一下,刚刚没有认真审题,你需要做长按的判定,我这个架构是基于短按的。 修改的地方位于keyDeal()部分, 短按 —— 是等待按键松开时裁决静态变量的计时值。 长按 —— 则是直接在静态变量等于‘长按时间点’的时刻将key_flag_light置一即可。key_flag_light==1的时候,状态机自然会处理长按事件,此后keyDeal()里的静态变量会在按键继续按着的时候继续加,但其值已经‘大于’‘长按时间点’了,所以key_flag_light不会被重复置一,当按键释放之后,此静态变量清零,一切重新开始。 |
hubj627 发表于 2020-1-13 09:20 进阶教程尚待坛友们自己修行,鄙人不才,只能带路到这了 ![]() |
|
V2版本的新帖子链接: http://www.51hei.com/bbs/dpj-241462-1.html 祝大家节日快乐 ![]() |
goodgoodgood 发表于 2026-1-5 06:08 V2版本的新帖子链接: http://www.51hei.com/bbs/dpj-241462-1.html 已经更完所有内容,谢谢支持 |
很好的文章,请继续。感谢!![]() |
| 很好的文章,请继续。感谢! |
| 很好的文章,请继续。感谢! |
| 很好的文章!! |
| 赞一个! |
| 真的是好文章,对51定时器的理解更深了,原来程序还能这么写 |
| 这个不错啊 |
本帖最后由 Similarv 于 2025-11-11 11:35 编辑 wmt333 发表于 2025-7-3 07:19 : http://www.51hei.com/bbs/dpj-241462-1.html本贴已经被置顶,因此无法再编辑正文了。 V2.0帖子内有pdf文档和工程文件,感谢支持。 |
| 这个框架好 |
| 好文章,开拓新思路,奠定优秀的未来 |
|
真的是好文章,对51定时器的理解更深了,原来程序还能这么写 |
| 学习良好的编程习惯,感谢楼主的付出!!! |
| 真的是书上看不到的技术文章~~ |
| 写得太好了 |
| 真厉害 |
|
好文章,不知楼主能否弄成pdf格式上传呢,想保存起来!!! |
|
不错学习了 |
| good!! |
| 绝世好贴! |
|
很好 |
| 感谢分享 |
| 这是教的程序整体架构,对于裸机(没有操作系统)开发是堪称经典的教程。 |
|
学会了,谢谢楼主 |
| 我是白菜,这个思路一下子就打开了我的思维,大多教程都是老的那一套,感谢大神的分享!! |
秒啊,好文![]() |
必须收藏了好吧![]() |
真不错,有耳目一新的感觉。![]() |
几年前的贴子怎么没有留意到呢,点了好几年的灯,看来有望进阶八级点灯大师啦![]() |
| 学到很多,单片机的学习最终还是必须回归到给客户服务 |
| 长文看不完,收藏吧 |
denggong 发表于 2025-3-9 08:28 中断讲究快进快出,除非不得已不得在中断里做太多工作 |
| 我直接在中断里调用显示程序,虽然占用点时间,但保证每次中断能刷新显示,不用每次刷新显存后调用显示程序。 |
| 受益匪浅 |
| 谢谢分享,学习一下 |
|
还以为是新帖,仔细一看原来是2019年的帖子,但是直到现在还有回复,内容真的干货。 感谢大神的无私分享。 |
| 把定时器封装成DELAY()MS,这样用也方便, |
| 很好,能看到这样的帖子很好 |
|
太棒了我正愁不知道该怎么办 |