打印

大家聊聊工作项目中怎么编写程序呢,郁闷啊··

[复制链接]
6884|37
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nixianmin|  楼主 | 2011-8-16 19:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近工作中写程序,越写越乱,变量越是越来越多,
全局变量也是一大堆,用来计数的,用来标志一些
功能实现的标志量,用来缓存的:dizzy:
    刚开始一个个模块写还是没什么问题,量也不少,
但和其他没什么联系,理清还是比较容易的,越到后面
联系越多,现在我看的都晕了。
    以前写的时候也考虑过怎么去构思,到头来到什么都没
变化,依旧还是乱。程序结构,还真是不好规划,想的好
写的就乱了。
    还有中断,2个串口,3个定时器,不知道会不会出问题,
真是纠结啊:dizzy:
    大家聊聊写程序都是怎么想的,我现在只能自己一个人
摸索,没人带,也不知道程序结构怎样才算好。

相关帖子

沙发
原野之狼| | 2011-8-16 20:58 | 只看该作者
琢磨的同时 多看点优秀的作品

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
highgear + 1
板凳
youxing2009| | 2011-8-16 21:15 | 只看该作者
通常来说,我都会把程序分成三部分,应用层,功能层和驱动层。每一个层里面会放相关的.c文件和对应的.h文件,这样看起来层次分明结构清晰,对于大程序这样做很有好处,呵呵。。。再多的中断,串口和定时器,只要组织清晰分工明确,是不会有问题的。

使用特权

评论回复
地板
highgear| | 2011-8-16 21:36 | 只看该作者
这是正常现象,也是好事。这说说明楼主已经开始进入另一个层次,只要不断的自我归纳总结,有心学习他人的经验,技术必然能再上一层楼。
如果能检视得失,多花些时间重新构思软件结构,最好能重写一次,肯定会有更多的收获。

使用特权

评论回复
5
nixianmin|  楼主 | 2011-8-16 21:41 | 只看该作者
我是按模块、功能分也是一块一个.c和.h文件的,
可以我把这也功能组合在一起时就可能出问题,
像我做的东西带液晶显示、采集表数据,
每段时间对表发命令,当表将数据发上来后查下一个表,
如果收到数据格式不对那么再发送,连续几次没收到数据就采集
下一个表,还有判断没收到使用定时器,多少时间没收到就算超时。
另一个串口则等待接受数据中心的命令,如果有命令下来则做相应的响应,

感觉这些处理我用到太多的标志量,感觉有点晕,
还有有时数据在后面采集发送什么的,按键和显示会对其有什么影响,
这个也因该考虑吧,我就觉得有时思路很清晰的,合在一起就混成浆糊了。

使用特权

评论回复
6
nixianmin|  楼主 | 2011-8-16 21:43 | 只看该作者
我想操作系统的一些原理是不是可以简单的应用在这些上
以前看过一些内容是比较不错的,只是现在忙着不能静下来读,
想和大家讨论下,做完这个项目,看书去

使用特权

评论回复
7
highgear| | 2011-8-16 21:50 | 只看该作者
当然可以。操作系统的核心思想是分时分片。你可以学习一些状态机的知识,构造一个状态转移表,用不同的状态来划分程序。

使用特权

评论回复
8
nixianmin|  楼主 | 2011-8-16 22:02 | 只看该作者
我现在也是按状态来执行,分时就没了感觉会有点麻烦,什么时候看看

使用特权

评论回复
9
highgear| | 2011-8-16 22:06 | 只看该作者
如果程序中有太多的标志量,说明你没有用好状态机。状态机其中的一个好处是能大量减少标志量,看看书中是如何构造状态表,会对你有启发。

使用特权

评论回复
10
gcb_bobo| | 2011-8-16 22:08 | 只看该作者
我也碰到楼主同样的问题.每当我脑袋快乱作一团的时候,都会拿笔来画画流程图,哪怕只是随便画画,也能理清一些头绪.其实流程图和需求说明是很重要的东西,我一直都在努力规范自己的编程习惯.

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
highgear + 1
11
nixianmin|  楼主 | 2011-8-17 06:40 | 只看该作者
有没有什么书推荐给下呢

使用特权

评论回复
12
alicedodo| | 2011-8-17 07:46 | 只看该作者
《Practical UML Statecharts in C/C++, Second Edition: Event-Driven Programming for Embedded Systems》
强烈推荐这本书!!!
这本书没有中文版,网上可以下载到PDF版
另外可以逛逛这个网站http://www.state-machine.com

使用特权

评论回复
13
dqyubsh| | 2011-8-17 08:19 | 只看该作者
找一些开源的代码,学学人家的实现方法。比如,AVRLIB。

使用特权

评论回复
14
xiaotann| | 2011-8-17 08:22 | 只看该作者
量也不少

使用特权

评论回复
15
frlop| | 2011-8-17 09:37 | 只看该作者
学习。。。。

使用特权

评论回复
16
飞言走笔| | 2011-8-17 09:45 | 只看该作者
https://bbs.21ic.com/icview-237577-1-1.html
看这篇**能否给你点启发~

使用特权

评论回复
17
hopewise| | 2011-8-17 09:46 | 只看该作者
我认为good的编程结构是解决办法之一,我用的变量更多,一般100多个的,看下面:
我的主周期是固定不变的,如所有时间变量就放在时间管理子程序里



sysdata    .section  'data'
  acc_bak    equ     [40h]           ;累加器的临时保存变量
  write_count         equ     [41h]           ;临时变量
  keydwn_t            equ     [42h]           ;按键按下的次数变量
  manage_done         equ     [43h]           ;显示字母"done"的时间变量
  opened_time         equ     [44h]           ;显示字母"opened"的时间变量
  tem4                equ          [45h]           ;临时变量
  SENCOND_MPW         equ          tem4.0          ;换管理码标志位
  FIRST_MPW           equ          tem4.1          ;换管理码标志位
  cover_sta           equ          tem4.2          ;消隐标志位
  f_magnet            equ          tem4.3          ;马达开门标志位
  f_auto_door         equ          tem4.4          ;自动锁门标志位
  
  status_bak   equ     [46h]    ;STATUS的临时保存变量  
  t_125us    equ     [47h]    ;125us定时中断变量            
  buz_len    equ     [48h]    ;声音响的长度变量   
  temp0               equ     [49h]    ;临时变量   
  ;temp                equ     [4ah]           ;临时延时时间变量
  temp1               equ     [4bh]           ;临时延时时间变量
  D_TEMP              equ     [4ch]           ;临时延时时间变量
  sec2_halt           equ     [4dh]           ;按键按下的时间(这段时间内没按键按下,则进入sleep状态)
  t_second            equ     [4eh]           ;临时变量
  E_CODE_time         equ     [4fh]           ;显示字母"E_CODE"的时间变量
  USER_time           equ     [50h]           ;显示字母"USER"的时间变量
  AGAIN_time          equ     [51h]           ;显示字母"AGAIN"的时间变量
  DONE_time           equ     [52h]           ;显示字母"DONE"的时间变量
  baojing_time        equ          [53h]           ;报警时间变量
  NEU_time            equ     [54h]           ;显示字母"new"的时间变量
  delay               equ     [55h]           ;临时变量
  HOLD_disp_time      equ     [56h]           ;处于锁键盘时,按任何键,显示2秒剩下的锁键盘时间
  temp9               equ          [57h]           ;临时变量
  tem1                equ     [58h]           ;临时变量
  f_baojing           equ     tem1.0          ;报警标志位
  delete_digital      equ        tem1.1          ;删除标志位
  lock_status         equ        tem1.2          ;电子锁状态标志。锁上是1,打开是0
  f_led_on            equ        tem1.3          ;键灯点亮标志位
  f_wake_up           equ          tem1.4          ;首次按下#键的标志位
  tem2                equ          [59h]           ;临时变量
  battery_vol_low_b   equ          tem2.0          ;电池低电压标志                                       
  position_close      equ          tem2.1          ;马达的close行程开关标志位
  position_open       equ          tem2.2          ;马达的open行程开关标志位
  halt_b              equ          tem2.3          ;进入睡眠状态的标志位
  user_b              equ          tem2.4          ;换用户密码的标志位
  f_open              equ          tem2.5          ;开门状态的标志位
  f_closed            equ          tem2.6          ;关门状态的标志位
  
  delay_5             equ          [6bh]           ;临时变量
  first_mpw_time      equ          [6ch]           ;换管理码的时间变量
  temp8               equ          [6dh]           ;临时变量
  sencond_mpw_time    equ          [6eh]           ;换管理码的时间变量
  ON_OFF_time         equ          [6fh]           ;消隐显示的时间变量
  
  disp_ram1_buf       equ          [70h]           ;临时密码变量(下同)
  disp_ram2_buf       equ          [71h]           ;临时变量
  disp_ram3_buf       equ          [72h]           ;临时变量
  disp_ram4_buf       equ          [73h]           ;临时变量
  disp_ram5_buf       equ          [74h]           ;临时变量
  disp_ram6_buf       equ          [75h]       ;临时变量
  disp_ram7_buf       equ          [76h]           ;临时变量
  disp_ram8_buf       equ          [77h]           ;临时变量
  disp_ram9_buf       equ          [78h]           ;临时变量
  disp_ram10_buf      equ          [79h]           ;临时变量
  shuiyin_time           equ          [7ah]           ;水银检测时间
  baojing_delay          equ          [7bh]           ;报警时按下键不报警的时间变量(2秒)
  key_data1              equ          [7ch]
  next_time               equ          [7dh]           ;显示第6位密码后面的时间变量
  keydata                  equ          [7eh]           ;键码变量
  key_data2              equ          [7fh]           ;第1次按下的BS804B的临时保存变量
  disp_ram1              equ          [80h]           ;数码管1显示内容寄存器
  disp_ram2              equ          [81h]          ;数码管2显示内容寄存器
  disp_ram3              equ          [82h]           ;数码管3显示内容寄存器
  disp_ram4              equ          [83h]           ;数码管4显示内容寄存器
  disp_ram5              equ          [84h]           ;数码管5显示内容寄存器
  disp_ram6              equ          [85h]          ;数码管6显示内容寄存器

  disp_ram                equ          [86h]           ;查表得到显示代码
  dis_bit                   equ          [87h]           ;led灯描次序寄存器  
  keys_locking_time   equ          [88h]           ;锁键盘时键(5分钟)
  battery_low_time    equ          [89h]           ;电池电压低的时间
  battery_normal_time equ        [8ah]           ;电池电压正常的时间
  read_out               equ          [8bh]           ;读出数据暂存器
  write_in                 equ          [8ch]           ;写入数据暂存器
  word_address        equ          [8dh]           ;读写地址暂存器
  key_data3             equ          [8eh]           ;报警时按下键,暂不报警时间     
  key_data4             equ          [8fh]
            
  door_time             equ          [90h]           ;门检测时间变量
  d_count                equ          [91h]           ;临时变量
  door_open_time    equ          [92h]           ;马达的open行程开关按下的时间变量
  door_close_time    equ          [93h]           ;马达的close行程开关按下的时间变量
  SW                      equ          [94h]           ;十位
  GW                      equ          [95h]           ;个位
  
  digital_bz            equ          [96h]             ;密码位数变量1
  digital_one          equ          digital_bz.0    ;1位密码标志位      
  digital_two          equ          digital_bz.1    ;2位密码标志位
  digital_three        equ          digital_bz.2    ;3位密码标志位      
  digital_four         equ          digital_bz.3    ;4位密码标志位
  digital_five          equ          digital_bz.4    ;5位密码标志位     
  digital_six           equ          digital_bz.5    ;6位密码标志位
  
  digital_bz1         equ          [97h]              ;密码位数变量2
  digital_seven      equ          digital_bz1.0   ;7位密码标志位        
  digital_eigh        equ          digital_bz1.1   ;8位密码标志位
  digital_nine        equ          digital_bz1.2   ;9位密码标志位        
  digital_ten         equ          digital_bz1.3   ;10位密码标志位     
  
  ;total                equ          [98h]           ;关门检测次数
  time_1sec         equ          [99h]           ;1秒时间变量
  time_1minute    equ          [9ah]           ;1分钟时间变量
  keytimes           equ          [9bh]           ;密码或号码按键位数
  n_wrong    equ  [9ch]                          ;密码输入错误次数变量
  Tout                 equ          [9dh]           ;临时变量
  data_8             equ          [9eh]            ;i2c的位数变量
  lock_time          equ          [9fh]             ;按键扫描暂时存放变量
  KEY_CODE       equ           [0a0h]          ;最终得到的按键代码
  temp_keytimes  equ          [0a1h]          ;数字键按下的暂时保存变量
  cancel_press_times  equ          [0a2h]    ;*键按下次数变量
  ;key_temp        equ          [0a3h]         ;临时变量
  half_sec            equ          [0a4h]          ;半秒变量
  ;BS2_DAT        equ          [0a5h]          ;换个人密码标志变量
  buz_set           equ          [0a6h]          ;声音变量
  key_count        equ          [0a7h]          ;临时变量
  pcs_com          equ          [0a8h]          ;临时变量
  sw_bz             equ          [0a9h]           ;按键变量   
  digital_press_b equ          sw_bz.1        ;数字键按下标志位
  delete_key        equ         sw_bz.2       ;*键按下标志位
  enter_key         equ         sw_bz.3       ;#键按下标志位   
  buz_num          equ        [0aah]          ;声音变量
  flag_buz           equ          [0abh]        ;蜂鸣器标志位      
  #define    f_buzen   flag_buz.0            ;蜂鸣器使能标志位  
  #define    f_buzsta  flag_buz.1            ;蜂鸣器状态标志位  
  #define    f_buzact  flag_buz.2            ;蜂鸣器鸣叫标志位
  auto_time         equ          [0ach]
disp_close_time  equ          [0adh]


;****************主程序区*************
;*************************************
main:   
     mov      a,t_125us
     sub      a,40
     snz      c                                   ;到了5mS吗   
     jmp      main                              ;没到,则跳到main
main1:
     clr       t_125us                          ;到了,则清t_125us变量
     snz     halt_b                             ;halt_b 等于1则进入睡眠状态
     jmp     $+2                                ;为0则正常执行指令
     jmp     sleep_man                       ;睡眠管理
     clr       wdt                                 ;喂狗
     call      IC_TM1637_driver_man     ;IC_TM1637驱动管理         
     call      key_scan_man                  ;按键扫描管理
     call      led_out_man                    ;按键led灯输出管理   
     call      open_inspection_man        ;马达开门行程开关检测管理  
     call      close_inspection_man        ;马达关门行程开关检测管理
     call      voltage_chk                      ;电池电压检测管理
     call      time_man                         ;时间管理
     call      motor_man                       ;马达驱动管理(开门)                                 
     call      buz_work                         ;蜂鸣器管理
     call      baojing_man                    ;报警输出管理
     call      HM_inspect_man               ;换码开关管理
     call      shuiyin_man                     ;水银开关检测管理
     call      key_deal_man                   ;按键处理管理  
     call      disp_man                         ;显示管理
     call     door_man                         ;门行程开关管理
     call     auto_man                         ;自动锁门管理(关门)
     jmp   main

;***************************************
;**********************时间管理*********
time_man:   
        inc     half_sec
        mov     a,half_sec
        sub     a,50
        snz     c
        jmp     dddd
        clr     half_sec
        sz      Tout
        dec     Tout
dddd:
        inc     time_1sec
        mov     a,time_1sec
        sub     a,200
        snz     c
        ret
        clr     time_1sec             ;1秒钟到                  
        sz      baojing_delay
        dec     baojing_delay
        sz      disp_close_time
        jmp     dec_close_time
        jmp     iiii
dec_close_time:
        dec     disp_close_time
        sz      disp_close_time
        jmp     iiii
        mov     a,0
        mov     sec2_halt,a
        set     f_closed
        clr     f_buzen
        clr     buzzer
        
iiii:
        sz      baojing_time
        jmp     dec_baojing_time
        jmp     mmmm
dec_baojing_time:
        dec     baojing_time
        sz      baojing_time
        jmp     mmmm
        clr     f_baojing
        clr     sec2_halt
mmmm:
        sz      next_time
        dec     next_time
        sz      ON_OFF_time
        dec     ON_OFF_time           ;ON_OFF_time不为零,则减一
        sz      opened_time
        dec     opened_time           ;opened_time不为零,则减一
        sz      HOLD_disp_time
        dec     HOLD_disp_time        ;hold_disp_time不为零,则减一
        sz      first_mpw_time
        dec     first_mpw_time        ;first_mpw_time不为零,则减一
        sz      sencond_mpw_time
        dec     sencond_mpw_time      ;sencond_mpw_time不为零,则减一
        sz      manage_done
        dec     manage_done           ;manage_done_time不为零,则减一
        sz      DONE_time
        dec     DONE_time             ;done_time不为零,则减一
        sz      AGAIN_time
        dec     AGAIN_time            ;AGAIN_time不为零,则减一
        sz      E_CODE_time   
        dec     E_CODE_time           ;e_code_time不为零,则减一           
        sz      lock_time
        jmp     dec_lock_time
        jmp     next_code10
dec_lock_time:            
        dec     lock_time
        sz      lock_time
        jmp     next_code10
        clr     f_open
        clr     sec2_halt
next_code10:        
        sz      user_time
        dec     user_time
        sz      auto_time
        dec     auto_time  
        sz      sec2_halt  
        dec     sec2_halt
        inc     time_1minute
        mov     a,time_1minute
        sub     a,60
        snz     c
        ret
        clr     time_1minute          ;1分钟时间到,则清time_1minute变量
        sz      keys_locking_time
        jmp     dec_keys_locking_time ;dec_keys_locking_time不为零,则减一
        clr     lock_status           ;锁键盘时间到,则清锁键盘标置位
        ret
dec_keys_locking_time:
        dec     keys_locking_time     ;dec_keys_locking_time不为零,则减一
        sz      keys_locking_time
        ret
        clr     lock_status
        ret               























































































































































































































































  disp_close_time     equ          [0adh]

使用特权

评论回复
18
阿穆琪| | 2011-8-17 10:39 | 只看该作者
读一读nucleus的源码,完全是组件式的做法,结构写的非常漂亮,错误检查外壳函数真的很有想法。
我现在写程序文件命名、模块接口都仿他的方法,但是有些不习惯他的注释方式,就还是按老的风格。

这样搞代码量是越写越大,动辄一个小模块都要几十K。而且搭了一个程序框架之后,没日没夜的写几天都还在不同的组件中晃悠。编译都过不了,更别提调试了。
优点是虽然前期工作量很大,但后续维护会变得轻松些。结构清晰,一目了然,出了BUG很容易定位修复。

使用特权

评论回复
19
cleaver.Yeh| | 2011-8-17 11:09 | 只看该作者
一个是考虑看起来的架构,一个是考虑逻辑方面的架构,都要有层次感.可以假想,如果你向别人介绍你这个程序,你能很有条理地说清楚,就基本可以了.这样的程序,调试起来比较方便.我就喜欢这样做.

使用特权

评论回复
20
zhenxinchip| | 2011-8-17 11:36 | 只看该作者
呵呵个人的做法是先想好架构,再画下各个模块的流程图,思路就清晰了,呵呵不过是针对单片机的,大的系统不知道是怎么样的过程

使用特权

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

本版积分规则

个人签名:电机控制,TI InstaSpin Foc交流群:335663930

40

主题

431

帖子

6

粉丝