![]() |
如果有需要,我可以把相关的主程序和架构打包上传……不过说实话这些代码随便敲敲就有了,需要锻炼的是一种“精准控制”软件的逻辑的思维。 跑快了的东西我们把它放慢些,跑慢了的东西给它放快些。 对于一个系统来说,“平衡”是很重要的事情。 最后再说一句,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 进阶教程尚待坛友们自己修行,鄙人不才,只能带路到这了 ![]() |
真的是书上看不到的技术文章~~ |
写得太好了 |
真厉害 |
好文章,不知楼主能否弄成pdf格式上传呢,想保存起来!!! |
不错学习了 |
good!! |
绝世好贴! |
很好 |
感谢分享 |
这是教的程序整体架构,对于裸机(没有操作系统)开发是堪称经典的教程。 |
学会了,谢谢楼主 |
我是白菜,这个思路一下子就打开了我的思维,大多教程都是老的那一套,感谢大神的分享!! |
秒啊,好文![]() |
必须收藏了好吧![]() |
真不错,有耳目一新的感觉。![]() |
几年前的贴子怎么没有留意到呢,点了好几年的灯,看来有望进阶八级点灯大师啦![]() |
学到很多,单片机的学习最终还是必须回归到给客户服务 |
长文看不完,收藏吧 |
denggong 发表于 2025-3-9 08:28 中断讲究快进快出,除非不得已不得在中断里做太多工作 |
我直接在中断里调用显示程序,虽然占用点时间,但保证每次中断能刷新显示,不用每次刷新显存后调用显示程序。 |
受益匪浅 |
谢谢分享,学习一下 |
还以为是新帖,仔细一看原来是2019年的帖子,但是直到现在还有回复,内容真的干货。 感谢大神的无私分享。 |
把定时器封装成DELAY()MS,这样用也方便, |
很好,能看到这样的帖子很好 |
太棒了我正愁不知道该怎么办 |
感谢大佬!!值得学习!! |
14页都看了一遍,深深认识到:感谢【51黑电子论坛】及其创办者和维护人员!!!有了这个平台和这些人,才有我们学习的机会,非常感谢! |
Similarv 发表于 2019-8-19 01:00 我自已做的开发板就用了个温感芯片,还自以为很高级,惭愧啊,热敏电阻,受教受教! ![]() |
首先,感谢楼主的分享!其次,本人愚钝,看时还未茅塞顿开,但有豁然开朗的感觉,需要慢慢消化吸收。 最后,再次致谢楼主的无私分享! |
干货![]() |
不错,很有用。 |
看了楼主的教程,学到了知识 |
越学越感觉深奥 |
很好,记录一下,学习 |
不错的文章。点赞,学习了![]() |
新手进阶必读 |
经典,不知道楼主如今何处开新贴了~~ |
谢谢分享,多发一些类似文章。 |
大佬原来是这么厉害的吗,学到了继续努力 |