打印
[C语言]

我的代码简史:楼主从单片机coder到嵌入式programer的简单历程

[复制链接]
27300|134
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2014-5-16 11:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
之前和大家谈了一点UML在嵌入式开发中的使用,以及链表、哈希表等数据结构在实现对象之间的交互机制(设计模式)的一点简单实例。有很多朋友表示很感兴趣,21ic高手云集,有点班门弄斧的感觉,所以还望尽情拍砖。之前的帖子很乱,除了因为太随意没有准备外,更主要是因为本人也处于半瓶子阶段,所谈问题题目又太大。对此我只能凭借拙见,谈点个人的理解,由于本人是这方面的新手,凭借一己之热情,大放厥词,还请各位斧正。

其实UML就是一个工具,提供了用例图、顺序图、活动图、类图、状态机图、部署图、包图等工具,辅助工程师完成:分析->设计->实施->测试的整个过程。每个过程都有细分,例如分析阶段:首先是需求分析,然后有系统分析,再次有对象结构分析等。需求分析阶段会使用到用例图、顺序图、状态机图、顺序图等,需求分析阶段的最重要的要素是软件的外部功能视图和使用场景等。其中前者使用用例图表述,它也提供了沟通用户和开发者的桥梁;后者用顺序图或状态机图等表述,提供了系统每个功能实现的可能路径。其他过程和需求分析阶段类似,这里篇幅所限就不再一一提及。UML就是这样同我们的设计过程关联起来的。

将面向对象的方法用于MCU是有必要的,也是可能的,当然也是很有效的。这样的努力最起码可以拉近mcu开发者同其他领域的C开发者之间的距离,弥补那道似乎难以逾越的鸿沟,比如看到linux内核代码时,你会发现原来如此亲切。当然,随着对面向对象方法的深入理解,你会发现C++也不再那么让你不知道如何使用,或者把C++用得像面向过程的语言一样。当然本人C++菜鸟,还望高手指教。

然而面向对象的方法也非一蹴而就,一朝搞定,它是一个循序渐进的过程,特别是应用与mcu这样的平台,好多东西是靠摸索出来的。如何开始,先从何处下手是个问题。

21ic同仁liufb提议:“正如《重构与模式》所说:如果想成为一名更优秀的软件设计师,了解优秀软件设计的演变过程比学习优秀设计本身更有价值,因为设计的演变过程中蕴藏着大智慧。”

我决定发掘一下我近十年以来的阶段性C代码,试图去发现一点什么,这个我之前还从未尝试过,能找到的一起的代码也寥寥无几。不过我觉得值得一试,那就从此开始吧。
评分
参与人数 2威望 +7 收起 理由
icecut + 6
xlsbz + 1 很给力!

相关帖子

沙发
keer_zu|  楼主 | 2014-5-16 11:15 | 只看该作者
先从发掘旧代码开始吧。版主,给个裤子鼓励一下吧。我要连载。

当然我也在探索,我会尝试从不同视角去说明这个题目。。。。。。一步一步来吧。

使用特权

评论回复
板凳
dirtwillfly| | 2014-5-16 12:10 | 只看该作者
赞一个,可惜我没有这个板块加酷的权限

使用特权

评论回复
地板
lxyppc| | 2014-5-16 12:59 | 只看该作者
前排占座
看看能不能有对象

使用特权

评论回复
5
yzgwxflove| | 2014-5-16 13:36 | 只看该作者
围观

使用特权

评论回复
6
four_zhg| | 2014-5-16 14:53 | 只看该作者
坐等楼主继续

使用特权

评论回复
7
keer_zu|  楼主 | 2014-5-16 15:23 | 只看该作者
努力发掘,搜索N年前的邮箱,居然找到了当时在一款AT89X52单片机上的处女作。就从它开始入手了。
时代背景:2006年,郑州某小公司,之前的工作是修手机,然后是在某气体传感器公司焊接维护生产设备,再后来在这家小公司画电路板,然而软件才是我的最爱。好不容易boss开恩,让我参与到写代码的行列。之前的进度让在郑州这种蜗牛般的工作节奏的大氛围里面的boss也觉得忍无可忍,于是我加入了。哈哈
代码太长,截取一部分吧。里面只有我写的一个子函数,大部分是同事写的。

使用特权

评论回复
8
keer_zu|  楼主 | 2014-5-16 15:27 | 只看该作者
本帖最后由 keer_zu 于 2014-5-16 15:30 编辑

代码太长,截取一部分吧。里面只有我写的一个子函数,大部分是同事写的。
由于做开始工作的同事不太会用多文件,所以这个项目的代码只有一个文件,连头文件都没有,整个文件有2600行代码。以下我将列举它的三大部分:
          1.全局变量部分。

          2.部分子函数。

          3.main函数。


最后我将会用现在的眼光,结合大师(Grady Booch)的经典,分析一下这部分代码。

使用特权

评论回复
9
keer_zu|  楼主 | 2014-5-16 15:30 | 只看该作者
本帖最后由 keer_zu 于 2014-5-16 15:34 编辑

全局变量部分:
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;
初评:除了最后是管脚定义外,前边都是全局的标志位或全局变量。

使用特权

评论回复
评论
xlsbz 2014-5-22 08:06 回复TA
让人有重写的冲动,看大侠后续提高篇。。。 
10
keer_zu|  楼主 | 2014-5-16 15:48 | 只看该作者
本帖最后由 keer_zu 于 2014-5-17 08:51 编辑

这个 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;                             
                             }
                        }
              else
                   Shift_on=0;
              if(switch_up==0)                   /*加一键*/
                  {
                            if(Add_on==0)
                              {
                                      Add_on=1;
                                        buzzer();
                            Flag_add=1;
                                   }
                         }
              else
                        Add_on=0;
              if(switch_down==0)                   /*减一键*/
                  {
                            if(Sub_on==0)
                              {
                                      Sub_on=1;
                                              buzzer();
                                      Flag_sub=1;
                                   }
                   }
               else
                   Sub_on=0;
              switch(clk_number)
                   {
                             case 1: max_value=99;min_value=0;break;
                             case 2: max_value=12;min_value=1;break;
                             case 3:     if(clk_data[1]==1||
                                                  clk_data[1]==3||
                                                  clk_data[1]==5||
                                                  clk_data[1]==7||
                                                  clk_data[1]==8||
                                                  clk_data[1]==10||
                                                  clk_data[1]==12)
                                                  max_value=31;       /*1,3,5,7,8,10,12*/
                                               else if(
                                                  clk_data[1]==4||
                                                  clk_data[1]==6||
                                                  clk_data[1]==9||
                                                  clk_data[1]==11)
                                                  max_value=30;                   /*4,6,9,11*/
                                               else if((clk_data[0]%4==0)||clk_data[0]==0)                          
                                                  max_value=29;                   /*闰年*/
                                               else
                                                  max_value=28;
                                               min_value=1;
                                               break;
                             case 4: max_value=23;min_value=0;break;
                             case 5: max_value=59;min_value=0;break;
                             case 6: max_value=7;min_value=1;break;
                           }
              if(Flag_add==1)
                 {
                           clk_data[clk_number-1]++;         
                           Flag_add=0;
                           if(clk_data[clk_number-1]>max_value)
                         clk_data[clk_number-1]=min_value;                     
                       }
              else if(Flag_sub==1)
                 {
                          clk_data[clk_number-1]--;        
                     Flag_sub=0;
                     if(clk_data[clk_number-1]<min_value||clk_data[clk_number-1]==0xff)
                        clk_data[clk_number-1]=max_value;  
                  }
             if(switch_function==0)
            {
                  if(function_on==0)
                  {
                            function_on=1;
                            FUN=0;
                            buzzer();
                            function_state=1;
                            fun0_flag=1;
                             set_time[0]=(clk_data[4]/10)*0x10+(clk_data[4]%10);
                          set_time[1]=(clk_data[3]/10)*0x10+(clk_data[3]%10);
                          set_time[2]=(clk_data[2]/10)*0x10+(clk_data[2]%10);
                          set_time[3]=(clk_data[1]/10)*0x10+(clk_data[1]%10);
                          set_time[4]=(clk_data[5]/10)*0x10+(clk_data[5]%10);
                          set_time[5]=(clk_data[0]/10)*0x10+(clk_data[0]%10);
                           
                                          
                         }
                     }
                     else
                     {
                             function_on=0;
                         }                        
                  
}
注:上面这个函数是我在51里面跑过的第一段代码,很有收藏价值,哈哈






//////////////////////////////////////////////////////////////////////////////////////////////////////
下边是我同事的一个函数,女工程师,女中豪杰,哈哈
//////////////////////////////////////////////////////////////////////////////////////////////////////
void check_switch()
{
        if(FUN==0)
        {
                if(switch_work==0)
                {
                        if(working_on==0)
                        {   
                                working_on=1;
                                buzzer();
                                if(working==1)
                                {
                                        working=0;
                                        flag0=0;
                                }
                                else
                                {
                                        working=1;
                                        flag0=1;
                                }
                        }
                }
                else
                {
                        working_on=0;
                }
        
                if(switch_function==0)
                {
                        if(function_on==0)
                        {
                                function_on=1;
                                        buzzer();
                                        program_state=1;
                                if(function_state==1)
                                {
                                        function_state=2;
                                         
                                }
                                else
                                {
                                        if(function_state==2)
                                        {
                                                function_state=3;
                                                         
                                                
                                        }
                                        else
                                        {
                                                if(function_state==3)
                                                {
                                                                function_state=4;
                                                                FUN=1;
                                                                fun1_flag=1;
                                                                working=0;
                                                                flagx=1;
                                                }
                                                else
                                                {
                                                        function_state=1;
                                                                 
                                                }
                                        }
                                }
                        }
                }
                else
                {
                        function_on=0;
                }
        
                if(switch_program==0)
                {
                        if(program_on==0)
                        {
                                program_on=1;
                                buzzer();
                                program_working=1;
                        
                                flagv=1;
                                flagy=1;
                                flagt=1;
                                flagw=1;
                        }
                }
                else
                {
                        program_on=0;

                }
                if(switch_up==0)
                {
                        if(up_flag==0)
                        {
                                up_flag=1;
                                up_on=1;
                                        buzzer();
                        }
                }
                else
                {
                        up_flag=0;
                }
                if(switch_down==0)
                {
                        if(down_flag==0)
                        {
                                down_flag=1;
                                down_on=1;
                                        buzzer();
                        }
                }
                else
                {
                        down_flag=0;
                }
                if(switch_AINTSYR==0)
                {
                        if(AINTSYR_on==0)
                        {
                                AINTSYR_on=1;
                                        buzzer();
                                if(AINTSY_state<=63)
                                {
                                        AINTSY_state=AINTSY_state+1;
                                }
                                
                        }
                }
                else
                {
                        AINTSYR_on=0;
                }
        
                if(switch_AINTSYW==0)
                {
                        if(AINTSYW_on==0)
                        {
                                AINTSYW_on=1;
                                        buzzer();
                                if(AINTSY_state>=1)
                                {
                                        AINTSY_state=AINTSY_state-1;
                                }
                                
                        }
                }
                else
                {
                        AINTSYW_on=0;
                }               
                if(switch_BINTSYR==0)
                {
                        if(BINTSYR_on==0)
                        {
                                BINTSYR_on=1;
                                        buzzer();
                                if(BINTSY_state<=63)
                                {
                                        BINTSY_state=BINTSY_state+1;
                                }
                                
                        }
                }
                else
                {
                        BINTSYR_on=0;
                }
               
                if(switch_BINTSYW==0)
                {
                        if(BINTSYW_on==0)
                        {
                                BINTSYW_on=1;
                                        buzzer();
                                if(BINTSY_state>=1)
                                {
                                        BINTSY_state=BINTSY_state-1;
                                }
                                
                        }
                }
                else
                {
                        BINTSYW_on=0;
                }
        }
        else
        {
                text();
        }
        
}

初评:注意到没有,几乎没有用到参数传递,整个代码所有数据全是通过全局变量传递的。这个我将在后边做出分析。

使用特权

评论回复
评论
keer_zu 2021-3-12 13:47 回复TA
@mailshichao :是的,代码中出现太多if else是有问题的,代码的坏味道。避免的一个有效方法是用C语言实现类似多态的效果。 
mailshichao 2021-3-12 13:43 回复TA
if else的套娃 
11
keer_zu|  楼主 | 2014-5-16 15:51 | 只看该作者
最后是main函数:

void main()
{               
                init_working();/*初始化程序*/
                   
                               
        start_t0:check_switch();
                    
                prepare_work();
                if(fun0_flag==1){
                            ds_settime(set_time);
                }
                display();
                      
                goto start_t0;
}

使用特权

评论回复
12
红金龙吸味| | 2014-5-16 16:06 | 只看该作者
呵呵,粗略看了下,大概是根据按键来调整时间的功能。
用了大量的标志来防止一次按下,多次响应的问题。第一次写代码能够写成这样,还是非常棒的。
期待后续。不过MAIN函数里面用goto 而不是用循环,有点费解,楼主最开始学的汇编吗?

使用特权

评论回复
13
wsnsyy| | 2014-5-16 16:16 | 只看该作者
咋沒有註釋啊

使用特权

评论回复
14
keer_zu|  楼主 | 2014-5-16 16:17 | 只看该作者
红金龙吸味 发表于 2014-5-16 16:06
呵呵,粗略看了下,大概是根据按键来调整时间的功能。
用了大量的标志来防止一次按下,多次响应的问题。第 ...

除了那个Text()剩下都是别人写的

使用特权

评论回复
15
keer_zu|  楼主 | 2014-5-16 17:22 | 只看该作者
站在巨人的肩上才能看得更远,先找一个这样的肩膀吧。从关于代码演变的基础知识说起:
【基础知识普及】
Wegner将早期高级语言做了分类:


以上内容摘自GradyBooch《面向对象:分析与设计》
扩展一下Wegner的分类:



以上内容摘自Grady Booch《面向对象:分析与设计》




使用特权

评论回复
评分
参与人数 1威望 +5 收起 理由
大秦正声 + 5 赞一个!
16
keer_zu|  楼主 | 2014-5-16 18:07 | 只看该作者
接下来看一下第一代和第二代早期程序设计语言的程序结构:

特点:
1. 所有子程序共用全局数据。
2. 共用数据带来大量交叉耦合。
3. 大量的标志位或者数据定义很难读懂它到底代表什么意思。

使用特权

评论回复
17
lnhjsdf| | 2014-5-16 18:38 | 只看该作者
期盼||

使用特权

评论回复
18
lxyppc| | 2014-5-16 18:46 | 只看该作者
楼主代码贴太多了,会影响读者的

使用特权

评论回复
19
电子无聊大神| | 2014-5-16 19:19 | 只看该作者
不错,我第一次写的流水灯代码都找不到了 哈哈哈

使用特权

评论回复
20
eydj2008| | 2014-5-16 20:51 | 只看该作者
电子无聊大神 发表于 2014-5-16 19:19
不错,我第一次写的流水灯代码都找不到了 哈哈哈

没有了 , 大侠?

使用特权

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

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1352

主题

12436

帖子

53

粉丝