C语言到底该怎么学,单片机coder怎么才能顺利转型成为嵌入式programer?21ic论坛有一“镇站之宝”的超长经验分享贴,特此分享给所有热爱coding的你。 之前和大家谈了一点UML在嵌入式开发中的使用,以及链表、哈希表等数据结构在实现对象之间的交互机制(设计模式)的一点简单实例。有很多朋友表示很感兴趣,21ic高手云集,有点班门弄斧的感觉,所以还望尽情拍砖。之前的帖子很乱,除了因为太随意没有准备外,更主要是因为本人也处于半瓶子阶段,所谈问题题目又太大。对此我只能凭借拙见,谈点个人的理解,由于本人是这方面的新手,凭借一己之热情,大放厥词,还请各位斧正。 其实UML就是一个工具,提供了用例图、顺序图、活动图、类图、状态机图、部署图、包图等工具,辅助工程师完成:分析->设计->实施->测试的整个过程。每个过程都有细分,例如分析阶段:首先是需求分析,然后有系统分析,再次有对象结构分析等。需求分析阶段会使用到用例图、顺序图、状态机图、顺序图等,需求分析阶段的最重要的要素是软件的外部功能视图和使用场景等。其中前者使用用例图表述,它也提供了沟通用户和开发者的桥梁;后者用顺序图或状态机图等表述,提供了系统每个功能实现的可能路径。其他过程和需求分析阶段类似,这里篇幅所限就不再一一提及。UML就是这样同我们的设计过程关联起来的。 将面向对象的方法用于MCU是有必要的,也是可能的,当然也是很有效的。这样的努力最起码可以拉近mcu开发者同其他领域的C开发者之间的距离,弥补那道似乎难以逾越的鸿沟,比如看到linux内核代码时,你会发现原来如此亲切。当然,随着对面向对象方法的深入理解,你会发现C++也不再那么让你不知道如何使用,或者把C++用得像面向过程的语言一样。当然本人C++菜鸟,还望高手指教。 然而面向对象的方法也非一蹴而就,一朝搞定,它是一个循序渐进的过程,特别是应用与mcu这样的平台,好多东西是靠摸索出来的。如何开始,先从何处下手是个问题。 21ic同仁liufb提议:“正如《重构与模式》所说:如果想成为一名更优秀的软件设计师,了解优秀软件设计的演变过程比学习优秀设计本身更有价值,因为设计的演变过程中蕴藏着大智慧。” 我决定发掘一下我近十年以来的阶段性C代码,试图去发现一点什么,这个我之前还从未尝试过,能找到的一起的代码也寥寥无几。不过我觉得值得一试,那就从此开始吧。 努力发掘,搜索N年前的邮箱,居然找到了当时在一款AT89X52单片机上的处女作。就从它开始入手了。 时代背景:2006年,郑州某小公司,之前的工作是修手机,然后是在某气体传感器公司焊接维护生产设备,再后来在这家小公司画电路板,然而软件才是我的最爱。好不容易boss开恩,让我参与到写代码的行列。之前的进度让在郑州这种蜗牛般的工作节奏的大氛围里面的boss也觉得忍无可忍,于是我加入了。 代码太长,截取一部分吧。里面只有我写的一个子函数,大部分是同事写的。 由于做开始工作的同事不太会用多文件,所以这个项目的代码只有一个文件,连头文件都没有,整个文件有2600行代码。以下我将列举它的三大部分: 1.全局变量部分。 2.部分子函数。 3.main函数。 最后我将会用现在的眼光,结合大师(Grady Booch)的经典,分析一下这部分代码。 全局变量部分: bit FUN,Shift_on,Add_on,Sub_on,fun_flag;bit dspflagz1,dspflagz2,dspflagz3;unsigned char z1,z2,td3,working,DSP_m,DSP_n;unsigned char l1,l2,r,m;bitflagv,flagy,flags,flag0,flagx,beepflag1,beepflag2,flagt,flagw;bit working_on,function_on, AINTSYR_on,AINTSYW_on,BINTSYR_on,BINTSYW_on ;bitprogram_on,program_woking,up_flag,down_flag,up_on,down_on;unsigned char AINTSY_state, BINTSY_state, function_state;unsigned char tx1,tx2,tx3,tw,TX,t;unsigned char display_state ,x1,x2,w1,w2;unsigned char program_state,program_working;unsigned char clk_number;unsigned char code DS[]={0,33,63,86,100,86,63,33};unsigned chards_curtime[6]={0x05,0x03,0x02,0x01,0x07,0x06};unsigned char clk_data[6]={06,1,1,0,0,1};unsigned char set_time[6];sbit switch_work= 0xB0;sbit switch_function=0xB1;sbit switch_program=0xB2;sbit switch_up=0x90;sbit switch_down=0x91;sbit switch_AINTSYR=0x92;sbit switch_AINTSYW=0x93;sbit switch_BINTSYR=0x94;sbit switch_BINTSYW=0x95;sbit RS=0xA2;sbit RW=0xA1;sbit E=0xA0;sbit CS2=0xA3;sbit CS1=0xA4;sbit DACS1=0xA7;sbit DACS2=0xA6;sbit DACS3=0xA5;sbit ds_sclk=0xB3 ; /*初始化变量*/sbit ds_io=0xB4;sbit ds_rst=0xB5; 初评:除了最后是管脚定义外,前边都是全局的标志位或全局变量。 这个 void text(void)可是我的处女作啊 //////////////////////////////////////////////////////////////////////////////////////////////////////void text(void){ bit Flag_add; /*加一标志*/ bit Flag_sub; /*减一标志*/ unsigned char max_value; /*各时间单位的最大值*/ unsigned char min_value; /*各时间单位的最小值*/ /*if(FUN==1) { */ /*定义标志位*/ if(switch_work==0) /*移位键*/ { if(Shift_on==0) { Shift_on=1; buzzer(); clk_number++; if(clk_number>6)clk_number=1; }…