打印

支持匠人 ”重返技术化道路“之帖一 《程序设计总则之全部

[复制链接]
5143|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
戒指320|  楼主 | 2009-7-25 20:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
呵呵,本来想多发几贴赚个积分啊什么的,毕竟我才55分啊。匠人提议我一次发,那我这次就发完吧。

设计总则之一
程序质量的评估:
程序的优劣可以从两个方面进行评估,定量指标和定性指标
定量指标包括:
1)程序代码执行效率;
2)程序占用资源多少。
定性指标包括:
1)可调试性,即是否方便排除程序语法错误;
2)可测试性,即是否方便验证程序功能的正确性;
3)可维护性,即是否方便程序的修改和升级;
4)可移植性;
5)可读性。

设计总则之二
程序架构
   为了便于维护和移植,推荐使用层次化的软件设计方法。可把整个软件分为三层:应用层、界面层和底层驱动层,各层之间的关系如图1所示。
 

层次化设计说明:
1)底层驱动层主要包含直接和硬件相关的驱动程序,如:数码管显示、按键、蜂鸣器、继电器和电机控制等。底层的各个模块间要保持各自的独立性,不产生直接的数据交互,底层也不直接访问应用层,如果有需要,都要通过见面层进行数据交互。
2)界面层主要提供数据交互,为应用层和底层驱动之间以及底层驱动层各模块之间提供数据的交互。
3)应用层主要完成具体功能的实现,它通过界面层控制底层驱动层各模块来完成所需的功能,而不能越过界面层直接访问底层驱动层。所有的用户接口要在应用层来实现。
    a)一个好的架构必须将底层硬件包装起来,为应用程序提供一组丰富的函数操作(buffer or parameter),例如在中断的处理中,应用程序不需要知道中断的堆栈如何保护,不需要知道地址操作,只需要读取中断产生的旗标动作。
4)在即时性软件系统里面,为达到高效率的即时性与反应力,所以程序使用大量的事件触发方式来设计任务。事件有可能来自外部的触发(key、rxdata、sensor、detect……)也可能是系统内部自行产生的(timer、alarm、flag),与事件触发方式相对应的是定时查询方式,一般来说查询效率较差,因为有多余的动作而且系统反应时间与查询时间间隔有关,但是在小型的mcu系统里面用查询方式反而简单许多。

设计总则之三

设计基本原则
1)尽量减少各个子程序功能模块间的耦合度(耦合度是指一个程序的执行对另外一个程序的影响力),保证各自的独立性。一般情况下,建议子程序模块功能的划分要尽可能细化,功能尽量单一,减少子程序模块间的数据交互。
2)在满足功能需求的情况下,可适当牺牲代码的执行速度,以保证程序的透明度。
3)主要子程序模块间的交互,要通过特定的界面跟应用层进行沟通,可使用FIFO或是BUFFER两种方式。每种子程序模块都可以有自己的FIFO。例如有key buffer 、key fifo或
直接进入AP fifo三种设计方式。
4)每个子程序模块只能有唯一一个程序入口地址在程序的首部,只能有唯一一个程序出口地址在程序的尾部。
5)上电复位时要对所有的RAM空间进行初始化(建议用户寄存器清零,系统寄存器进行必要设定),不要使用未经初始化的变量。RAM未经过完整的初始化,容易导致程序执行的不确定性,这一不良现象往往在批量生产中有所体现。
6)系统中如果需要等待一些未知的应答信号,如通信或等待输入信号时,必须进行超时或异常处理,以防止程序进入“死等”状态。
例如在红外接收中,由于信号的突然消失或干扰从而无法得到一帧完整或正确的信息,这时需要复位接收程序的入口条件并退出接收程序,而不是一直等待信号的来临。不然无法进行下次接收甚至会影响到其他程序的执行。
7)通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。这种方法时解决软件空间效率的根本办法。
8)保证循环体内的工作量最小化。应仔细考虑循环体内的语句是否可以放在循环体之外,使循环体内工作量最小,从而提高程序的执行效率。
9)在多重循环中,应将最忙的循环放在最内层。
10)中断处理程序应尽量短。有效的做法为:在中断中进行标记,在主程序中进行处理。但一些实时性要求较高的程序例外。此外,进入中断时应该保存涉及道德变量和寄存器。
11)看门狗的正确使用。看门狗主要用于微控制器死机时的时间溢出复位,需要程序适时清除。正确的处理方式为:整个系统程序中尽量保证只有一处清看门狗位置,而且应处在主循环的主干位置。切忌不可在定时中断中清狗,因为微控制器有时只是在主循环中死掉。(所有AC电源的应用程序,都必须强迫加入看门狗选项,尤其是条件式的看门狗有利于系统发生异常的重启动)


   为了说明这种思想的好处,我特贴出一暖风机的应用层程序,大家看看
(当然这里面也涉及到了状态机的思想)。
/************************************************************
函数名称:mnapp
功能说明:应用层函数。
创建日期:2008.12.4
使用晶体:4MHZ晶振
************************************************************/
mnapp:
    mov    a,sys_state        ;状态分析
    @jmp_a    4    
mnapp00:
    jmp    mnapp10            ;状态0(关机)
    jmp    mnapp20            ;状态1(正常运行状态)
    jmp    mnapp30            ;状态2(温度设定状态)
    jmp    mnapp40            ;状态3(定时设定状态)

;******************************************************
;状态0事件分析
;******************************************************
mnapp10:
    clr    r
    call    rd_FIFO            ;事件分析
    mov    a,r
    @jmp_a    10
    jmp    mnapp90            ;无键按下    
    jmp    mnapp10_0        ;power on/off键
    jmp    mnapp10_1        ;模式键
    jmp    mnapp10_2        ;+键
    jmp    mnapp10_3        ;-键
    jmp    mnapp10_4        ;定时键
    jmp    mnapp10_5        ;摆风键
    jmp    mnapp10_6        ;定时设定值确认
    jmp    mnapp10_7        ;定时时间到
    jmp    mnapp10_8        ;温度设定值确认    
;0--1(关机--POWER事件)
mnapp10_0:
    mov_    sys_state,#1        ;转到状态1
    call    long_ring        ;长鸣
    mov_    LCD_buf+0,tmpbuf1    ;开机显示当前温度;????????????1    
    mov_    LCD_buf+1,tmpbuf2
    mov_    LCD_buf+3,#00010001b    ;显示温度图标和自动模式图标
    jmp    mnapp80            ;跳到mnapp80刷新显示
;0--2(关机--模式事件)
mnapp10_1:
    jmp    mnapp90            ;其他键不做处理
;0--3(关机--+事件)
mnapp10_2:
    jmp    mnapp90    
;0--4(关机---事件)    
mnapp10_3:
    jmp    mnapp90
;0--5(关机---定时事件)
mnapp10_4:
    jmp    mnapp90
;0--6(关机---摆风事件)
mnapp10_5:
    jmp    mnapp90
;0--7(关机---定时设定值确认事件)
mnapp10_6:
    jmp    mnapp90
;0--8(关机---定时时间到事件)
mnapp10_7:
    jmp    mnapp90
;0--9(关机---温度设定值确认事件)
mnapp10_8:
    jmp    mnapp90

;******************************************************
;状态1事件分析
;******************************************************
mnapp20:
    clr    r
    call    rd_FIFO            ;事件分析
    mov    a,r
    @jmp_a    10
    jmp    mnapp90            ;无键按下    
    jmp    mnapp20_0        ;power on/off键
    jmp    mnapp20_1        ;模式键
    jmp    mnapp20_2        ;+键
    jmp    mnapp20_3        ;-键
    jmp    mnapp20_4        ;定时键
    jmp    mnapp20_5        ;摆风键
    jmp    mnapp20_6        ;定时设定值确认事件
    jmp    mnapp20_7        ;定时时间到事件
    jmp    mnapp20_8        ;温度设定值确认事件
;1--1(状态1--power键)
mnapp20_0:
    jmp    mnapp70            ;关机    
;1--2(状态1--模式键)
mnapp20_1:
    call    short_ring        ;短鸣    
    call    changemodel        ;模式图标改变    
    jmp    mnapp80            ;显示刷新
;1--3(状态1--+键)
mnapp20_2:
    call    short_ring        ;短鸣
    bts0    LCD_buf+3.0        ;判断工作在何种模式下为1自动模式,为0设定模式
    jmp    mnapp20_2_1        ;工作在自动模式下,则转换到状态2
    call    fengsuinc        ;工作在设定模式下,则加风速
    jmp    mnapp80            ;显示刷新
mnapp20_2_1:
    mov_    sys_state,#2        ;转到温度设定状态
    mov_    set_tim,#250        ;2.5s确认设定
    mov_    LCD_buf+0,stmpbuf1    ;定时设定完,显示当前温度
    mov_    LCD_buf+1,stmpbuf2
    bset    LCD_buf+3.4
    bclr    LCD_buf+3.5
    jmp    mnapp80            ;显示刷新        
;1--4(状态1-- -键)
mnapp20_3:
    call    short_ring        ;短鸣
    bts0    LCD_buf+3.0        ;判断工作在何种模式下
    jmp    mnapp20_3_1        ;工作在自动模式下,则转换到状态2
    call    fengsudec        ;工作在设定模式下,则减风速
    jmp    mnapp80            ;显示刷新
mnapp20_3_1:
    mov_    sys_state,#2        ;转到温度设定状态
    mov_    set_tim,#250        ;2.5s确认设定
    mov_    LCD_buf+0,stmpbuf1    ;定时设定完,显示当前温度
    mov_    LCD_buf+1,stmpbuf2
    bset    LCD_buf+3.4
    bclr    LCD_buf+3.5
    jmp    mnapp80            ;显示刷新        
;1--5(状态1--定时键)
mnapp20_4:
    call    short_ring        ;短鸣
    bts0    LCD_buf+3.7
    jmp    mnapp20_4_1
    mov_    set_tim,#250        ;2.5s确认设定
    mov_    sys_state,#3        ;转到定时设定状态
    mov_    LCD_buf+0,setime_buf1    ;显示当前定时值
    mov_    LCD_buf+1,setime_buf2
    bclr    LCD_buf+3.4
    bset    LCD_buf+3.7
    bset    LCD_buf+3.5
    bset    LCD_buf+3.2
    jmp    mnapp80
mnapp20_4_1:
    mov_    time_buf1,#0        ;关定时功能
    mov_    time_buf2,#0
    bclr    LCD_buf+3.7
    bclr    LCD_buf+3.2    
    jmp    mnapp80
;1--6(状态1--摆风键)
mnapp20_5:
    call    short_ring        ;短鸣
    call    swing            ;改变摆风状态
    jmp    mnapp80
;1--7(状态1--定时设定值确认事件)
mnapp20_6:
    jmp    mnapp80
;1--8(状态1--定时时间到事件)
mnapp20_7:
    jmp    mnapp70
;1--9(状态1--温度设定值确认事件)
mnapp20_8:
    jmp    mnapp80

;*****************************************************
;状态2事件分析
;*****************************************************
mnapp30:
    clr    r
    call    rd_FIFO            ;事件分析
    mov    a,r
    @jmp_a    10
    jmp    mnapp90            ;无键按下    
    jmp    mnapp30_0        ;power on/off键
    jmp    mnapp30_1        ;模式键
    jmp    mnapp30_2        ;+键
    jmp    mnapp30_3        ;-键
    jmp    mnapp30_4        ;定时键
    jmp    mnapp30_5        ;摆风键
    jmp    mnapp30_6        ;定时设定值确认
    jmp    mnapp30_7        ;定时时间到
    jmp    mnapp30_8        ;温度设定值确认
;2--1(状态2--power键)
mnapp30_0:
    jmp    mnapp70    
;2--2(状态2--模式键)
mnapp30_1:
    call    short_ring        ;短鸣    
    call    changemodel        ;模式图标改变    
    jmp    mnapp80            ;显示刷新
;2--3(状态2--+键)
mnapp30_2:
    call    short_ring        ;短鸣
    call    tmpinc            ;加设定目标温度
    jmp    mnapp80            ;显示刷新
;2--4(状态2-- -键)
mnapp30_3:
    call    short_ring        ;短鸣
    call    tmpdec            ;减设定目标温度
    jmp    mnapp80            ;显示刷新
;2--5(状态2--定时键)
mnapp30_4:
    mov_    sys_state,#3        ;转到定时设定状态
    mov_    set_tim,#250        ;2.5s确认设定        
    jmp    mnapp80

;2--6(状态2--摆风键)
mnapp30_5:
    call    short_ring        ;短鸣
    call    swing            ;改变摆风状态
    jmp    mnapp80

;2--7(状态2--定时设定值确认)
mnapp30_6:
    jmp    mnapp90    
;2--8(状态2--定时时间到)
mnapp30_7:
    jmp    mnapp70            ;关机    
;2--9(状态2--温度设定值确认)
mnapp30_8:
    mov_    sys_state,#1        ;转到正常运行状态
    mov_    LCD_buf+0,tmpbuf1    ;温度设定完毕显示但前温度    
    mov_    LCD_buf+1,tmpbuf2
    jmp    mnapp80
;*****************************************************
;状态3事件分析
;*****************************************************
mnapp40:
    clr    r
    call    rd_FIFO            ;事件分析
    mov    a,r
    @jmp_a    10
    jmp    mnapp90            ;无键按下    
    jmp    mnapp40_0        ;power on/off键
    jmp    mnapp40_1        ;模式键
    jmp    mnapp40_2        ;+键
    jmp    mnapp40_3        ;-键
    jmp    mnapp40_4        ;定时键
    jmp    mnapp40_5        ;摆风键
    jmp    mnapp40_6        ;定时设定值确认
    jmp    mnapp40_7        ;定时时间到
    jmp    mnapp40_8        ;温度设定值确认
;3--1(状态3--power键)
mnapp40_0:
    jmp    mnapp70    
;3--2(状态3--模式键)
mnapp40_1:
    call    short_ring        ;短鸣    
    call    changemodel        ;模式图标改变    
    jmp    mnapp80            ;显示刷新
;3--3(状态3--+键)
mnapp40_2:
    call    short_ring        ;短鸣
    jmp    mnapp80            ;显示刷新
;3--4(状态3-- -键)
mnapp40_3:
    call    short_ring        ;短鸣
    jmp    mnapp80            ;显示刷新
;3--5(状态3--定时键)
mnapp40_4:
    call    short_ring        ;短鸣
    call    timing            ;定时设定    
    jmp    mnapp80

;3--6(状态3--摆风键)
mnapp40_5:
    call    short_ring        ;短鸣
    call    swing            ;改变摆风状态
    jmp    mnapp80
;3--7(状态3--定时设定值确认)
mnapp40_6:
    mov_    sys_state,#1        ;转到正常运行状态
    mov_    time_buf1,setime_buf1    ;开启定时
    mov_    time_buf2,setime_buf2
    bclr    LCD_buf+3.5
    jmp    mnapp90    
;3--8(状态3--定时时间到)
mnapp40_7:
    jmp    mnapp70            ;关机    
;3--9(状态3--温度设定值确认)
mnapp40_8:
    jmp    mnapp80
mnapp70:
    mov_    sys_state,#0        ;转到关机状态
    call    long_ring        ;长鸣
    mov_    LCD_buf+0,#10        ;清屏
    mov_    LCD_buf+1,#10
    clr    LCD_buf+2
    clr    LCD_buf+3
    mov_    control_buf,LCD_buf+2    ;控制刷新,关闭风扇和电热丝
    bset    CONrfb_flag
    jmp    mnapp80        
mnapp80:
    bset    LCDrfb_flag        ;显示刷新
mnapp90:
    ret

相关帖子

沙发
戒指320|  楼主 | 2009-7-25 20:37 | 只看该作者

o

这个图 贴的位置不对啊。另外我画的也不好看,大家将就一下。如果发现  总则 里有个别错别字也别在意啊,毕竟我输完这些字后 手都算了。

使用特权

评论回复
板凳
程序匠人| | 2009-7-25 21:01 | 只看该作者

这张图不错,呵呵

使用特权

评论回复
地板
戒指320|  楼主 | 2009-7-25 21:17 | 只看该作者

哇!主题旁边出现了个 ”酷“啊!这些字没白敲啊,最重要的是希望对大家有用。

使用特权

评论回复
5
itelectron| | 2009-7-25 22:02 | 只看该作者

使用特权

评论回复
6
qqdgc| | 2009-7-26 11:19 | 只看该作者

使用特权

评论回复
7
古道热肠| | 2009-7-26 11:29 | 只看该作者

总结的设计总则内容很好,的确是经验之谈

使用特权

评论回复
8
古道热肠| | 2009-7-26 11:33 | 只看该作者

俺也上一段最近写的状态机代码,让大家看看状态机有多实用,

                else
                {
                    //MCU if Free

                    ucKeyValue = KbGet();
                    if(ucKeyValue != c_Key_NULL)        //检查是否有键按下
                    {
//                        Delay(10);                        //消抖延时
                        ET0 =1;                    //开动定时器系统

                        if(ucKeyValue == KbGet())        //复检按键键码,确认有键按下进行处理
                        {
                        
                            if(ucKeyValue & c_Key_SW2_ScanCode)        //SW2按下
                            {
                                switch(ucSW2Status)
                                {
                                    case c_SW2_Status_Idle:
                                            SetSysTimer(c_SW2_DelayTimerID,10);                    
                                            ucSW2Status = c_SW2_Status_Wait1;
                                            break;
                                    case c_SW2_Status_Wait1:
                                            if(GetSysTimer(c_SW2_DelayTimerID))    
                                            {    
                                                ucPlayMusicCtrl_MacroKeyValue ^= c_MacroKeyValue_Pause;
                                                ucSW2Status = c_SW2_Status_Pause;    
                                            }
                                            break;
                                    case c_SW2_Status_Pause:
                                            SetSysTimer(c_SW2_DelayTimerID,50);                    
                                            ucSW2Status = c_SW2_Status_Wait2;
                                            break;                                            
                                    case c_SW2_Status_Wait2:
                                            if(GetSysTimer(c_SW2_DelayTimerID))    
                                            {    //长按键
                                                bSW2_ChannelSwitchFlag = ~bSW2_ChannelSwitchFlag;
                                                ucSW2Status = c_SW2_Status_Idle;
                                            }
                                            break;                                            
                                    
                                    default:
                                            break;
                                }            
                            }

                            if(ucKeyValue & c_Key_SW3_ScanCode)        //音量加
                            {
                                
                                switch(ucSW3Status)
                                {
                                    case c_SW3_Status_Idle:
                                            SetSysTimer(c_SW3_DelayTimerID,2);    //增音量放慢,符合习惯
                                            ucSW3Status = c_SW3_Status_INC;
                                            break;
                                    case c_SW3_Status_INC:
                                            if(GetSysTimer(c_SW3_DelayTimerID))    
                                            {    
                                                if(bSW2_ChannelSwitchFlag)        //检查是否为音量控制状态
                                                {
                                                    if(ucMusicVolume >c_Volume_Top_Value)
                                                    {
                                                        bVolumeValueOver = false;    //
                                                        ucMusicVolume--;        //值越小,音量越大
                                                        Mp3SetVolume(ucMusicVolume,ucMusicVolume);
                                                    }
                                                    else
                                                    {
                                                        bVolumeValueOver = true;    //音量值达边界
                                                    }
                                                
                                                }
                                                else
                                                {        //为选曲状态,切换到上一曲
                                                    ucPlayMusicCtrl_MacroKeyValue |= c_MacroKeyValue_EndPlay;
                                                    bPlaySongCount_Direction = c_MusicFile_Play_Director_Pre;
                                                }

                                                ucSW3Status = c_SW3_Status_Idle;    
                                            }
                                            break;
                                    default:
                                            ucSW3Status = c_SW3_Status_Idle;    
                                            break;                                    
                                }                
                            }

                            if(ucKeyValue & c_Key_SW4_ScanCode)        //音量减
                            {
                                switch(ucSW4Status)
                                {
                                    case c_SW4_Status_Idle:
                                            SetSysTimer(c_SW4_DelayTimerID,1);    //减音量较快
                                            ucSW4Status = c_SW4_Status_DEC;
                                            break;
                                    case c_SW4_Status_DEC:
                                            if(GetSysTimer(c_SW4_DelayTimerID))    
                                            {    
                                                if(bSW2_ChannelSwitchFlag)
                                                {
                                                    if(ucMusicVolume <c_Volume_Bottom_Value)
                                                    {
                                                        bVolumeValueOver = false;    //
                                                        ucMusicVolume++;
                                                        Mp3SetVolume(ucMusicVolume,ucMusicVolume);

                                                    }
                                                    else
                                                    {
                                                        bVolumeValueOver = true;    //音量值达边界
                                                    }
                                                }
                                                else
                                                {        //选下一曲,进行播放.
                                                    ucPlayMusicCtrl_MacroKeyValue |= c_MacroKeyValue_EndPlay;
//                                                    bPlaySongCount_Direction = c_MusicFile_Play_Director_Next;
                                                }
                                                ucSW4Status = c_SW4_Status_Idle;    
                                            }
                                            break;
                                    default:
                                            ucSW4Status = c_SW4_Status_Idle;    
                                            break;                                    
                                }                
                            }

                        }
                        //以下实现当音量调节抵达边界时,闪烁LED2的功能
                        if(bSW2_ChannelSwitchFlag)
                        {
                            if(bVolumeValueOver)
                            {    //到达音量边界时有效
                                switch(ucFlashLED2Status)
                                {
                                    case c_FlashLED2_Status_Idle:
                                            SetSysTimer(c_LED2_DelayTimerID,10);                    
                                            ucFlashLED2Status = c_FlashLED2_Status_Wait1;
                                            break;
                                    case c_FlashLED2_Status_Wait1:
                                            if(GetSysTimer(c_LED2_DelayTimerID))    
                                            {
                                                SetVS1003B_GPIO_LED2_On();
                                                SetSysTimer(c_LED2_DelayTimerID,10);                    
                                                ucFlashLED2Status = c_FlashLED2_Status_Wait2;        
                                            }
                                            break;
                            
                                    case c_FlashLED2_Status_Wait2:
                                            if(GetSysTimer(c_LED2_DelayTimerID))    
                                            {
                                                SetVS1003B_GPIO_LED2_Off();
                                                ucFlashLED2Status = c_FlashLED2_Status_Idle;        
                                            }
                                            break;
                                    default:
                                            ucFlashLED2Status = c_FlashLED2_Status_Idle;
                                            break;

                                }    
                            }
                            else
                            {    //音量在正常范围时常亮
                                SetVS1003B_GPIO_LED2_On();
                            }
                        }
                    }
                    else    //无键按下后的恢复现场工作
                    {
                        ucSW2Status =    c_SW2_Status_Idle;
                        ucSW3Status =    c_SW3_Status_Idle;
                        ucSW4Status =    c_SW4_Status_Idle;

                        bVolumeValueOver = false;
                        ET0 = 0;        //停止定时器系统,让MCU专心播放音乐
                    }

//KeyBaordProcess End
                    //由宏按键控制字刷新内部逻辑控制变量
                    if(ucPlayMusicCtrl_MacroKeyValue & c_MacroKeyValue_EndPlay)
                    {
                        bPlayEndFlag = true;
                    }
                    if(ucPlayMusicCtrl_MacroKeyValue & c_MacroKeyValue_Pause)
                    {
                        bPauseFlag = 0;
                    }
                    else
                    {
                        bPauseFlag = 1;
                    }
                    if(ucPlayMusicCtrl_MacroKeyValue & c_MacroKeyValue_EndDir)
                    {
                        bEndLoopPlayFlag = true;    //改变全局变量通知其它函数改变播放目录
                    }

                    //将内部状态刷新到显示部分,保持同步
                    if(bPauseFlag)
                    {
            
                        SetVS1003B_GPIO_LED1_On();
                    }
                    else
                    {
                    
                        SetVS1003B_GPIO_LED1_Off();
                        Macro_Set_Busy_On();            //暂停后点亮指示灯提示
                    }

                    if(!bVolumeValueOver)    //在音量调节值未溢出时,LED2由bSW2_ChannelSwitchFlag控制
                    {
                        if(bSW2_ChannelSwitchFlag)
                        {
                
                            SetVS1003B_GPIO_LED2_On();
                        }
                        else
                        {
                        
                            SetVS1003B_GPIO_LED2_Off();
                        }
                    }

                }

            }

使用特权

评论回复
9
古道热肠| | 2009-7-26 11:38 | 只看该作者

上贴实现的功能描述如下

3个按键,1个功能键,一个增加,一个为减少
短按功能键,实现暂停与播放切换
长按功能键,实现音量与选曲的切换
增加或减少,当系统处理音量调节模式时,增音或减音,当系统处于选曲模式时,选上一曲或下一曲.

使用特权

评论回复
10
戒指320|  楼主 | 2009-7-26 13:51 | 只看该作者

“指正”!8楼的大侠羞煞小弟了,小弟从来没用过c写过单片机(最多是写了个多功能闹钟),看你用c写的这么爽,小弟我也想练练。

使用特权

评论回复
11
戒指320|  楼主 | 2009-7-26 22:55 | 只看该作者

再顶!

使用特权

评论回复
12
大道至简| | 2009-7-28 08:24 | 只看该作者

楼主还在汇编呀? 稀有物种哦。。。

使用特权

评论回复
13
lifengtao| | 2009-7-28 13:57 | 只看该作者

呵呵~

我也用汇编啊~保护一下我吧~

使用特权

评论回复
14
戒指320|  楼主 | 2009-7-28 22:03 | 只看该作者

呵呵,很稀有吗?

使用特权

评论回复
15
ecook| | 2009-7-29 09:26 | 只看该作者

标记一下,以后好再看

使用特权

评论回复
16
hero0765| | 2009-7-29 10:59 | 只看该作者

留个脚印

使用特权

评论回复
17
new1988| | 2009-8-5 21:46 | 只看该作者
很有帮助

使用特权

评论回复
18
戒指320|  楼主 | 2009-8-12 19:31 | 只看该作者
荒芜了

使用特权

评论回复
19
glf| | 2009-8-13 08:46 | 只看该作者
像大家学习了

使用特权

评论回复
20
xuwanmin| | 2009-8-13 15:19 | 只看该作者
看了楼主发的帖子,对我启发很大,特别是子函数结构,程序效率部分的讲解,以前也看过一些编程方面的书,主要是C语言,对子函数的用法不是很清楚,特别是为什么只能return一个值,今天看到楼主的帖子,让我茅塞顿开。楼主我只能说,谢谢啊,希望能经常看到像这样的精华贴。

使用特权

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

本版积分规则

37

主题

290

帖子

2

粉丝