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

    [复制链接]

技术达人

发表于 2013-12-5 11:24:01   323290 查看 2167 回复 显示全部楼层 倒序浏览
分享
本帖最后由 jianhong_wu 于 2015-11-28 01:50 编辑

         大家好,我叫吴坚鸿。

第一节:吴坚鸿谈初学单片机的误区。





第六节:在主函数中利用累计主循环次数来实现独立按键的检测。
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=406259&pid=2536782&fromuid=635735

第七节:在主函数中利用累计定时中断的次数来实现独立按键的检测。
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=406259&pid=2539501&fromuid=635735

第八节:在定时中断函数里执行独立按键的扫描程序。
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=406259&pid=2542756&fromuid=635735




第十二节:按住一个独立按键不松手的连续步进触发。
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=406259&pid=2577472&fromuid=635735

第十三节:按住一个独立按键不松手的加速匀速触发。

第十四节:矩阵键盘的单个触发。

第十五节:矩阵键盘单个触发的压缩代码编程。

第十六节:矩阵键盘的组合按键触发。

第十七节:两片联级74HC595驱动16个LED灯的基本驱动程序。

第十八节:把74HC595驱动程序翻译成类似单片机IO口直接驱动的方式。

第十九节:依次逐个点亮LED之后,再依次逐个熄灭LED的跑马灯程序。

第二十节:依次逐个亮灯并且每次只能亮一个灯的跑马灯程序。

第二十一节:多任务并行处理两路跑马灯。

第二十二节:独立按键控制跑马灯的方向。

第二十三节:独立按键控制跑马灯的速度。

第二十四节:独立按键控制跑马灯的启动和暂停。

第二十五节:用LED灯和按键来模拟工业自动化设备的运动控制。

第二十六节:在主函数while循环中驱动数码管的动态扫描程序。

第二十七节:在定时中断里动态扫描数码管的程序。

第二十八节:数码管通过切换窗口来设置参数。

第二十九节:数码管通过切换窗口来设置参数,并且不显示为0的高位。

第三十节:数码管通过闪烁来设置数据。

第三十一节:数码管通过一二级菜单来设置数据的综合程序。

第三十二节:数码管中的倒计时程序。

第三十三节:能设置速度档位的数码管倒计时程序。

第三十四节:在数码管中实现iphone4S开机密码锁的程序。

第三十五节:带数码管显示的象棋比赛专用计时器。

第三十六节:带数码管显示的加法简易计算器。

第三十七节:数码管作为仪表盘显示跑马灯的方向,速度和运行状态。

第三十八节:判断数据尾来接收一串数据的串口通用程序框架。

第三十九节:判断数据头来接收一串数据的串口通用程序框架。

第四十节:常用的自定义串口通讯协议。

第四十一节:在串口接收中断里即时解析数据头的特殊程序框架。

第四十二节:通过串口用delay延时方式发送一串数据。

第四十三节:通过串口用计数延时方式发送一串数据。

第四十四节:从机的串口收发综合程序框架

第四十五节:主机的串口收发综合程序框架

第四十六节:利用AT24C02进行掉电后的数据保存。

第四十七节:操作AT24C02时,利用“一气呵成的定时器延时”改善数码管的闪烁现象。

第四十八节:利用DS1302做一个实时时钟  。

第四十九节:利用DS18B20做一个温控器  。

第五十节:利用ADC0832采集电压信号,用平均法和区间法进行软件滤波处理。

第五十一节:利用ADC0832采集电压信号,用连续N次一致性的方法进行滤波处理。

第五十二节:程序后续升级修改的利器,return语句鲜为人知的用法。

第五十三节:指针的第一大好处,让一个函数可以封装多个相当于return语句返回的参数。

第五十四节:指针的第二大好处,指针作为数组在函数中的输入接口。

第五十五节:指针的第三大好处,指针作为数组在函数中的输出接口。

第五十六节:指针的第四大好处,指针作为数组在函数中的输入输出接口。

第五十七节:为指针加上紧箍咒const,避免意外修改了只做输入接口的数据。

第五十八节:指针的第五大好处,指针在众多数组中的中转站作用。

第五十九节:串口程序第40,44,45节中存在一个bug,特此紧急公告。

第六十节:用关中断和互斥量来保护多线程共享的全局变量。

第六十一节:组合BCD码,非组合BCD码,以及数值三者之间的相互转换和关系。

第六十二节:大数据的加法运算。

第六十三节:大数据的减法运算。

第六十四节:大数据的乘法运算。

第六十五节:大数据的除法运算。

第六十六节:单片机外部中断的基础。

第六十七节:利用外部中断实现模拟串口数据的收发。

第六十八节:单片机C语言的多文件编程技巧。

第六十九节:使用static关键字可以减少全局变量的使用。

第七十节:深入讲解液晶屏的构字过程。

第七十一节:液晶屏的字符,16点阵,24点阵和32点阵的显示程序。

第七十二节:在液晶屏中把字体顺时针旋转90度显示的算法程序。

第七十三节:在液晶屏中把字体镜像显示的算法程序。

第七十四节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序。

第七十五节:在12864液晶屏中让字体以1个点阵为单位进行移动显示的算法程序。

第七十六节:如何把一个任意数值的变量显示在液晶屏上。

第七十七节:在1个窗口里通过移动光标来设置不同参数的液晶屏菜单程序。

第七十八节:在多个窗口里通过移动光标来设置不同参数的液晶屏菜单程序。

第七十九节:通过主菜单移动光标来进入子菜单窗口的液晶屏程序。

第八十节:调用液晶屏内部字库来显示汉字或字符的坐标体系和本质。

第八十一节:液晶屏显示串口发送过来的任意汉字和字符。

第八十二节:如何通过调用液晶屏内部字库把一个任意数值的变量显示出来。

第八十三节:矩阵键盘输入任意数字或小数点的液晶屏显示程序。

第八十四节:实时同步把键盘输入的BCD码数组转换成数值的液晶屏显示程序。

第八十五节:实时同步把加减按键输入的数值转换成BCD码数组的液晶屏显示程序。

第八十六节:数字键盘与液晶菜单的综合程序。

第八十七节:郑文显捐赠的工控项目源代码。

第八十八节:电子称连续不断从串口对外发送数据,单片机靠关键字快速截取有效数据串。

第八十九节:用单片机内部定时器做一个时钟。

第九十节:针对行程开关感应器,分享一种既能及时响应,又能抗干扰处理的识别思路。

点评

@吴鉴鹰 @吴鉴鸿运 你们都是好人啊  发表于 2014-4-14 15:03
吴鉴鹰 吴坚鸿都是大神级人物  发表于 2014-4-14 15:02
鸿哥,也很努力啊!  发表于 2014-4-12 13:34

评分

参与人数 9威望 +4 +4 积分 +20 收起 理由
dunziangel + 5 您的付出是论坛的动力,感谢您一直支持!.
嘉靖 + 2 您的帖子很精彩,期待您分享的下一个帖子!.
电信孩纸 + 5
GMC12345678 + 1 您的帖子很精彩,确实不错,吴老师,对于单.
梅林2016 + 5
hnnxlm + 1 您的帖子很精彩,期待您分享的下一个帖子!.
吴鉴鹰 + 1 + 1 + 1 感谢鸿哥的持续分享!
chen472015439 + 1 + 1 您的帖子很精彩,期待您分享的下一个帖子!.
谁与争锋ok + 2 + 2 NB

查看全部评分

工程师

发表于 2013-12-5 11:43:19  
鸿哥老大。QQ不用加横杠。支持你们、
回复

点赞 1 举报

技术达人

发表于 2013-12-5 11:46:19    楼主|

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
本帖最后由 jianhong_wu 于 2014-6-20 00:50 编辑
冰葑世纪 发表于 2013-12-5 11:43
鸿哥老大。QQ不用加横杠。支持你们、

谢谢。我承诺,一定会加倍奉献给论坛更加多精彩的原创内容。
回复

点赞 举报

工程师

发表于 2013-12-5 11:52:33  
jianhong_wu 发表于 2013-12-5 11:46
谢谢。第一次在论坛做点擦边球的广告,我心里有点忐忑,觉得不好意思。但是我承诺,一定会加倍奉献 ...

鸿哥出品。必属精品
回复

点赞 举报

工程师

发表于 2013-12-5 17:46:41  
是不是该叫吴老师了?
回复

举报

社区之星

发表于 2013-12-5 22:13:18  
我们必将推出史上从单片机到ARM到嵌入式最强音。
回复

点赞 1 举报

技术员

发表于 2013-12-6 00:47:59  
搬来板凳,等待吴老师讲课!
回复

点赞 0 举报

技术员

发表于 2013-12-6 20:55:18  
期待得到鸿哥的培训,鸿哥V5
回复

点赞 举报

技术达人

发表于 2013-12-7 12:21:36    楼主|
本帖最后由 jianhong_wu 于 2014-6-20 00:48 编辑

第一节:吴坚鸿谈初学单片机的误区。

(1)很难记住繁杂的寄存器?寄存器不用死记硬背,鸿哥我行走江湖多年,连一个寄存器都记不住。需要配置寄存器的时候,直接在网上或者书本上参考别人现成的配置程序是上策,查找芯片数据手册是中策,死记硬背寄存器是最最下策。

(2)很难记住繁杂的汇编语言指令?除非是在校学生要应付考试或者少数工作中绕不开汇编,否则学汇编就是浪费时间。鸿哥我行走江湖多年,从来就没有用汇编帮客户做过一个项目。

(3)C语言很难学?你不用学指针,你不用学带形参的函数,你不用学结构体,你不用学宏定义,你不用学文件操作,你也不用死记繁琐的数据类型。你只要会:
      5条指令语句switch语句,if else语句,while语句,for语句,=赋值语句。
      7个运算符+,-,*,/,|,&,!。
      4个逻辑关系符||,&&,!=,==.
      3个数据类型unsigned char, unsigned int, unsigned long。
      3个进制相互转化,二进制,十六进制,十进制。
      1个void函数。            
      1个一维数组code(或const) unsigned char array[]。
      那么世界上任何一种逻辑功能的单片机软件你都能做出来。
      鸿哥我当年刚毕业出来工作的时候才知道可以用C语言开发单片机,一开始只用if语句就把项目做出来了,没有用指针,没有用带形参的函数等复杂的功能。再到后来才慢慢开始用C语言其他的高级功能,但是我发现C语言其他的高级功能,本质上都是用我前面列举出来的最基本功能集合而成,只是书写更加简单方便了一点,编译后的机器码都大同小异。所以不会指针等高级功能你不用自卑,恰恰相反,当你会最简单的几个语句,就把这些高级功能的程序都做出来了,你才发现你对底层了解得更加透切,再学那些高级功能轻而易举。当你裸机跑的程序都能够协调得很好的时候,你才发现所谓高深的操作系统也不过如此,只要给你时间和金钱你也可以写个操作系统来玩玩。

(4)很难记住精确时间的计算公式?经常看到时间公式等于晶振,时钟周期,执行指令次数他们之间的乘除关系式。鸿哥我认为这些都是浮云,不用纠结也不用去记,大概了解一下就可以了。不管你对公式掌握得有多精确,你都不可能做出非常精确的时间。想用单片机做一个非常精确的时间这种想法一开始就是错的,不可能的。真想做一个比较精确的时间,应该用外围时钟芯片或者FPGA和CPLD,而不是单片机。

(5)很难记住繁杂的各种通信协议?什么IIC,SPI,232串口通讯,CAN,USB等等。这些都是浮云,你不用记那么多,你只要理解两种通讯方式就够了,那就是串行通讯方式和并行通讯方式。不管世界上有多少种通讯协议,物理世界上只有这两种通讯方式,其他各种名称的通讯协议都基于此两种方式演变而来。

(6)很难写短小精悍的程序?初学者不要纠结于此。做项目开发,程序容量不是刻意追求的目标,程序多一点少一点没关系,现在大容量的单片机品种非常多,容量不会是寸土寸金的事情,我们更加要关注程序的运行效率,可读性和可修改性。

      既然鸿哥列出了那么多误区,那么什么才是初学者关注的核心?预知详情,请听下回分解----delay()延时实现LED灯的闪烁。

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



回复

点赞 6 举报

技术员

发表于 2013-12-9 06:29:03  
坐等更新,鸿哥的观点很适合我们初学者。而朱老师的课程是要有一定基础才可以听懂的!
当然各有千秋。个人更喜欢鸿哥的风格!
回复

点赞 0 举报

助理工程师

发表于 2013-12-9 09:24:46  
学习板购买事项没有说明。
回复

点赞 举报

技术达人

发表于 2013-12-9 10:15:18    楼主|
本帖最后由 jianhong_wu 于 2014-2-22 22:21 编辑
3312856 发表于 2013-12-9 09:24
学习板购买事项没有说明。

要学习板你可以上朱兆祺的淘宝:http://mantoukeji.taobao.com
回复

点赞 1 举报

技术达人

发表于 2013-12-9 10:43:26    楼主|
本帖最后由 jianhong_wu 于 2014-6-20 00:50 编辑
卡布清风 发表于 2013-12-9 06:29
坐等更新,鸿哥的观点很适合我们初学者。而朱老师的课程是要有一定基础才可以听懂的!
当然各有千秋。个人 ...

我打算放下手上一部分的开发项目,专门抽些时间出来做技术分享。
回复

点赞 2 举报

技术员

发表于 2013-12-9 14:40:58  
jianhong_wu 发表于 2013-12-7 12:21
第一节:吴坚鸿谈初学单片机的误区。

(1)很难记住繁杂的寄存器?寄存器不用死记硬背,鸿哥我行走江湖多 ...

       鸿哥所言极是。开设“吴坚鸿风格的C51程序(连载)”能让广大51单片机初学者受益,此举功德无量,可谓利在当下,功在千秋。
我等初入“武林”的哥们,正等着欣赏“吴大侠”的一招一式------乃至降龙十八掌。
回复

点赞 举报

实习生

发表于 2013-12-9 15:41:09  
快快更新,等着
回复

举报

技术达人

发表于 2013-12-9 16:41:44    楼主|
lhxtzlhxtz 发表于 2013-12-9 14:40
鸿哥所言极是。开设“吴坚鸿风格的C51程序(连载)”能让广大51单片机初学者受益,此举功德无量, ...

谢谢你一如既往的支持和捧场。
回复

点赞 1 举报

技术达人

发表于 2013-12-10 14:38:42    楼主|
本帖最后由 jianhong_wu 于 2014-6-20 00:51 编辑

第二节:delay()延时实现LED灯的闪烁。

开场白:
    上一节鸿哥列出了初学者六大误区,到底什么才是初学者关注的核心?那就是裸机奔跑的程序结构。一个好的程序结构,本身就是一个微型的多任务操作系统。鸿哥教给大家的就是如何编写这个简单的操作系统。在main函数循环中用switch语句实现多任务并行处理的任务切换,再外加一个定时器中断,这两者的结合就是鸿哥多年来所有实战项目的核心。鸿哥的程序结构看似简单,实际上就是那么简单。大家不用着急,本篇连载文章现在才正式开始,这一节我要教会大家两个知识点:
第一点:鸿哥首次提出的“三区一线”理论。此理论把程序代码分成三个区,一个延时分割线。
第二点:delay()延时的用途。

(1)硬件平台:基于朱兆祺51单片机学习板。

(2)实现功能:让一个LED闪烁。

(3)源代码讲解如下:

#include "REG52.H"

void initial_myself();   
void initial_peripheral();

void delay_short(unsigned int uiDelayshort);
void delay_long(unsigned int uiDelaylong);
void led_flicker();

/* 注释一:
* 吴坚鸿个人的命名风格:凡是输出后缀都是_dr,凡是输入后缀都是_sr。
* dr代表drive驱动,sr代表sensor感应器
*/
sbit led_dr=P3^5;  

void main()  //学习要点:深刻理解鸿哥首次提出的三区一线理论
  {
/* 注释二:
* initial_myself()函数属于鸿哥三区一线理论的第一区,
* 专门用来初始化单片机自己的寄存器以及个别外围要求响应速度快的输出设备,
* 防止刚上电之后,由于输出IO口电平状态不确定而导致外围设备误动作,
* 比如继电器的误动作等等。
*/
   initial_myself();

/* 注释三:
* 此处的delay_long()延时函数属于第一区与第二区的分割线,
* 延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定。
* 比如液晶模块,AT24C02存储芯片,DS1302时钟芯片,
* 这类芯片有个特点,一般都是跟单片机进行串口或并口通讯的,
* 并且不要求上电立即处理的。
*/
   delay_long(100);

/* 注释四:
* initial_peripheral()函数属于鸿哥三区一线理论的第二区,
* 专门用来初始化不要求上电立即处理的外围芯片和模块.
* 比如液晶模块,AT24C02存储芯片,DS1302时钟芯片。
* 本程序基于朱兆祺51单片机学习板。
*/
   initial_peripheral();

/* 注释五:
* while(1){}主函数循环区属于鸿哥三区一线理论的第三区,
* 专门用来编写被循环扫描到的非中断应用程序
*/
   while(1)
   {
      led_flicker();   //LED闪烁应用程序
   }

}

void led_flicker() //LED闪烁应用程序
{
  led_dr=1;  //LED亮
  delay_short(50000);  //延时50000个空指令的时间

/* 注释六:
* delay_long(100)延时50000个空指令的时间,因为内嵌了一个500次的for循环
*/
  led_dr=0;  //LED灭
  delay_long(100);    //延时50000个空指令的时间  
}


/* 注释七:
* delay_short(unsigned int uiDelayShort)是小延时函数,
* 专门用在时序驱动的小延时,一般uiDelayShort的数值取10左右,
* 最大一般也不超过100.本例为了解释此函数的特点,取值范围超过100。
* 此函数的特点是时间的细分度高,延时时间不宜过长。uiDelayShort数值
* 的大小就代表里面执行了多少条空指令的时间。数值越大,延时越长。
* 时间精度不要刻意去计算,感觉差不多就行。
*/
void delay_short(unsigned int uiDelayShort)
{
   unsigned int i;  
   for(i=0;i<uiDelayShort;i++)
   {
     ;   //一个分号相当于执行一条空语句
   }
}


/* 注释八:
* delay_long(unsigned int uiDelayLong)是大延时函数,
* 专门用在上电初始化的大延时,
* 此函数的特点是能实现比较长时间的延时,细分度取决于内嵌for循环的次数,
* uiDelayLong的数值的大小就代表里面执行了多少次500条空指令的时间。
* 数值越大,延时越长。时间精度不要刻意去计算,感觉差不多就行。
*/
void delay_long(unsigned int uiDelayLong)
{
   unsigned int i;
   unsigned int j;
   for(i=0;i<uiDelayLong;i++)
   {
      for(j=0;j<500;j++)  //内嵌循环的空指令数量
          {
             ; //一个分号相当于执行一条空语句
          }
   }
}



void initial_myself()  //初始化单片机
{
  led_dr=0;  //LED灭
}
void initial_peripheral() //初始化外围
{
  ;   //本例为空
}

总结陈词:
鸿哥首次提出的“三区一线”理论概况了各种项目程序的基本分区。我后续的程序就按此分区编写。
Delay()函数的长延时适用在上电初始化。
Delay()函数的短延时适用在驱动时序的脉冲延时,此时的时间不能太长,本例中暂时没有列出这方面的例子,在后面的章节中会提到。
在本例源代码中,在led_flicker()闪烁应用程序里用到的两个延时delay,它们的延时时间都太长了,在实战项目中肯定不能用这种延时,因为消耗的时间太长了,其它任务根本没有机会执行。那怎么办呢?我们应该如何改善?欲知详情,请听下回分解-----累计主循环次数使LED灯闪烁。

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

点评

顶一下。现在已经从那个帖子转战这个帖子。V5,看百家之长,取其精华去其糟粕。  发表于 2014-8-17 09:54
回复

点赞 举报

技术员

发表于 2013-12-10 15:56:06  
jianhong_wu 发表于 2013-12-10 14:38
第二节:delay()延时实现LED灯的闪烁。

开场白:

首次亮相提出的“三区一线”理论非常精彩,也是做工程时常要考虑的问题之一,好好好------!如果在以后的程序中能以严格的标准来处理单点或多点输入(开关量)端口的滤波[不只是满足于51板上顺利实现程序,更要想象成面对的是q1an9林弹雨,充满强力干扰的工控环境]的话,那就是“倚天一出,谁与争锋”了。
回复

点赞 举报

技术员

发表于 2013-12-10 15:58:43  
lhxtzlhxtz 发表于 2013-12-10 15:56
首次亮相提出的“三区一线”理论非常精彩,也是做工程时常要考虑的问题之一,好好好------!如果在以后的 ...

不好意思,是“q1an9林弹雨”。
回复

点赞 0 举报

技术员

发表于 2013-12-10 16:00:10  
lhxtzlhxtz 发表于 2013-12-10 15:58
不好意思,是“q1an9林弹雨”。

q1an9
回复

点赞 2 举报

高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐 上一条 /9 下一条

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

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区