陕西理工学院毕业设计
用户目5V电源外围接口在线调试器 PROBE (当I/O口外接5V器件时用) VDD(15) XICE(16) ICECLK(17) ICESDA(18) VSS(19) (1)VDD (2)XIC (3)ICECLK (4)ICESDA (5)VSS 25针计算机标准并行接口 3.3V电源 32678Hz晶振 SPCE061A PC 图3.9 用户目标板、PROBE、计算机三者之间的连接图
图3.10 PROBE方式实物连接图
第 9 页 共 51 页
陕西理工学院毕业设计
4系统软件设计
4.1系统的总体程序流程
在μ'nSP?单片机的汇编程序设计中,用户可以不用考虑程序代码在实际物理存储器中的存储地址,而是通过伪指令(如“.CODE”、“.TEXT”、“.RAM”等)来通知编译器把程序代码定位在什么类型的存储空间即可.至于具体的存储地址则由编译器管理。
μ'nSP?单片机的汇编指令针对C语言进行了优化,所以其汇编的指令格式很多地方直接类似于 C 语言。另外其开发仿真环境 IDE 也直接提供了C语言的开发环境,C函数和汇编函数可以方便地进行相互调用,详细方法在本章节中将详细介绍。显然,在 HLL 平台上要比在汇编级上编程具有诸多优势:代码清晰易读、易维护,易形成模块化,便于重复使用从而增加代码的开发效率。
HLL 中又因 C 语言的可移植性最佳而成为首选。因此,支持C语言几乎是所有微控制器设计的一项基本要求。μ'nSP?指令结构的设计就着重考虑了对C语言的支持。
语音辨别小车的主程序分为四大部分:初始化、训练、识别、重训操作。 初始化:把IOB8~IOB11端口 作为输出端来控制驱动电机。必要时也得有相应的输入端设置和脉冲宽度调制端口设置。
训练:训练部分其实就是建立语音信息模型,以便小车对语音信息进行辨识。
识别:在此过程当中,若识别内容是小车的名字,那么小车会停止并处于待命状态,然后等待接收动作命令。若辨识结果是动作信息指令,小车就会播放语音告知接下来要执行的动作并执行该动作。
重训操作:如果要进行重新训练,按KEY3键进行初始化,然后按照训练部分的步骤进行重新训练。
系统的总体流程如图4.1所示。
图4.1系统总体流程图
第 10 页 共 51 页
陕西理工学院毕业设计
4.2汇编语言程序设计 4.2.1汇编语言的程序结构
程序最基本的结构形式有顺序、循环、分支、子程序四种结构。顺序结构在这里不作讨论,在此章节中将从分支、循环、子程序出发,向读者介绍嵌套递归与中断程序的设计方法。
分支结构可分为双分支结构和多分支结构两种如图 4.2所示。在程序体中,根据不同的条件执行不同的动作,在某一确定的条件下,只能执行多个分支中的一个分支。
图4.2 分支结构的两种形式
汇编语言中没有专用的循环指令,但是可以使用条件转移指令通过条件判断来控制循环是继续还是结束。
在一些实际应用系统中,往往同一组操作要重复许多次,这种强制CPU多次重复执行一串指令的基本程序结构称为循环程序结构。循环程序可以有两种结构形式,一种是WHILE_DO结构形式;另一种是DO_UNTIL结构形式,如图4.3所示。
DO_UNTIL结构 WHILE_DO结构
N 初始化 初始化 循环体 Y Y 循环控制条件 循环控制条件
Y
循环体 N 退出循环 退出循环 图4.3循环结构的两种方式
WHILE_DO结构把对循环控制条件的判断放在循环的入口,先判断条件,满足条件就执行循环体,否则退出循环。DO_UNTIL 结构则先执行循环体然后再判断条件,满足则继续执行循环操作,一旦不满足条件则退出循环。这两种结构可以根据具体情况选择使用。一般来说,如果有循环次数等于0的可能则应选择WHILE_DO结构。不论哪一种结构形式,循环程序一般由三个主要部分组成。 (1)初始化部分:为循环程序做准备,如规定循环次数、给各个变量和地址指针预置初值。
(2)循环体:每次都要执行的程序段,是循环程序的实体,也是循环程序的主体。
第 11 页 共 51 页
陕西理工学院毕业设计
(3)循环控制部分:这部分的作用是修改循环变量和控制变量,并判断循环是否结束,直到符合结束条件时,跳出循环为止。 下面是这两种循环结构的举例。 (1)数据搬运
把内存中地址为0x0000~0x0006中的数据,移到地址为0x0010~0x0016中。
流程图如图4.4所示。
N Y
开始 r2=[C_Move_To_Position] bp=Label r1=7(数据个数) 复制数据 源地址和目的地址各加1 r1=r1-1 r1=0?
Y
结束 图4.4程序流程图
(2)延时程序
向B口送0xffff数据,点亮LED灯,延时1秒后,再向B口送0x0000数据,熄灭LED灯。
延时子程序的流程图如图4.5所示。
第 12 页 共 51 页
陕西理工学院毕业设计
Y
开始 r1=400 r2=936 r2=r2-1 N r2=0? Y r1=r1-1 r2=0? Y 返回 图4.5 时间延时子程序流程图
N 下面分析一下如何进行时间延时,延时时间主要与两个因素有关:其一是循环体(内循环)中指令执行的时间;其二是外循环变量(时间常数)的设置。上例选用系统默认的 FOSC,CPUCLK,CPUCLK=FOSC/8=24M/8=3M(Hz),所以一个CPU周期为1/3M(s)。执行一条r1=400 指令的时间为4个CPU周期,执行一条nop指令的时间为2个CPU周期,执行 r2-=1 指令的时间为 2 个 CPU 周期,执行 jnz Loop2 指令的时间为 2 或 4 个 CPU 周期(当条件满足时为5个CPU周期,条件不满足时3个CPU周期)。所以上例子中的时间延时子程序的时间为 (4+4+6*1248+2+4-2)*200+4-2=1500002个 CPU 周期,约为 0.5 秒,有点不精确。故在进行精确的时间延时,一般不采用这种方法,而是采用中断来延时,因为 SPCE061A单片机有丰富的定时中断源,如:2Hz ,4Hz,128Hz 等。当然在一般的延时程序也可以采用指令延时,它也挺方便的,在上例的延时程序中只要改变 r1 的值就可以很方便地改变延时时间,比如:r1=4,那么它的延时时间为 10ms。 4.2.2子程序的嵌套
子程序嵌套就是指子程序调用子程序。其中嵌套的层数称为嵌套深度。图4.6表示了三重嵌套的过程。子程序嵌套要注意以下几个方面。
(1)寄存器的保护和恢复,以避免各层子程序之间发生因寄存器冲突而出错的情况。 (2)程序中如果使用了堆栈来传递参数,应对堆栈小心操作,避免堆栈使用不当造成子程序不能正确返回的出错情况。
(3)子程序的嵌套层数不是无限的。堆栈是在数据存储区内开辟的空间,而由于SPCE061A单片机的数据存储的空间为2kWORD。
第 13 页 共 51 页