第五章EM78系列单片机程序设计基础文档格式.docx
《第五章EM78系列单片机程序设计基础文档格式.docx》由会员分享,可在线阅读,更多相关《第五章EM78系列单片机程序设计基础文档格式.docx(75页珍藏版)》请在冰豆网上搜索。
例
例:
从PAGE1跳转到PAGE0
;
PAGE0,beginat000h
049add0x11,a
050mova,@0x55
051mov0x05,a;
port5<
--0x55
052bs0x03,5;
selectPAGE1
053jmplab1;
PAGEjump
054
PAGE1,beginat400h
447
448mova,@0x3f
449xor0x12,a
450Lab1bc0x06,3
451mova,0x05
说明:
052:
将R3寄存器的位5设为"
1"
(选择PAGE1)。
053:
Lab1会被编译为"
50"
,程序跳转至PAGE1中"
Lab1"
(450)的位址。
注意:
此例中"
052"
和"
053"
是用来跳PAGE的,假如沒有"
这行指令,则程序将跳转至"
050"
的位址(在PAGE0中),如此將沒有达到預期的目的。
2.不同PAGE子程序呼叫的方法:
如第1项所述,当程序超过1K時,执行"
的设定就必须加以考虑。
下面將以EM78256为例来说明呼叫不同PAGE子程序的方法。
从PAGE0调用PAGE1中的子程序
053callLab2;
054bc0x03,5;
restore
055jbs0x15,2
056
417
418mova,@0x3f
419xor0x12,a
450Lab2bc0x06,3
45fret
說明:
將R3寄存器的位5設为"
Lab2將会被編译为"
,呼叫PAGE1中"
Lab2"
子程序。
054:
將R3寄存器的位5还原为"
0"
。
是用来呼叫PAGE1中"
的子程序,假如果沒有"
這行指令,則程序將呼叫"
的位址(在PAGE0中),而非"
450"
的位址(在PAGE1中),如此將发生錯誤。
5.1.3."
BS"
,"
BC"
等指令对I/OPort的作用:
"
等指令会先有"
读"
再"
写"
的动作,例如"
bc0x06,3"
指令是將整个Port6(8pin)读進CPU,执行位运算后再写至Port6上。
假如Port6有一些pin是双向I/Opin(如P65)時,假設当执行"
時P65是输入pin,則P65pin上的内容会被读入再写至Latch上,覆蓋原先Latch上的内容。
因此只要P65一直是输入pin將不会有問題,一旦P65切換为输出,則Latch上的内容將是不可預知的。
5.1.4.I/OPort读取的路径:
若仔細研究EM78系列八位微控器的I/OPort构造,就可发現在做"
I/OPort的动作時(如"
mova,0x06"
),所读入内容有两个路径来源,一是I/Opin上的内容,另一是输出Latch上的内容,而由I/O控制寄存器決定此读入的路径。
例如I/Opin设计为输入pin時(对应的I/O控制寄存器为"
),对I/OPort做"
的动作時,是读到pin上的内容。
若I/Opin设计为输出pin時(对应的I/O控制寄存器为"
的动作時,是读到输出Latch上的内容。
5.1.5.WDT(WatchdogTimer)的使用:
WDT是微控器內部RC自振的计時器,其超時溢位(Time-out)的基本周期約18ms,WDT有与TCC共用的倍除器,使得超時溢位(Time-out)的最大周期可至約2.2sec。
WDT计時的使能或禁止是可隨時由指令控制的(控制位在IOCE寄存器)。
当WDT使能時,其超時溢位將使微控器发生RESET(或喚醒),"
wdtc"
指令是用来清除WDT,令WDT再从头计時,因此适当的使用"
指令,可使WDT不会发生RESET。
当WDT被禁止時,WDT不会使微控器RESET或喚醒。
要特別注意的是,Power-on之後WDT是使能的,如果該应用中並沒有使用WDT,必須在程序的前头用指令將WDT计時禁止。
EM78156/256/456就是依上述所設计。
在EM78247/447/248/448/056/P156除了上述的設计外,另有一CodeOption決定使能或禁止WDT,其功能如下:
1.假如应用中有使用WDT,WDT必須以CodeOption使能,則在程序中隨時可以用指令使能或禁止WDT计時。
Power-on之後WDT是使能的。
2.假如应用中並沒有使用WDT,WDT可以以CodeOption禁止,則WDT是永遠被禁止的,如此可省去須在程序的前头用指令將WDT计時禁止的麻煩。
5.2.基本设计规则
5.2.1.设定I/O口的模式:
用户可以单独设定任一支I/O脚为输出模式(OutputMode),或是输入模式(InputMode)。
只要將每个I/O的设定写入累加器(A)中,再將累加器的内容写到I/O控制寄存器中,设定就算完成了。
例1:
將PORT6设定为OUTPUTPORT。
;
定义。
设定A=0。
將PORT6设定为输出模式。
PORT6==6
MOVA,@0X00
IOWPORT6,A
设定A=0X0F,高四位为
OUTPUTPORT,低四位为
INPUTPORT。
例2:
將PORT6的低四位设成INPUTPORT;
高四位设定为OUTPUTPORT。
MOVA,@0X0F
5.2.2.检查寄存器的内容:
检查寄存器的内容有很多种方法,可以用AND的功能,或SUB的功能…等。
在做完AND或SUB的功能之后,可以检验状态标志(STATUSFLAG),然后写一个判断式,針对状态标志的結果,处理个別的情形。
判断寄存器0X20內含值是否为0。
设定A=0XFF。
寄存器0X20,和A中的值做and
若是寄存器0x20为0,则寄存
器0X03的bit2位为1。
若是寄存器0X20不为零则产
生循环。
CHECK:
MOVA,@0XFF
ANDA,0X20
JBS0X03,2
JMPCHECK
5.2.3.简易的循环设计
1.FORLOOP的设计:
如果用户想让同一段程序执行N次,用户可以利用一个寄存器为计数器,在程序执行前,先將计数寄存器设为N,然后每执行一次,计数器就減一,再跳为原區段执行,直到计数器被減至零。
例:
设计一个FORLOOP循环,让循环連續执行10次。
MOVA,@0X0A
设A=0X0A。
设定计数值。
计数寄存器
为0X10。
递減计数寄存器,若计数
值为0,则跳出循环。
MOV0X10,A
LOOP:
DJZ0X10
JMPLOOP
2.IF…THEN…程序设计:
IF…THEN…的说法就是,如果…就做…。
用户可以利用检查两个数值是否相等,例如”IFX=YTHENGOTOELSE”的格式,来完成这种功能。
●例:
判断两个寄存器(0X20,0X21)的数值是否相等,如果相等,就將标志寄存器设为1。
將BUFFER1的值存入A中。
將A的值和BUFFER2的值做xor
IFBUFFER1=BUFFER2
THEN
ELSE
设定FLAG为0。
设定FLAG为1。
BUFFER1==0X20
BUFFER2==0X21
FLAG==0X22
MOVA,BUFFER
XORA,BUFFER2
JBC0X03,2
JMPFLAG_1
JMPFLAG_0
FLAG_0:
MOVA,@0
MOVFLAG,A
JMPPROCESS
FLAG_1:
MOVA,@1
PROCESS:
5.2.4.查表程序设计:
在一个沒有規则性的内容转换中,查表程序是相当有用的,用户可以使用查表程序很快速的得到相关内容的转换。
设计一个程序,將如下图所示中的PORT5读到的一个数值,将输入内容做转换,然后输出到PORT6的7段显示器上。
电阻
PORT5
P50
P51
P52
P53
指拨开关
接地
图5.1
上图中开关关闭,I/O引脚可以得到一个低电位,若是开关开启则I/O引脚可以得到一个高电位。
A
图5.2数码管八段说明
F
B
D
E
C
G
H
7段显示器的接线图如上,我們要編一个表做为读入内容以及输出内容的对映。
7段显示器各脚位电位状态
PORT6输出
PORT5输入
H
G
F
E
D
C
B
A
16进位数值
10进位数值
1
0X3F
0X06
0X5B
2
0X4F
3
0X66
4
0X6D
5
0X7D
6
0X07
7
0X7F
8
0X6F
9
0X77
10
0X7C
11
0X58
12
0X5E
13
0X79
14
0X71
15
设定程序起始位址。
设定PORT6为Output口。
设定PORT5为Input口。
跳转到主程序中。
输入及输出对映表。
程序清单如下:
PC==0X02
PORT5==5
ORG0X10
MOVA,@0
IOWPORT6
IOWPORT5
JMPSTART
TABLE:
ADDPC,A
RETL@0X3F
RETL@0X06
RETL@0X5B
RETL@0X4F
RETL@0X66
RETL@0X6D
RETL@0X7D
RETL@0X07
RETL@0X7F
RETL@0X6F
RETL@0X77
RETL@0X7C
RETL@0X58
RETL@0X5E
RETL@0X79
RETL@0X71
START:
MOVA,PORT5
ANDA,@0X0F
CALLTABLE
MOVPORT6,A
JMPSTART
5.2.5.中断程序的设计
在EM78X56系列的IC中有三种中断信号,分別是:
TCC溢位中断。
PORT6Change中断。
外部信号中断。
在说明中断使用方式之前,用户要了解中断寄存器,及与中断息息相关的控制寄存器(ControlRegister),另外在芯片中預除器(Prescalar)的使用方法,用户也需要住意。
中断信号显示寄存器0X0F各位安排如下:
BIT7
BIT6
BIT5
BIT4
BIT3
BIT2
BIT1
BIT0
中断信号
-
外部中断标志
PORT6Change
TCC溢位标志。
寄存器0X0F使用到的有BIT0~BIT2。
BIT0在TCC计時器计数溢位時就会被设定,用户可以根据0X0F的BIT0被设定而判定TCC计数溢位。
跟TCC配合的还有另一个寄存器---控制寄存器(ControlRegister,简称CONT)。
控制寄存器0X0F各位安排如下:
控制信号
INT
TS
TE
PAB
PSR2
PSR1
PSR0
各位的代表意义如下:
□PSR2~PSR0:
TCC/WDT預除器设定。
TCC比例
WDT比例
1:
16
32
64
128
256
FIGURE3.5PS0~PS2的设定值与預除器和TCC及WDT的比例关係。
□Bit3預除器配置:
0:
TCC
WDT
□Bit4TCC递增時机:
外部信号,触发边沿为正沿触发。
外部信号,触发边沿为負沿触发。
□Bit5TCC信号来源:
內部指令周期触发。
外部引脚(第三脚)触发。
□Bit6INT使能标志:
禁止所有中断产生。
使能中断信号。
□Bit7无使用。
三种中断产生都有其先前的设定值,接下来会以示例说明。
写一个程序,將寄存器0X20当做计数器,每当TCC中断产生,就自动加1。
设定A=0。
关闭WatchDog。
设定接下来的程序位址。
清除寄存器0X20。
跳转到TCC_PRO。
关闭各項中断功能。
清除中断寄存器。
计数器加1。
MOVA,@0X0
IOW0X0E
ORG6
CLR0X20
JMPTCC_PRO
INT_PRO:
DISI
CLR0X0F
返回主程序,並使能中断。
设定A=1。
使能TCC溢位中断产生。
设定A=0X40。
將A的值写入控制寄存器。
使能中断。
等待TCC计数器计数溢位。
INC0X20
RETI
TCC_PRO:
CLR0X0F
MOVA,@0X01
IOW0X0F
MOVA,0X40
CONTW
ENI
TCC_WAIT:
NOP
NOP
JMPTCC_WAIT
TCC中断产生有几个设计的重点:
1.关闭看门狗计時器(WatchDogTimer)。
2.设定控制寄存器(包括預除器、TCC信号来源、触发時机…)。
3.使能中断(下ENI指令)。
4.使能TCC中断(设定中断控制寄存器的bit0为1)。
5.中断服务位址为0X08。
6.进入中断服务程序首先要將中断禁止,否则会产生重复中断。
7.中断寄存器0X0F,在进入中断服务程序時可以提供用户判断为何种中断,判断完成之后用户必須自行清除。
8.由中断服务程序返回主程序应使用指令RETI。
写一个程序,將寄存器0X20当做计数器,每当PORT6Change中断产生,就自动加1。
中断禁止。
设定下一个位址为0X06。
清除计数寄存器。
跳转到主程序。
0X08为中断服务程序起始。
清除中断标志寄存器。
计数器遞增。
將PORT6的值存入正反器。
回主程序。
设定A=0XFF。
將PORT6设成输入口。
DISI
JMPPORT6_CH
MOVPORT6,PORT6
PORT6_CH:
设定A=0X02。
使能PORT6Change中
断产生。
清除WatchDogTimer。
等待PORT6Change。
循环。
MOVA,@0X02
WAIT_INT:
WDTC
JMPWAIT_INT
使用PORT6Change中断有下列几个步骤。
1.关闭看门狗计時器(WatchDogTimer),若看门狗计時器未关闭,用户要定時下WDTC的指令。
2.清除中断寄存器。
3.设定PORT6为输出口。
4.將PORT6的值存入触发器中(这很重要)。
5.使能中断(下ENI的指令)。
6.使能PORT6Change中断(设定中断控制寄存器的bit1为1)。
7.中断服务程序的启始位址在0X08。
8.进入中断服务程序首先要將中断禁止,否则会产生嵌套中断。
9.中断寄存器0X0F,在进入中断服务程序時可以提供用户判断为何种中断,判断完成之后用户必須自行清除。
10.由中断服务程序返回主程序应使用指令RETI。
写一个程序,將寄存器0X20当做计数器,每当外部中断产生,就自动加1。
设定启始位址为0X06。
清除计数器。
清除中断标志。
递增计数寄存器。
返回主程序。
A=0X04。
使能外部中断信号产生。
A=0X40。
设定PORT6,BIT0为中断输入脚
等待外部中断输入。
所謂的外部中断就是利用IC外部引脚,針对单片机外部的信号做为信号源来产生中断。
EM78系列的外部中断引脚是第4脚,是和PORT6位0合用,所以再使用前要先设定PORT6,BIT0是要单純用做I/O引脚,或是中断输入引脚。
ORG6
JMPEXT_PRO
INT_EXT:
EXT_PRO:
MOVA,@0X04
MOVA,@0X40
EXT_WAIT:
JMPEX_WAIT
外部中断显然比較容易了解。
所需注意的項目有:
1.禁止中断。
2.设定中断服务程序的地址在0X08。
3.清除中断标志寄存器。
4.使能外部中断信号产生(设定中断控制寄存器为0X04)。
5.將PORT6,BIT0设定成外部中断引脚(设定控制寄存器0X0E,BIT6为1)。
6.使能中断信号(ENI)。
7.用户在进入中断服务程序(0X08)時,首先要記得禁止中断(DISI)。
8.可以由中断标志寄存器判断中段的信号为何产生,判断完之后应自行清除中断标志。
9.返回主程序時用指令RETI。
以上三支中断程序的写法都是利用无穷循环,所以用户想要看到結果只有結束程序,然后查看计数寄存器(0X20)的计数状況。
5.2.6.延迟子程序的编写:
在許多程序设计的場合,我們時常会利用到时间延迟子程序,接下来就介紹一个可以控制延迟时间的延迟子程序。
开下面是利用发工具E8-ICE来演示的一个精确的控制延迟时间的程序,选择使用石英振荡器,可以精确的算准延迟时间,时间可以到nanosecond(十亿分之一秒),很神奇。
A=2。