单片机程序设计编程规范_第1页
单片机程序设计编程规范_第2页
单片机程序设计编程规范_第3页
单片机程序设计编程规范_第4页
单片机程序设计编程规范_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机程序设计编程规范本规范适用于松翰科技8-bit MCU部门汇编程序编写准则,同样适用于代 理商及重要客户工程师编程规范参考。 本规范的目的为统一编程风格,保证程序 编写质量,提高程序的可移植性和维护性。大部分的规范严格,品质要求高的软件公司对员工编写代码的风格都有硬 性规定,例如缩排的使用,TAB的长度,函数变量的命名方式。这些规定的明显 好处是可以统一规范不同程序员所编制的代码,提升程序代码的可读性与可维护 性,同时统一格式的编程风格也为 code review提供方便。目录一、设计总则二、排版风格三、程序可读性及可维护性四、注释五、变量命名规则六、常量命名规则七、标号命名规则八、文件

2、命名规则及文件分割九、标准程序模块十、附录一、设计总则1. 程序质量的评估程序的优劣可以从两个方面进行评估,定量指标和定性指标。定量指标包括:1)程序代码执行效率;2)程序占用资源多少。定性指标包括:1)可调试性,即是否方便排除程序语法错误;2)可测试性,即是否方便验证程序功能的正确性;3)可维护性,即是否方便程序的修改和升级;4)可移植性;5)可读性。2、程序架构为了便于维护和移植,推荐使用层次化的软件设计方法。可把整个软件分为三层: 应用层、界面层和底层驱动层。各层之间的关系如下图所示。层次化设计说明:1)底层驱动层主要包含直接和硬件相关的驱动程序,如数码管显示、按键、 峰鸣器、继电器和电

3、机控制等。底层的各个模块间要保持各自的独立性, 不产生 直接的数据交互,底层也不直接访问应用层,如果有需要,都要通过界面层进行 数据交互。2)界面层主要提供数据交互, 为应用层和底层驱动之间以及底层驱动层各 模块之间提供数据的交互。3)应用层主要完成具体功能的实现,它要通过界面层控制底层驱动层各模 块来完成所需功能,而不能越过界面层直接访问底层驱动层。所有的用户接口要 在应用层来实现。4)一个好的架构必须将底层硬件包装起来,为应用程序提供一组丰富的函数操作(buffer or parameter),例如在中断的处理中,应用程序不需要资料中断的堆栈如何保护不需要知道地址操作,只需要读取中断产生的

4、旗标动作。5)在即时性软件系统里面,对达到高效率的实时性与反应力,所以程序使 用大量的事件触发方式来设计任务。事件有可能来自外部的触发(key , rxdata ,sensor detect,)也可能是系统内部自行产生的(Timer, alarm, flag),与事 件触发方式相对应的是定时查询方式(polling), 一般来说polling 效率较差因 为有多余的动作而且系统反应时间与查询polling时间间隔有关,但是在小型的MCI系统里面用Polling方式反而简单许多。3、设计基本原则1)尽量减少各个子程序功能模块间的耦合度(耦合度是指一个程序的执行 对另一个程序的影响力),保证各自的

5、独立性。一般情况下,建议子程序模块功 能的划分要尽可能细化,功能尽量单一,减少子程序模块间的数据交互。2)在满足功能需求的情况下,可适当牺牲代码的执行速度,以保证程序的 透明度。3)主要子程序模块间的交互,要通过特定的界面跟应用层进行沟通,可使用FIFO (First in,First out)或是Buffer 两种方式。每种子程序模块都可 以有自己的FIFO。例如:就按键来说,一般有 Key buffer 、Key FIFO或直接 进入AP FIFO三种设计方式。Key buffer : 一般用于保存数字按键信息。例如:在电话机的设计中,需要记录 按键内容用于LCD显示、最后数字确认、数字存

6、储等,这时候需要把按键值的 信息(0123456789*#)记录在 Key buffer 中。Key FIFO: 一些功能按键可以将相应信息列入到Key FIFO中,等待应用层的取用,这样可根据不同的工作模式进行不同的处理及动作。这些类似的观念可以应用在许多周边中:输入类:Key、RF Data in put、UART data in put、Switch in put 等。输出类:LCD display、LED display、UART data output 等。APPFIFO (应用界面层):主要是将发生的事件储存在 APPFIFO里面等待适当的 时间依序处理,不然有可能造成系统在某一程

7、序物件里面循环, 从而降低系统的 实时性(Real-Time )。4)每个子程序模块只能有唯一一个程序入口地址在程序的首部,只能有唯个程序出口地址在程序的尾部。例如:以下的写法是不规范的(两个RET出口,存在调试时不易设立断点,程序可读性 降低等问题):lable:bObtsO fzretclr yret应该改为(只有一个出口位置,标号为lable90,便于程序检查):lable:bObtsO fzjmp lable90clr ylable90:ret5)上电复位时要对所有的RAM空间进行初始化(建议用户寄存器清零,系 统寄存器进行必要设定),不要使用未经初始化的变量。RA咏经过完整的初始 化

8、,容易导致程序执行的不确定性,这一不良现象往往在批量生产中有所体现。(这点是工程师经常犯错的地方,须特别注意)6)系统中如果需要等待一些未知的应答信号,如通信或等待输入信号时, 必须进行超时或异常处理,以防止程序进入“死等”状态。例如在红外接收中,由于信号的突然消失或干扰从而无法得到一帧完整或正 确的信息,这时需要复位接收程序的入口条件并退出接收程序,而不是一直等待信号的来临。不然无法进行下次接收甚至会影响到其它程序的执行。7)通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提 高空间效率。这种方式是解决软件空间效率的根本办法。8)保证循环体内的工作量最小化。应仔细考虑循环体内的语

9、句是否可以放 在循环体之外,使循环体内工作量最小,从而提高程序的执行效率。9)在多重循环中,应将最忙的循环放在最内层。10)中断处理程序应尽量短。有效的作法为:在中断中进行标记,在主程序 中进行处理。但一些实时性要求较高的程序例外。 此外,进入中断时应该保存涉 及到的变量和寄存器。11)看门狗的正确使用。看门狗主要用于微控制器死机时的时间溢出复位, 需要程序适时清除。正确的处理方式为:整个系统程序中尽量保证只有一处清看 门狗位置,而且应处在主循环的主干位置。 切记不可在定时中断中清狗,因为微 控制器有时只是在主循环中死掉。(所有AC电源的应用程序 都必须强迫加入看 门狗选项尤其是条件式的看门狗

10、有利于系统发生异常后的重启动)二、排版风格1、 程序采用缩进风格编写,缩进为1个Tab键,1个Tab键定义为8个空格位。2、程序中的标号要从第一列开始书写。以“.”开头的预编译命令也要从第一列 开始书写,其他预编译命令采用缩进风格编写。例如:1)以“.”开头的预编译命令要从第一列开始书写, 其他预编译命令采用缩 进风格书写。丄1ST;从第一列开始书写INCLUDESTD macro1.h.CONSTNUMBER EQU 55h.DATAwkOO DS 1.CODEORG 0h2)标号要从第一列开始书写。mai n:;从第一列开始3)变量或常量的定义采用缩进风格例如:.DATAkeybuf DS

11、 1.CONSTNUMBER EQU 84) 定义变量或常量时, 变量名或常量名与命令符之间使用 2个Tab键(相 当于16个空格位)分开,命令符与后面的操作数用1个Tab键(相当于8个空格 位)分开。例如:keybuf DS 1NUMBER EQU 55h5)操作码与操作数之间用1个Tab键(相当于8个空格位)分开。 例如:ORG 80hmov a,NUMBERtable:DW 1234h6. )程序中两个操作数之间用一个“,”作为分隔符,“# ”号与立即数 之间不需要分隔符。例如:Mov a,#55h7)标号要单独占一行。8)相对独立的程序块之间必须加空行。例如:ORG 10hINCLUD

12、E sys.asmINCLUDE in t.asmINCLUDE key.asm9)程序语句后面若有注释,所有的注释要遵守上下对齐的原则例如:bOmovl,#7fh;use dpOx(hl) poin termova,#00;set poin ter = 007fh应该书写为:b0movl,#7fh;use dp0x(hl) pointermova,#00;set poin ter = 007fh三、程序可读性与可维护性1. 程序中的语句、标号、变量使用小写英文字母,常量与预编译命令使用大写英 文字母,以便和一般的语句进行区分。例如:NUMBER EQU 55h.DATAaccbuf DS 1

13、.CODEmov a,#NUMBER2. 表示不同进制的立即数,要在立即数后面加上不同的进制符号。 例如:mova,#00100011bmova,#23h不建议使用:mova,#0x233. 一般情况下,变量和常量要分开定义,不要混在一起。变量在“ .DATA ”段 中定义,采用命令符“DS ,常量在” .CONST”段中定义,采用命令符“ EQU 。 例如:.CONSTNUMBER EQU 10.DATAAccbufDS14. 程序中不使用未定义或意义不明确的常量例如:下面的赋值方法要避免使用:不要直接使用意义不明确的数字mova,#3在常量中做定义movr,a建议采用如下赋值方法:.CON

14、STNUMBER EQU 3;循环次数.CODEmova,#NUMBERmovr,a5. 整个程序的结尾要以“ ENDP语句结束。6. 当一段代码在程序中有多个地方使用时,建议采用子程序调用或宏命令的方式 来替代。如此,对该代码段的修改就可在一处完成,增强代码的可维护性。7. 程序中关系较为密切的子程序代码尽可能相邻。8. 避免程序中的垃圾代码,预留代码应以注释的方式出现。程序中的垃圾代码不 仅占用额外的空间,而且还可能影响到程序的功能与性能,很可能给程序的测试、 维护等造成不必要的麻烦。四、注释1. 程序应该包括两个部分注释,说明部分和语句注释。一般情况下,源程序有效 注释量必须在30%以上

15、。2. 说明部分:1)源文件说明部分位于每个源文件的最前面,主要描述:文件名、作者、生成日期、联络方式、功能描述、版本号、软硬件平台、版权说明、修改记录等 的简要说明,以英文书写。例如:/*File n ame:;文件名Author:;作者Date:;日期Email:;邮箱地址Descripti on:;功能描述Versio n:;版本号Hardware&IDE;软硬件平台Copyright (C), SONIX TECHNOLOGY Co., Ltd.History:;修改记录*/2)子程序说明部分位于每个子程序的最前面, 主要描述:子程序名称、功能、 设计原理、所用变量、入口条件、

16、出口信息、调用模块、堆栈层数、影响资源、 算法简述、使用说明和修改记录等。例如:/*Subrouti ne:;子程序名称Descriptio n:;子程序功能的描述Prin cipium:;程序设计原理Calls:;被本子程序调用的子程序清单Variables:;本子程序中所用到的临时变量In put:;子程序调用所需要基本参数的说明Output:;子程序调用后运算结果的说明Stack:;占用的堆栈层数History:;修改记录*刘3. 边写代码边注释,修改代码的同时修改相应注释,以保证注释与代码的一致性。不再有用的注释要删除。4. 要避免在注释中使用缩写,特别是非常用缩写。5. 程序在必要的

17、地方必须有注释,注释要准确、易懂、简洁。注释要有意义,如果有需要,还要详细描述相关含义。例如:以下是无意义的注释mov a,#5;把 5 赋给 accmov wk00,a;把 acc 赋给 wkOO应该如下注释:mov a,#5;设置循环次数为5次mov wk00,a6. 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句 的注释)的相邻位置,不可放在下方,如放于上方则需与其上面的代码用空行隔 开。例如:clr wk00;Check Read in dex = FiFo Limitcmprs a,r;ls Read in dex = LimitJmp f7. 注释格式尽量统一

18、,对多行注释建议使用“ /*/ ” ,对单行的注释建 议使用“;”。8. 注释应考虑程序易读及外观排版因素,语言尽量统一。对不能进行准确英文表 达的建议使用中文。9. 对有含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以 注释,说明其含义。五、变量命名规则1. 变量的名称要采用有意义的英文单词小写缩写。可以采用以下几种方式进行缩写命名:1) 去掉所有不在词头的元音字母。如screen可以简写为scrn。2) 使用每个单词的头几个字母。如cha nn elactivatio n可以简写为chanactiv。3) 使用变量名中具有典型意义的单词。如numberofcycle 可以简

19、写为 cyclenumber。4)去掉无用的单词后缀ing、ed等。女口 pagingrequest 可以简写为 pagreq。5 )尽量使用标准或惯用的缩写形式,缩写应该保持一致性。如serialperipheralinterface可以简写为 spi 。6)部门已经完成函式的变量名称,如果没有特别原因,发展人员延续使用 以增加可读性2. 在定义部分要加入注释来说明变量的含义。3. 变量的定义要在“ .DATA'段中。4. 变量标识符的长度不超过16个字符。5. 序会用到起码三种变量1)全局变量 名称前面不加任何修饰。2) 局部变量利用wkOO , wk01.wkOn来表示,每个独立

20、程序里面用到的Local var. 可有效节省RAM3) 中断局部变量中断里面用的 In terrupt local var.利用Iwk00, Iwk01 以作为区隔(注意中断使用的变量必定要小心的跟主程序区隔开 ,不然影响系统 稳定性相当大)。例如:.DATAaccbuf ds1;全局变量l number ds5;局部变量6.位定义。程序多处会经常对寄存器的某一位进行操作,可以在变量定义时对需要用到的位进行定义,建议名称以”f_”开头。7.临时工作寄存器的定义。程序中经常需要用到一些临时存储数据的寄存器, 我们称之为临时工作寄存器,这些临时工作寄存器的命名方法为 “wk”加上一个二位数字组成

21、,这个数字可以从“00”开始随着需要定义的临时工作寄存器的数量 的增加而增加。需要特别说明的是,临时工作寄存器的使用可以大量节省 RAM 空间,但是要注意相应的生命周期,必须在子程序退出之前,将空间释放以便其 它子程序使用。8.在中断处理程序中用到的寄存器,为了和一般的临时工作寄存器作以区分, 可 以在寄存器前面加英文字母“ i”来命名。在使用时需要加以注意,不要和主程 序中的变量复用。例如:.DATAwk00ds1wk01ds1wk02ds1iwk00ds1 ;中断中要用到的临时工作寄存器iwk01ds1 ;中断中要用到的临时工作寄存器CODEMova,rMovwk00,amova,wk01

22、movr,a六、常量命名规则1. 常量的名称要采用有意义的英文单词大写缩写2. 常量要定义在“ .CONST段中。3. 在定义部分要加入注释来说明常量含义。4. 量标识符的长度不超过16个字符。5. 系统寄存器中常用到的某些位可以再额外进行定义,但要有意义:P_key1 EQU P1.0 ;P_打头表示为Port 定义Pm_key1 EQU P1m.0 ;Pm_打头表示为Port 方向定义七、标号命名规则1. 标号的名称要采用有意义的英文单词小写缩写。2. 子程序标号定义。在同一个子程序中,所有的标号应该有规律可寻。建议第一 个标号为子程序名,下面所用到的标号用子程序名添加数字表示,从而便于今

23、后 程序的添加和修改。数字尽量使用两位数,在子程序的退出位置,数字一般为” 90”。例如:在一段按键扫描程序中,如下的标号是不可取的。Label:LabelOKLabelFailLabelQuitLabelf un:LabelE nd:Ret(设计师要花许多精神命名label,同时不容易看出子程序的结构关西,所以建 议在子程序里面别在花精神命名,都用号码表示)(详细的动作都用注解来说明) 应该改为: *J;Sub-routi ne , Name : label *JLabel:If the con diti on fail the n go to Label90;program beg in

24、hereLabel10:;注解都写在这里Label20:;最后结尾结束的label都用90当做结尾:有助于程序的阅读Label90:Ret3. 为了使程序的结构更加清晰,子程序的命名要尽量能显示出相互间的调用关系。由main主循环中直接调用的程序,要以“ mn_作为标号的开头,下面仅列出一些常用的子程序名称,其它类似情况可同样处理。mn_app系统应用程序mnn tg nd中断与主程序之间的界面子程序mn _key按键扫描子程序mn led;LCD显示子程序mn led;LED显示子程序mn tone声音处理子程序mn_epp;EEPROM读写操作mn bio基本输入/输出控制mn ade;A

25、DC输入及处理mn_debug;debug处理程序4. 程序的几个常用入口地址命名如下:复位入口:reset中断入口:isr主程序入口:mai n例如:orgjmpresetorgjmpsr;ISR(In terrupt Service Routi ne)org10;有效程序开始地址reset:;进入主程序前的一些准备工作(预处理)prema in:;主程序循环圈main:Jmp mai n八、文件名的命名规则及文件分割1. 在一个项目中要包括两种文件:源文件和头文件。源文件是程序体,扩展名为“ .asm ” ,头文件包括了变量、常量、宏命令的定义,扩展名为” .inc ”。2. 头文件的命名

26、头文件用三个不同的文件来分别定义常量、变量、宏命令,其命名方法如下:常量定义文件:xxx_equ.i nc变量定义文件:xxx_ram.i nc宏命令定义文件:xxx_macro.i nc其中,xxx表示项目的名称。例如:作一个电话机的完整程序,头文件可如下定义:常量定义文件:pho ne_equ.i nc变量定义文件:pho ne_ram.i nc宏命令定义文件:phon e_macro.i nc3. 源文件分为主文件、子文件。主文件包括了项目的主程序,它描述了芯片信息、CODEOPTIO信息及项目包含的其它子文件模块。子文件是由各个子程序模块组 成,功能相近的子程序要放在一个文件中,文件名

27、可以用“项目名+模块功能的缩写+扩展名”表示。下面列举一些常用的文件名:主程序文件:xxx_ma in.asm常用的子文件定义:中断服务程序模块:xxx_i nt.asm进程处理模块:xxx_pro.asm系统处理程序:xxx_sys.asm按键处理模块:xxx_key.asmLCD显示模块:xxx_lcd.asm其中,xxx表示项目的名称。九、标准程序模块常用功能模块尽量采用附件提供的标准程序,如果无法使用标准的程序模块, 那 么所编写的程序一定要符合规范要求。 所提供的标准程序如下,详细的源代码在附录中。1.mn _keyJ单键扫描子程序2.mn_mulkeyJ多键处理子程序3.mn_to

28、neJ声音处理子程序4.mncd;LCD显示子程序5.mn_i2c;I2C操作子程序6.mn_sio;SIO操作子程序7.mn_1wireJ单总线操作子程序8.mn_ uart;UART子程序9.wr_fifoJ写 FIFO10.rd_fifoJ读 FIFO11.ram2ram;RAM到RAM的数据传递12.rom2ram;ROM到RAM的数据传递13.mathJ基本运算程序实例说明1.初始化1)当程序上电复位时,一个完整的用户寄存器初始化或清零动作是非常重要的,否则容易造成程序执行的不确定性。例如:pre_clrRAM:bOmov y,#0;清 RAM bankObOmov乙 #48:Clr

29、yzdeemszjmpbclryzret2)系统寄存器必须进行初始化,比如说I/O 口方向和输出电平等。需要特 别说明的是输出口的初始化必须按照下列顺序来处理:(1) 设定相应I/O 口输出高低电平(2) 将相应I/O 口为输出口如此可确保 MCU的I/O 口从输入模式转 为输出模式时不会有脉冲的存在。 而在I/O 口控制频繁变化(如通信)时更要 引起注意。例如:(3) mov a,# 11111111b;如果p1.0和p1.1原来为输入高电平,当直接切换为输出方式时会有高电平 脉冲的输出,而这不是所希望的。bOmovp2m,amov a,# 11111100bbOmovp2,a mova,#

30、00001100bbOmovp2,a;这样处理p1.0和p1.1就避免了高电平脉冲的输出mov a,#11111111b ;bOmov p2m,a开机时后IO toggle 的作法:利用暂时没有用到的IO做toggle 可有效观察以下几点1)系统是否正常开机2)是否发生 reset or watchdog reset 现象3)程序是否重头运行观察10 toggle pulse width 可以了解In ternal RC频率的准确性或是协助调整外部RC数值以上方法可以有效协助量产生产问题开机时后Test Mode的作法:Test Mode必须在开机时后按下某些组合按键同时通过de-bounee

31、才可进入test mode2. 按键处理1)一般来说key的处理是所有程序的基础教科书里面所教导的key处理观念大多以delay循环与多次检查来处理弹跳事件,但是此种方法由于导入delay 循环大大降低系统实时性,而大多使用者都没有警觉此问题依然延续此观念 设计key scan and de-bounee技巧,此份文件详细叙述key处理观念。2)家电产品中经常用到抗干扰的测试 EFT,会从电源端打入噪声测试系统抗 噪声能力,如果key处理不好会有key误动作产生,一般使用者会在key sean 地方加入电容以减低此问题的产生,但是此方法还是无法完全避免此问题 同时 还增加硬件成本,这里提出的d

32、e-bounee观念可以完全解决此问题。3)按键处理很多程序员都会将系统的程序设计与key程序结合没有分开结构,这造成很多程序就以key程序 变成程序主体来运行,这里提出将key动作 得出的keycode到fifo(first in first out)中,使得AP系统得以在有空闲的 时候才处理key code动作,程序架构自然形成。4)一般来说key处理都只侦测key down,但是在某些系统确有key downand keyup的要求,这方面可以透过 key in buffer 的储存new/old buffer XOR 比对得到key eve nt,更深一层的技巧侦测多按键处理更是需要利

33、用n ew/oldbuffer XOR来处理合理的按键处理一般包括按键扫描、按键弹跳处理、按键输出转换等环节。例如:mn _key:callkeyin ;读取按键输入将资料储存在key in buf里面Callkeychk ;按键弹跳处理Callkeycvt ;弹跳处理后,将按键扫描码转换储存到FIFO里面!ret keyi n-按键扫描,其主要负责将外部按键信息读入到内部buffer 中。用的按键般包括:直接按键、M*N矩阵式扫描按键、三角形按键、扩充按键、按键与其它周边共享I/O脚位等,部分场合还要考虑睡眠和按键的唤醒功能。 下面进行分别说明:1) 直接按键最简单的按键方式,通常作法利用M

34、CU里面的pull-up电阻上拉,外面按键落地,平时没有按键的时候,MCU in put端口读到Hi ,按键按下时候读到 Low,如下图所示:2) M*N矩阵式扫描按键最典型的按键扫描方式,有分Single key , multi-key 扫描。单按键扫描:一个时间只允许一个按键动作同时也只读取一个按键。多按键扫描:一个时间允许一个以上的key按下,但是只读取最新按下 的按键。扫描注意事项:一般来说扫描的作法 有Output port and in put port配合Output port 1110110110110111依序送出0信号 让in put port 读取,但此时可能发生两件冲突

35、事件需要如果用output 0 and output 1 的组合来送出scan pattern , 当客户同时 按下同一排两组按键的时候,会有短路现象,传统作法是加入 二极管diode来 保护,现在单片机的作法则是利用 output din put pull-up R的方式来达成。见图面说明但是当使用In put pull-up R 时候 又有另外一件事情要注意就是当111001101 时候,bitO =output 0 din put pull-up 1 , 必须是 bit 0 = output 0 doutput 1 din put pull-up中间必须经过output 1 的动作,这动

36、作要协助output 0的信号直接快速拉至Hi准位,然后再切换入inputmode,如果直接 output 0 din put mode,此时会有一个较长的上升时间,导致key sea n错误3)三角形按键效的增加扫描按键数目,见图面说明4)扩充按键可以加上diode增加key scan 数目见图面说明5)按键与其它周边共享I/O脚位6)ADC与RF接收机杂音避免的方式 keychk按键弹跳处理,其主要负责滤除按键输入口灌入的杂讯或按键弹跳 杂波。1)一般建议 弹跳时间 处理约在70mS 100mS , EFT特性如果要好 可以更加长到使用者可接受到最常时间200mS2)弹跳时间的处理并非用d

37、elay loop 延迟,这会降低系统的实时性与反应力必须检查的动作放在主程序循环里面配合keychat time的递减来完成。3)如果主循环绕圈时间1mS那按键稳定检查连续次数可高达100次左右 这对于Key处理来说是非常稳定的。4)弹跳的检查是连续检查key变化后维持相同状态100mS比如说key 按下后Hi变成Low这时候程序侦测到输入有异动便开启检查时间机制 ,当程 序连续检查100mS都发现Low没有改变的时候便发出key eve nt ,此时才有按 键发生。5)关于de-bounee的程序验证可透过修改弹跳时间测试,比如说故意将弹 跳时间改1sec.观察在一秒内的按键动作是否都不成

38、立,只有按键持续达一秒 以上 才有动作产生,确认后再将弹跳时间改回。 keycvt 按键输出转换,其主要负责将确认的按键信息进行转换和存储。1)KeyCVT主要工作将经过de-bounee的keybuffer跟之前所得到的key相比对,看看新的key eve nt为何,转换出来后 存储到keybuffer or keyfifo 至直接进入apfifo2)将key code储存到fifo中是一个非常重要的观念,这里展示出Key处理是一个独立的物件程序,他的运行跟其他程序都没有相关,唯一对外的界面 in terface 就是fifo 。而key的处理方式端看当时系统的 status 还有AP设 计

39、的流程才做出相对应的工作 Task。3. 计时系统计时系统一般包括定时器初始化和定时设置及处理两部分。1) 定时器初始化部分又包括:(1) 定时器控制寄存器的设定(2) 相关用户寄存器的设定(3) 定时时间的初始化2) 定时设置及处理:由于系统里面会经常在不同的时间点执行不同的动作,所以定时的设置及处理变的尤为重要。例如需要以下时间的定时:10ms定时: 每10ms产生定时到达标志位100ms定时: 每100ms产生定时到达标志位1000ms定时: 每1000ms产生定时到达标志位一般来说,10ms的工作可放在中断处理程序或主程序循环圈中执行,至于采取 哪种方式主要是看时间准确性的要求。100

40、ms以上的工作如果没有特别的要求建 议放在主程序循环中执行。此外在系统时间设计中,时间不准确的问题经常发生,一般来源于时基的计算与处理。可以在定时中断处理程序中输出一个方波来 检查中断发生的时间。定时设置及处理有两种方法可作参考:(1)计算法:利用MCU本身的定时中断作出10ms的时基,再利用计算的方法作出100ms、1000ms的定时。累加法:此方法适用于对时间没有特别要求的场合。下面以四位位元依次累加来说明做法:假设变量timeslot 以每5ms的时间来累加:timeslot= 0 0 0 btimeslot= 0 0 1 b ;bitO=1, 5ms动作timeslot= 0 1 0

41、b ;bit1=1,产生 10ms flagtimeslot= 0 1 1 b ;bit0=1,执行5ms动作,此时不再检杳bit1timeslot= 1 0 0 b ;bit2=1,产生 20ms flagtimeslot= 1 0 1 b ;bit0=1,执行5ms动作timeslot= 1 1 0 b ;bit1=1,执行10ms动作timeslot= 1 1 1 b ;bit0=1,执行20ms动作timeslot= 0 0 0 b ; 没有动作由上面例子的规律来看,一个时间只会有一个时间任务产生,从而不会有太多 的时间单位。4. 中断和主程序的处理1)Push and PoP 动作要

42、确实完整i. 请参照不同母体的建议作法2)透过mnintgnd副程序来操作i. Interrupt中产生的动作 可以在中断中直接处理(又急又准的需求)约mS等级的动作 如tone output , RF TX,有些计时参数的递减等ii. 不需要在中断处理,设立旗标flag 等待在主程序中检查处理 (mnintgnd)约100mS以上的动作:女口 0.5S计时动作,某些timeout 命令需要 AP层处理iii. 需要了解interrupt暂用系统多少时间,可以在进入中断时候做一个output H离开中段时候作个output L 来观察,当然这方面可以利用假 指令(If Debug = 1 )

43、来设置,当系统完成后 将此output H/L 动作关闭,进 入中断所占用的时间越短越好,原则是只要能够在主程序处理的动作都在中断里面设定flag 等到主程序(mnintgnd)处理,所以中断/主程序的比例越低越好(这里也可以透过主程序循环的toggle 来观察主循环的绕圈时间)。5.EEPROM的读写操作1) EEPRO M的使用有以下几个问题要注意i.EEPROM write timea) write , delay , write需要一些时间,所有有两种作法,不建议使用除非写入资料很少,暂用系统时间少2)write, check busy, write超过 10 byte data 以上

44、ii. 透过 buffer read/writeiii. 24series EEP要特别注意ACK讯号(绝大部份的设计者都失败在 ACK信号的处理,造成系统稳定性不佳),同时上拉电阻的设置对于24series也是很 重要的iv. 品牌较差的EEPRO普遍存在datalost的问题当有高电压脉冲的时候(尤其开机瞬间)很容易将内部资料清除,所以这方面要注意,当然开机那瞬间 MCU寸于EEP的 output设定也是很重要的很容易在开机瞬间误写错误信息给EEP6. T0ne的处理1)可能MCU产生的tone 有下列几种i. 配合按键动作的 Key tone 约 100mS single tone。ii

45、. 电话响铃音 来电转接音 保留音。iii. 标准音乐Do-Re-Mi等。iv. 警示音 error tone 。7. Display 的处理1)LCD Display程序的唯一性尤其LCM模块使用更是重要i. 平时LCD都是透过LCD Buffer(RAM)来作为in terface, 当AP层面有更 动LCD资料并不直接对LCM硬件操作,而是针对RAM Buffer更动资料 同时设 立 LCDREQ flag。ii. MNLCD里面发现LCDREQ=1时候才进入MNLCD程序运行显示更新,此法可有效改善效率与显示的稳定性。iii. 相同如果非LCM的操作有些人认为可以直接更改LCD RAM

46、数值直接 更新显示,这也存在相当大的风险,最好的方式还式透过另外一组Buffer来 做缓冲。iv. 松翰的ICE发展系统有提供软件LCD模拟器给客户使用 当客户的LCD 还没有实体,可以透过模拟器直接在PC画面上显示,配合程序开发非常方便8. Telecomm 的处理1) S ync (with clock) and Async.2) Sync.类似 SPI 信号 data in, data out, and clock3) Async.本身没有Clock时钟信号 一般来说有以下几个组成i. Bit sync位元同步ii. Frame sync特定的 frame code 来锁定 frame

47、data 开始iii. Data length资料长度来收集资料iv. Checksum最后靠check sum 来验证资料的正确性4) 一般来说同步或异步通信程序都是TX容易/ RX 译码困难i. 拍码TX只需要考虑大笔资料拍码的 buffer and pointer 影响程序实 时性不大。ii. 接收RX部分就有点困难 需要有较多的技巧考量 尤其异步通信更是 麻烦。5) RF通信里面还要考虑拍码调变的方式某些硬件电路只能利用曼彻斯特编码 法来拍码以去除DC分量9. Main Loop 的处理1) 进入主程序循环前要有个”前处理”(Pre_Main)来将基本参数设置好才进入 主循环2) 看门

48、狗/条件式看门狗 能够放在主循环内,可以确保主循环有效的运行,当 主循环运行失败,“看门狗”自然发生Reset动作3) 主循环的绕圈时间(实时性 系统反应力)i. 牵涉到系统的实时性(real-time) 所以绕圈时间越短越好 建议在5mS 以内,利用IO toggle 来观察主循环绕圈时间,如果程序里面有多余的IO就 可以留下此IO供日后生产测试观察使用,如果没有多余 在程序稳定后可以将此 观察的IO移除。ii. 主循环绕圈时间也会受到中断的影响,由于中断的执行等级高于主循环 所以当中断运行时间越长自然主循环的运行时间也越长 ,所以中断里面占用时间 必须稳定的控制,不然影响系统实时性/反应性

49、很大。iii. 主循环里面每一个物件都要设计良好才能确保一个整体的绕圈时间, 每一个子程序物件进入前,都必须透过旗标判断是否需要执行,如MNLCD程序进入后立即检查是否lcdreq=1 ,如果在此绕圈动作中没有任何led资料更 新,那也就不用浪费时间进入led sub-routine。另外如EEP储存动作由于会有write data busy问题所以也必定要将资料分批写入,不然程序会停留在write data循环里面影响当时整体实时性。10. Watchdog 的处理1)Watchdog功能说明2)Watchdog方块图说明3)条件式清除watchdog4)使用地方注意事项11. Applic

50、atio n的处理1)透过 APFIFO 读取 APCodei. APFIFO越大越能够了解系统发生过的事件 (event)有助于system debug, 只要在ICE上面stop运行 观察FIFO buffe r里面的数值 就可以知道哪些动 作进入FIFO发生过哪些事情ii. 同时系统里面有 keybuffer , lcd buffer, tx buffer , rx buffer ,eeprom buffer ,tone buffer 利用 FIFO and Buffer 的观察,软件系统的除错 性自然产生2)APCode的编排设计i.由于程序最后可以透过PC跳转 所以APcode的数值设计就非常重要。3)根据不同的status 可以展开所有动作有两次跳转动作设计出所有的命令4)程序最后可达到表格化设计的境界利用跳转表格将程序的流程具体化12. Power dow n and wakeup1)省电的考量(系统耗电应该低于1uA/5V)i. I nput pin :内部Pull-up resistor或是外部设定皆可ii. Outputiii. Power down失败的情形 wake-up pin 没有设置好,power down 指令下达后马上就唤醒wake-up ,使用者会误以为无法power donwiv. Power down 进入Sleep mode 软

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论