dsp应用实例
第12章 应用实例 12.1 TMS320LF2407与图形液晶显示模块接口及应用 ;对系统和LCD显示程序中用到的寄存器定义:
LCD_FLAG .usect ".data0",1 ;LDP=5
LCD_FLAG1 .usect ".data0",1 ;LCD的两个标志寄存器 LCDCMD .usect ".data0",1 ;LCD 列地址寄存器 LCDZKTAB .usect ".data0",1 ;查
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
地址临时寄存器 LCDDATA .usect ".data0",1 ;LCD 显示的数据 DP_USER .set 5H
DP_USER1 .set 12H
DP_PF2 .set 0E1H
PADATDIR .set 7098H
PBDATDIR .set 709AH
MCRA .set 7090H
;LCD 宏定义:
E1_H .set 00080H ;E1=IOPA7=1, 选中E1块,即LCD模块左边 E1_L .set 0FF7FH ;E1=0
E2_H .set 00040H ;E2=IOPA6=1, 选中E2块,即LCD模块右边 E2_L .set 0FFBFH ;E2=0
RW_H .set 00020H ;R/W=IOPA5=1, 读LCD显示的内容 RW_L .set 0FFDFH ;R/W=0, 写LCD显示的内容 A0_H .set 00010H ;A0=IOPA4=1, 选择数据操作 A0_L .set 0FFEFH ;A0=0, 选择指令操作
;主程序:显示一屏,主要用于测试LCD底层程序
.text
_c_int0
CALL SYSINIT
CALL LCDINIT
LAR AR1,#SHIJIAN ;送显示时间
MAR *,AR1
LACL #01H
SACL *+
LACL #1115H
SACL *+
LACL #22H
259
SACL *+
LACL #4155H
SACL *
CALL LCDP0 ;显示一屏信息 WAIT: NOP
NOP
B WAIT
;系统初始化程序
SYSINIT:SETC INTM
CLRC SXM
CLRC OVM
CLRC CNF ;B0 被配置为数据存储空间
LDP #0E0H
SPLK #81FEH,SCSR1 ;CLKIN=6 M,CLKOUT=24 M
SPLK #0E8H,WDCR ;Disable WDT
LDP #0
SPLK #0000H,IMR ;不使能中断
SPLK #0FFFFH,IFR ;清全部中断标志
RET
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;LCD初始化及底层程序
; 描述:LCD初始化程序
; 被修改的寄存器:ACC, LCDCMD
; 调用到的子程序:COMWE, CLEAR
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LCDINIT:LDP #DP_PF2 ;DP ? 7080h,70FFh
LACL MCRA
AND #000FH ;配置IOPA[4,7],IOPB[0,7] 为一般I/O口功能
SACL MCRA
LACL PADATDIR
OR #0F000H ;IOPA4,IOPA7 为输出方式
AND #0FF0FH ;IOPA[4,7]=0
SACL PADATDIR
LDP #DP_USER
SPLK #0AEH,LCDCMD ;关显示 10101110B
CALL COMWE
SPLK #00E2H,LCDCMD ;复位 11100010B
CALL COMWE
260
SPLK #0A4H,LCDCMD ;正常显示驱动 10100101B
CALL COMWE
SPLK #0A9H,LCDCMD ;占空比为1/32,10101001B
CALL COMWE
SPLK #0A0H,LCDCMD ;ADC选择,正常输出 10100000B
CALL COMWE
SPLK #0C0H,LCDCMD ;显示起始行
CALL COMWE
CALL CLEAR ;清屏
SPLK #0AFH,LCDCMD ;开显示 10101111B
CALL COMWE
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:对E1和E2写控制命令子程序,此程序只用在LCD初始化程序中
; 被修改的寄存器:ACC, LCD_FLAG
; 调用到的子程序:CWE
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
COMWE: LACL LCD_FLAG
AND #0FFFEH ;LCD_FLAG.0=0选中E1
SACL LCD_FLAG
CALL CWE
LACL LCD_FLAG
OR #0001H ;LCD_FLAG.0=1选中E2
SACL LCD_FLAG
CALL CWE
LDP #DP_USER
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:写控制命令子程序,向LCD写一个控制字
; 人口:LCD_FLAG, LCDCMD
; 被修改的寄存器:ACC
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CWE: LDP #DP_USER
BIT LCD_FLAG,15 ;判是E1还是E2? LCD_FLAG.0=0,则选中E1
BCND CWE1,TC ;TC=1 则选中E2
LDP #DP_PF2
LACL PADATDIR
AND #E2_L ;E2=0
261
AND # RW_L ;R/W=0
OR #E1_H ;E1=1
SACL PADATDIR
B CWE2
CWE1: LDP #DP_PF2 ;LCD_FLAG=01,则选中E2
LACL PADATDIR
AND #E1_L ;E1=0
AND #RW_L ;R/W=0
OR #E2_H ;E2=1
SACL PADATDIR
CWE2: LACL PADATDIR
AND #A0_L ;A0=0
SACL PADATDIR
LACL PBDATDIR
OR #0FF00H ;IOPB[0,7]设置为输出
AND #0FF00H ;IOPB[0,7]=0
LDP #DP_USER
OR LCDCMD ;IOPB[0,7]=LCDCMD
LDP #DP_PF2
SACL PBDATDIR ;送列地址
LACL PADATDIR
AND #E1_L ;E1=0
AND #E2_L ;E2=0
SACL PADATDIR
LDP #DP_USER
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:写数据子程序,向LCD写一个数据
; 人口:LCD_FLAG, LCDCMD,LCDDATA
; 被修改的寄存器:ACC, AR7
; 调用到的子程序:CWE
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DWE: LDP #DP_USER
SAR AR7,LCDCMD ;AR7存放列地址
CALL CWE
BIT LCD_FLAG,15 ;判是 E1 或E2模块?
LDP #DP_PF2
BCND DWE1,TC ;LCD_FLAG=0001h, 则为E2模块
262
LACL PADATDIR
AND E2_L ;E2=0
AND #RW_L ;R/W=0
OR #E1_H ;E1=1
SACL PADATDIR
B DWE2
DWE1: LACL PADATDIR
AND #E1_L ;E1=0
AND #RW_L ;R/W=0
OR #E2_H ;E2=1
SACL PADATDIR
DWE2: LACL PADATDIR
OR #A0_H ;A0=1
SACL PADATDIR
LACL PBDATDIR
OR #0FF00H ;IOPB[0,7]设置为输出
AND #0FF00H ;IOPB[0,7]=0
LDP #DP_USER
OR LCDDATA ;IOPB[0,7]=LCDDATA
LDP #DP_PF2
SACL PBDATDIR ;送显示的数据
LACL PADATDIR
AND #E1_L ;E1=0
AND #E2_L ;E2=0
SACL PADATDIR
MAR *,AR7
ADRK #1 ;向列地址增1,以便向下一列写数
LDP #DP_USER
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:清屏子程序,LCD清屏
; 被修改的寄存器:ACC, AR0, AR6, AR7, LCD_FLAG, LCDCMD, LCDDATA ; 调用到的子程序:CWE, DWE
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CLEAR:LDP #DP_USER
LAR AR6,#0B8H ;设置页地址代码指令 10111000B
;AR6存放的是页地址
SPLK #00H,LCDDATA ;将00写入
263
CLR1: SAR AR6,LCDCMD
LACL LCD_FLAG
AND #0FFFEH ;LCD_FLAG.0=0
SACL LCD_FLAG
CALL CWE ;设置页号
LACL LCD_FLAG
OR #0001H ;LCD_FLAG.0=1
SACL LCD_FLAG
CALL CWE
LAR AR7,#00H ;从00列开始清0, AR7存放的是列地址
LAR AR0,#80 ;比较值( 可以61列) CLR2: LACL LCD_FLAG
AND #0FFEH ;LCD_FLAG.0=0
SACL LCD_FLAG
CALL DWE ;向E1写入00
MAR *,AR7 ;AR7兼作循环计数器
CMPR 01 ;(AR7
60?
BCND HZ0,TC
AND #0FFFEH ;在E1 块显示
B HZ00
HZ0: OR #0001H ;在E2 块显示
SBRK #59 ;(AR7)—60 HZ00: SACL LCD_FLAG ;根据AR7的值设置LCD_FLAG.0
LACL LCD_FLAG
AND 0FF00H
RPT #7
SFR
SUB #1
LDP #DP_USER
SACL LCDZKTAB ;得字号
LT LCDZKTAB
MPY #10H
SPM #0H ;P寄存器无输出移位
PAC ;ACC=PREG
ADD #LCDHZK
SACL LCDZKTAB
LAR AR0,#0H
MAR *,AR6
CMPR #2H ;AR6>AR0 则显示在B8位置
BCND HZPSET0,TC
LAR AR6,#0BAH
B HZPSET1
HZPSET0:LAR AR6,#0B8H
HZPSET1:SAR AR6,LCDCMD ;设置页号
CALL CWE
MAR *,AR6
ADRK #1 ;页号加1,以准备显示汉字的下半部分
265
LAR AR0,#9
LAR AR5,#1 ;计数器 HZ1: LACC LCDZKTAB
TBLR LCDDATA ;表读
LACC #00FFH
AND LCDDATA
SACL LCDDATA
CALL DWE
LACC LCDZKTAB
TBLR LCDDATA
ADD #1
SACL LCDZKTAB
LACC #0FF00H
AND LCDDATA
RPT #7
SFR
SACL LCDDATA
CALL DWE
MAR *,AR5
ADRK #1 ;计数器加1
CMPR 01 ;比较,是否该汉字在本页显示完成
BCND HZ1,TC
SAR AR6,LCDCMD
CALL CWE ;设置汉字下半部分显示的页
MAR *,AR7
SBRK #16
LAR AR0,#17 ;新比较值
MAR *,AR5
CMPR 01 ;比较,是否该汉字显示完成
BCND HZ1,TC
LDP #DP_USER
MAR *,AR7 ;准备下一个汉字显示
BIT LCD_FLAG,15
BCND HZ2,NTC
ADRK #59 ;E2 块 (AR7)+60
HZ2: ADRK #16
LAR AR0,#0BBH
MAR *,AR6
266
CMPR 00
BCND HZ3,NTC
LAR AR6,#0
B HZRET
HZ3: LAR AR6,#1
HZRET: SPLK #00,LCD_FLAG
LDP #DP_USER
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;描述: 数字、字母显示子程序,LCD显示数字或字母程序 ;人口: LCD_FLAG, AR6——页号,AR7——列地址
; LCD_FLAG的高8位——字号,LCD_FLAG的低8位为标志位 ; LCD_FLAG.0=0选中E1,LCD_FLAG.0=1选中E2 ; 被修改的寄存器:ACC, AR0, AR5, AR6, AR7, LCD_FLAG, LCDCMD, LCDDATA, LCDZKTAB
;调用到的子程序:CWE, DWE
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LCDSZ: LDP #DP_USER
LACL LCD_FLAG
MAR *,AR7
LAR AR0,#59
CMPR 2 ;(AR7)>60?
AND #0FFFEH ;E1 块
BCND SZ0,TC
B SZ00
SZ0: OR #0001H ;E2 块
SBRK #59 ;(AR7)—60 SZ00: SACL LCD_FLAG ;根据AR7的值设置LCD_FLAG.0
LACL LCD_FLAG
AND #0FF00H
RPT #7
SFR
LDP #DP_USER
SACL LCDZKTAB
LT LCDZKTAB
MPY #08H
SPM #0H
PAC
ADD #LCDSZK
267
SACL LCDZKTAB
LAR AR0,#0
MAR *,AR6
CMPR #2H
BCND SZPSET0,TC
LAR AR6,#0BAH
B SZPSET1 SZPSET0:LAR AR6,#0B8H
SZPSET1:SAR AR6,LCDCMD ;设置页号
CALL CWE
MAR *,AR6
ADRK #1 ;页号加1,以准备显示字符的下半部分
LAR AR0,#5
LAR AR5,#1 ;计数器 SZ1: LACC LCDZKTAB
TBLR LCDDATA ;表读
LACC #00FFH
AND LCDDATA
SACL LCDDATA
CALL DWE
LACC LCDZKTAB
TBLR LCDDATA
ADD #1
SACL LCDZKTAB
LACC #0FF00H
AND LCDDATA
RPT #7
SFR
SACL LCDDATA
CALL DWE
MAR *,AR5
ADRK #1 ;计数器加1
CMPR 01 ;比较,是否该数字在本页显示完成
BCND SZ1,TC
SAR AR6,LCDCMD
CALL CWE
MAR *,AR7
SBRK #8
268
LAR AR0,#9 ;新比较值
MAR *,AR5
CMPR 01 ;比较,是否该数字显示完成
BCND SZ1,TC
LDP #DP_USER
MAR *,AR7 ;准备下一个字符显示
BIT LCD_FLAG,15
BCND SZ2,NTC
ADRK #59 ;E2 块 (AR7)+60 SZ2: ADRK #0AH
LAR AR0,#0BBH
MAR *,AR6
CMPR 00
BCND SZ3,NTC
LAR AR6,#0
B SZRET
SZ3: LAR AR6,#1
SZRET: SPLK #00,LCD_FLAG
LDP #DP_USER
RET
;显示主屏程序
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:液晶显示液晶主屏程序,显示日期 XX年XX月XX日,显示时间 XX:XX:XX ; 人口:为要显示内容寄存器
; 被修改的寄存器:ACC, AR1, AR6, AR7, LCD_FLAG ; 调用到的子程序:CLEAR, LCDSZ, LCDHZ
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LCDP0: CALL CLEAR
LAR AR6,#0 ;页地址为00BAh
LAR AR7,#2H ;列地址为0002h
LAR AR1,#SHIJIAN ;(年, 月 日, 时,分 秒)
MAR *,AR1
LACL *
AND #0F0H ;取“年”的十位数字
RPT #3
SFL ;左移4位得到字号
OR LCD_FLAG
SACL LCD_FLAG
269
CALL LCDSZ ;显示“年”的十位数字
LAR AR7,#0CH
MAR *,AR1
LACL *+
AND #0FH ;取“年”的个位数字
RPT #7
SFL ;左移8位得到字号
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“年”的个位数字
LAR AR7,#18H
SPLK #01FFH,LCD_FLAG ;显示“年”这个字
CALL LCDHZ
LAR AR7,#2AH
MAR *,AR1
LACL *
AND #0F000H ;取“月”的十位数字
RPT #3
SFR
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“月“的十位数字
LAR AR7,#34H
MAR *,AR1
LACL *
AND #0F00H ;取“月”的个位数字
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“月”的个位数字
LAR AR7,#3EH
SPLK #02FFH,LCD_FLAG ;显示“月”这个字
CALL LCDHZ
LAR AR7,#50H
MAR *,AR1
LACL *
AND #0F0H ;取“日”的十位数字
RPT #3
SFL
270
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“日”的十位数字
LAR AR7,#5AH
MAR *,AR1
LACL *+
AND #0FH ;取“日”的个位数字
RPT #7
SFL
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“日”的个位数字
LAR AR7,#64H
SPLK #03FFH,LCD_FLAG ;显示“日”这个字
CALL LCDHZ
LAR AR6,#1 ;页地址为00B8h
LAR AR7,#10H
MAR *,AR1
LACL *
AND #0F0H ;取“小时”的十位数字
RPT #3
SFL
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“小时”的十位数字
LAR AR7,#1CH
MAR *,AR1
LACL *+
AND #0FH ;取“小时”的个位数字
RPT #7
SFL
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“小时”的个位数字
LAR AR7,#28H
SPLK #0AFFH,LCD_FLAG ;显示 " :"
CALL LCDSZ
LAR AR7,#34H
271
MAR *,AR1
LACL *
AND #0F000H ;取“分”的十位数字
RPT #3
SFR
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“分”的十位数字
LAR AR7,#40H
MAR *,AR1
LACL *
AND #0F00H ;取“分”的个位数字
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“分”的个位数字
LAR AR7,#4CH
SPLK #0AFFH,LCD_FLAG ;显示 " :"
CALL LCDSZ
LAR AR7,#58H
MAR *,AR1
LACL *
AND #0F0H ;取“秒”的十位数字
RPT #3
SFL
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“秒”的十位数字
LAR AR7,#64H
MAR *,AR1
LACL *
AND #0FH ;取“秒”的个位数字
RPT #7
SFL
OR LCD_FLAG
SACL LCD_FLAG
CALL LCDSZ ;显示“秒”的个位数字
LDP #DP_USER
RET
272
;字库列表,汉字库,16*16点阵
LCDHZK .word 02000H ;年 (1),其中(1)表示是汉字库中第1个汉字
.word 0cc10H
.word 4447H
.word 0fc44H
.word 4444H
.word 6444H
.word 0446H
.word 0000H
.word 0404H
.word 0704H
.word 0404H
.word 0ff04H
.word 0404H
.word 0404H
.word 0604H
.word 0004H
.word 0000H ;月 (2)
.word 0000H
.word 22feH
.word 2222H
.word 2222H
.word 0ff22H
.word 0002H
.word 0000H
.word 0080H
.word 3040H
.word 020fH
.word 0202H
.word 4202H
.word 7f82H
.word 0000H
.word 0000H
.word 0000H ;日 (3)
.word 0fe00H
.word 8282H
.word 8282H
.word 8282H
273
.word 0ff82H
.word 0002H
.word 0000H
.word 0000H
.word 07f00H
.word 2020H
.word 2020H
.word 2020H
.word 7f20H
.word 0000H
.word 0000H LCDSZK ;数字、字母8×16点阵表
.word 0f8f0H ;"0" 字母的编号为0
.word 0c40cH
.word 0f80cH
.word 00f0H
.word 0703H
.word 080cH
.word 070cH
.word 0003H
.word 1000H ;"1" 字母的编号为1
.word 0fc18H
.word 00fcH
.word 0000H
.word 0800H
.word 0f08H
.word 080fH
.word 0008H
.word 0c08H ;"2" 字母的编号为2
.word 0c484H
.word 3c64H
.word 0018H
.word 0f0eH
.word 0809H
.word 0c08H
.word 000cH
.word 0c08H ;"3" 字母的编号为3
.word 4444H
274
.word 0fc44H
.word 00b8H
.word 0c04H
.word 0808H
.word 0f08H
.word 0007H
.word 0e0c0H ;"4" 字母的编号为4
.word 98b0H
.word 0fcfcH
.word 0080H
.word 0000H
.word 0800H
.word 0f0fH
.word 0008H
.word 7c7cH ;"5" 字母的编号为5
.word 4444H
.word 0c444H
.word 0084H
.word 0c04H
.word 0808H
.word 0f08H
.word 0007H
.word 0f8f0H ;"6" 字母的编号为6
.word 444cH
.word 0c044H
.word 0080H
.word 0f07H
.word 0808H
.word 0f08H
.word 0007H
.word 0c0cH ;"7" 字母的编号为7
.word 8404H
.word 7cc4H
.word 003cH
.word 0000H
.word 0f0fH
.word 0000H
.word 0000H
275
.word 0fcb8H ;"8" 字母的编号为8
.word 4444H
.word 0fc44H
.word 00b8H
.word 0f07H
.word 0808H
.word 0f08H
.word 0007H
.word 7c38H ;"9" 字母的编号为9
.word 4444H
.word 0fc44H
.word 00f8H
.word 0800H
.word 0808H
.word 070cH
.word 0003H
.word 0000H ;":"(A)
.word 3000H
.word 0030H
.word 0000H
.word 0000H
.word 0600H
.word 0006H
.word 0000H
276
212.2 IC串行日历时钟与TMS320LF2407的接口及应用
2TMP_DATA .usect ".data0",1 ;IC临时数据寄存器
BYTE_ADDR .usect ".data0",1 ;存放字节地址
T_DATA .usect ".data0",1 ;发送数据缓冲器
R_DATA .usect ".data0",1 ;接收数据缓冲器
DP_USER equ 5 ;DP指向0280h,0300h
2;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IC 宏定义~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2DEVSELWR equ 0A0H ;IC器件写操作命令
2DEVSELRD equ 0A1H ;IC器件读操作命令
DATAH equ 00020H ;数据线SDA=1 (IOPC5) DATAL equ 0FFDFH ;SDA=0
CLOCKH equ 00008H ;时钟线SCL=1 (IOPC3) CLOCKL equ 0FFF7H ;SCL=0
DATACLOCKH equ 00028H ;SDA=SCL=1 DATACLOCKL equ 0FFD7H ;SDA=SCL=0 DATAINPUT equ 0DFFFH ;PCDATDIR.13=0,即IOPC5引脚作为输入 DATAOUTPUT equ 02000H ;PCDATDIR.13=1,即IOPC5引脚作为输出
.include "F2407REGS.H"
.def _c_int0
;(1)主程序
.text
_c_int0
CALL SYSINIT ;系统初始化子程序
LDP #225
LACL MCRB
AND #0FFD7H
SACL MCRB ;配置IOPC3和IOPC5为一般的I/O口方式
LACL PCDATDIR
OR #02828H ;IOPC3和IOPC5为输出方式
SACL PCDATDIR ;SCL=SDA=1
LDP #DP_USER
LACL #00H,BYTE_ADDR
LACL #00H, T_DATA
CALL BYTE_WR ;设置PCF 8583的控制状态寄存器
LDP #DP_USER
LACL #03H,BYTE_ADDR
277
CALL BYTE_RD ;读取分单元的值 WAIT: NOP
B WAIT
;(2)字节读写程序
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2C器件写1个字节的数据 ; 描述:字节写子程序,即向I
; 人口:BYTE_ADDR, T_DATA
; 调用到的子程序:START,TRANSMIT,SLAVE_ACK,STOP ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2BYTE_WR: CALL START ;启动IC
LDP #DP_USER
LACL #DEVSELWR ;送写控制字
CALL TRANSMIT
CALL SLAVE_ACK
LDP #DP_USER
LACL BYTE_ADDR ;送地址
CALL TRANSMIT
CALL SLAVE_ACK
LDP #DP_USER
LACL T_DATA ;要保存的数据
CALL TRANSMIT
CALL SLAVE_ACK
CALL STOP
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2; 描述:字节读子程序,即从IC器件读出1个字节的数据 ; 人口:BYTE_ADDR
; 出口:R_DATA
; 调用到的子程序:START,TRANSMIT,RECEIVE ,SLAVE_ACK,NO_ACK ,STOP
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BYTE_RD:CALL START
LDP #DP_USER
LACL #DEVSELWR
CALL TRANSMIT
CALL SLAVE_ACK
LDP #DP_USER
LACL BYTE_ADDR
CALL TRANSMIT
278
CALL SLAVE_ACK
CALL START
LDP #DP_USER
LACL #DEVSELRD ;送读控制字
CALL TRANSMIT
CALL SLAVE_ACK
CALL RECEIVE
LDP #DP_USER
SACL R_DATA
CALL NO_ACK
CALL STOP
RET
2C时序子程序 ;(3)以下是模拟I
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:发送字节子程序
; 人口:ACC
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TRANSMIT: LDP #DP_USER
SACL TMP_DATA
LAR AR0,#08H
MAR *,AR3
LAR AR3,#0H
LDP #225
LACL PCDATDIR
AND #CLOCKL ;SCL=0
SACL PCDATDIR
CALL IIC_DLY
T_NEXT: LDP #DP_USER
BIT TMP_DATA,8
BCND T_NEXT1,TC
LDP #225
LACL PCDATDIR
AND #DATAL ;SDA=0
SACL PCDATDIR
B T_NEXT2
T_NEXT1:LDP #225
LACL PCDATDIR
OR #DATAH ;SDA=1
279
SACL PCDATDIR
T_NEXT2:CALL IIC_DLY
LACL PCDATDIR
OR #CLOCKH ;SCL=1
SACL PCDATDIR
CALL IIC_DLY
LACL PCDATDIR
AND #CLOCKL ;SCL=0
SACL PCDATDIR
LDP #DP_USER
LACL TMP_DATA
SFL
SACL TMP_DATA
ADRK #1
CMPR 00
BCND T_NEXT, NTC
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:接收一个字节子程序
; 出口:ACC
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RECEIVE:LDP #DP_USER
SPLK #00H ,TMP_DATA
MAR *,AR0
LAR AR0,#08H
MAR *,AR3
LAR AR3,#0H
LDP #225
LACL PCDATDIR
AND #DATAINPUT ;SDA 设为输入
SACL PCDATDIR
CALL IIC_DLY
R_NEXT: LACL PCDATDIR
OR #CLOCKH ;SCL=1
SACL PCDATDIR
CALL IIC_DLY
LACL PCDATDIR
AND #DATAH ;从SDA引脚读数据
280
RPT #4 ;因为SDA=IOPC5,则应右移5位到ACC.0
SFR ;再把接收到的位加到TMP_DATA寄存器中
LDP #DP_USER
ADD TMP_DATA,1 ;(ACC,TMP_DATA)后再左移1位,空出ACC.0
;供下一次使用
SACL TMP_DATA
CALL IIC_DLY
LDP #225
LACL PCDATDIR
AND #CLOCKL ;SCL=0
SACL PCDATDIR
ADRK #1
CMPR 00
BCND R_NEXT, NTC
LDP #225
LACL PCDATDIR
OR #DATAOUTPUT
SACL PCDATDIR
LDP #DP_USER
LACL TMP_DATA
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2; 描述:IC 启动子程序
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
START: LDP #225
LACL PCDATDIR
OR #DATACLOCKH ;SDA=SCL=1
SACL PCDATDIR
RPT #3BH
NOP ;Delay 4.7US
LACL PCDATDIR
AND #DATAL
SACL PCDATDIR ;SDA=0
RPT #32H
NOP ;Delay 4.0US
LACL PCDATDIR
AND #CLOCKL
SACL PCDATDIR ;SCL=0
281
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2C 停止子程序 ; 描述:I
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IIC_STOP:LDP #225
LACL PCDATDIR
OR #CLOCKH ;SCL=1
SACL PCDATDIR
RPT #3BH
NOP ;Delay 4.7US
LACL PCDATDIR
OR #DATAH ;SDA=1
SACL PCDATDIR
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 描述:从机应答信号
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SLAVE_ACK: LDP #225
LACL PCDATDIR
OR #DATAH
SACL PCDATDIR
RPT #32H
NOP
LACL PCDATDIR
OR #CLOCKH
SACL PCDATDIR
RPT #32H
NOP
LACL PCDATDIR
AND #DATAINPUT ;SDA INPUT
SACL PCDATDIR
RPT #32H
NOP
LACL PCDATDIR
AND #0008H
SUB #08H
BCND ERROR_ACK,EQ
LACL PCDATDIR
282
OR #DATAOUTPUT
AND #DATACLOCKL
SACL PCDATDIR
ERROR_ACK:
--------- ;添加错误处理程序
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 描述:主机应答信号
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MASTER_ACK:LDP #225
LACL PCDATDIR
AND #DATAL
SACL PCDATDIR
CALL NO_ACK
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 描述:主机无应答信号
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NO_ACK:LDP #225
LACL PCDATDIR
OR #CLOCKH
SACL PCDATDIR
RPT #32H
NOP
LACL PCDATDIR
AND #CLOCKL
SACL PCDATDIR
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 描述:为配合时序,延时10 μs子程序
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IIC_DLY: RPT #7DH
NOP
RET
END
283
12.3 用TMS320LF2407实现三相SPWM波形发生器
FCL .usect ".data0",1 ;保存载波频率浮点数的低位
FCH .usect ".data0",1 ;保存载波频率浮点数的高位
FRL .usect ".data0",1 ;保存信号频率浮点数的低位
FRH .usect ".data0",1 ;保存信号频率浮点数的高位
AL .usect ".data0",1 ;保存调谐度浮点数低位
AH .usect ".data0",1 ;保存调谐度浮点数高位
N .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数 NL .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数浮点数低位 NH .usect ".data0",1 ;保存一个周期要输出的PWM脉冲个数浮点数低位 I .usect ".data0",1 ;保存当前输出的是第几个脉冲
T3PR_TEMPL .usect ".data0",1 ;保存定时器3周期寄存器值的浮点数低位 T3PR_TEMPH .usect ".data0",1 ;保存定时器3周期寄存器值的浮点数高位 DATIOL .usect ".data0",1 ;保存占空比浮点数低位
DATIOH .usect ".data0",1 ;保存占空比浮点数低位
DFLAG .usect ".data0",1 ;送出一个脉冲的标志寄存器
.include "F2407REGS.H" ;引用头部文件
.ref F$$ITOF,F$$DIV,F$$MUL,F$$FTOI,F$$ADD,F$$LTOF,F$$SUB
.ref _sin
.def _c_int0
;(1)建立中断向量表
.sect ".vectors" ;定义主向量段
RSVECT B _c_int0 ;PM 0 Reset Vector 1 INT1 B PHANTOM ;PM 2 Int level 1 4 INT2 B GISR2 ;PM 4 Int level 2 5 INT3 B PHANTOM ;PM 6 Int level 3 6 INT4 B PHANTOM ;PM 8 Int level 4 7 INT5 B PHANTOM ;PM A Int level 5 8 INT6 B PHANTOM ;PM C Int level 6 9 RESERVED B PHANTOM ;PM E (Analysis Int) 10 SW_INT8 B PHANTOM ;PM 10 User S/W int —
?
?
SW_INT31 B PHANTOM ;PM 3E User S/W int —
;中断子向量入口定义pvecs
.sect ".pvecs" ;定义子向量段
284
PVECTORS B PHANTOM ;Reserved pvector addr offset-0000h
B PHANTOM ;Reserved pvector addr offset-0001h
?
?
B PHANTOM ;Reserved pvector addr offset-002Eh
B T3GP_ISR ;Reserved pvector addr offset-002Fh T3PINT中断
B PHANTOM ;Reserved pvector addr offset-0030h
?
?
B PHANTOM ;Reserved pvector addr offset-0041h
;(2)主程序
.text
_c_int0:
CALL SYSINIT ;调系统初始化子程序
CALL PWM_INIT ;调PWM初始化子程序
LDP #5
SPLK #2710H,FCL ;载波频率
SPLK #0,FCH
SPLK #032H,FRL ;信号频率
SPLK #0,FRH
SPLK #3E8H,AL ;调谐度AL=A*1000
SPLK #0,AH
SPLK #0,I ;I=0
SPLK #1,DFLAG
CALL JISUAN
LOOP: LDP #5
BIT DFLAG,BIT0
BCND LOOP,NTC
LACL DFLAG
AND #0FFFEH
SACL DFLAG
CALL DATIO
B LOOP
;(3)系统初始化程序
SYSINIT: SETC INTM
CLRC CNF
LDP #0
SPLK #02h,IMR ;使能第1级中断2
285
SPLK #0FFFFh,IFR ;清第1级所有中断标志位
LDP #DP_PF1
SPLK #0E8h,WDCR ;禁止 WDT
LDP #00E0H
SPLK #81FEH,SCSR1 ;CLKIN=6M,CLKOUT=24 M
RET
;(4)EVB模块的PWM初始化程序
PWM_INIT:LDP #DP_PF2
LACL MCRA
OR #07EH ;IOPE1,IOPE6
SACL MCRC ;配置为特殊功能
LACL MCRC
OR #600h
SACL MCRC
LDP #DP_EVB
SPLK #0FFFFh,EVBIFRA ;清EVA的所有中断标志位
SPLK #0555h,ACTRB ;PWM6,4,2 为低,PWM5,3,1 为高
SPLK #00h,DBTCONB ;禁止死区控制
SPLK #1fh,CMPR4 ;给比较寄存器赋初值
SPLK #2Fh,CMPR5
SPLK #3fh,CMPR6
SPLK #0960h,T3PR ;给周期寄存器赋初值
LDP #5
SPLK #0960h,T3PR_TEMPL
SPLK #0,T3PR_TEMPH
LDP #DP_EVB
SPLK #0A600h,COMCONB ;禁止比较功能
SPLK 0,T3CNT
SPLK #41h,GPTCONB
SPLK #080h,EVBIMRA
SPLK #0000101101001110b,T3CON
CLRC INTM
RET
;(5)将一些整数转换为浮点数子程序,得到计算占空比要用的常数 JISUAN:LDP #5 ;调谐度由整形转换为浮点
LACL AL
LRLK AR1,STACK ;设置 STACK指针
SETC SXM
286
CALL F$$ITOF,AR1 ;A=a×1000
CLRC SXM
MAR *-
LACC *-,16
ADDS *
SACL AL
SACH AH
LRLK AR1,STACK ;A/2000=0.5 a
SETC SXM
LACL #0
SACL *+
LACL #44FAH ;44FA 0000h =2000
SACL *+
LACL AL
SACL *+
LACL AH
SACL *+
CALL F$$DIV
MAR *-
LACC *-,16
ADDS *
SACL AL
SACH AH
LACL T3PR_TEMPL
LRLK AR1,STACK
SETC SXM ;定时器周期寄存器
;的值转换为浮点数
CALL F$$ITOF,AR1
CLRC SXM
MAR *-
LACC *-,16
ADDS *
SACL T3PR_TEMPL
SACH T3PR_TEMPH
LACL FCL ;FC值转换为浮点数
LRLK AR1,STACK
SETC SXM
CALL F$$LTOF,AR1
287
CLRC SXM
MAR *-
LACC *-,16
ADDS *
SACL FCL
SACH FCH
LACL FRL
LRLK AR1,STACK
SETC SXM ;FR值转换为浮点数
CALL F$$ITOF,AR1
CLRC SXM
MAR *-
LACC *-,16
ADDS *
SACL FRL
SACH FRH
LRLK AR1,STACK ;N=FC/FR
LACL FRL
SACL *+
LACL FRH
SACL *+
LACL FCL
SACL *+
LACL FCH
SACL *+
CALL F$$DIV
MAR *-
LACC *-,16
ADDS *
SACL NL
SACH NH ;N的浮点数
LRLK AR1,STACK
SETC SXM
SACL *+
SACH *+
CALL F$$FTOI
SACL N ;N的整数
LRLK AR1,STACK
288
SACL *+
LACL NH
SACL *+
LACL #0F5C3H ;40C8F5C3h=6.282=2×3.141
SACL *+
LACL #40C8H
SACL *+
CALL F$$DIV
MAR *-
LACC *-,16
ADDS *
SACL NL
SACH NH
RET
;(6)计算占空比子程序
DATIO: LDP #5
LACL I ;I由整形转换为浮点数
LRLK AR1,STACK
SETC SXM
CALL F$$ITOF,AR1
CLRC SXM
MAR *-
LACC *-,16
ADDS * ;结果保存在 ACC
LRLK AR1,STACK ;i*2*3.14/N
SACL *+
SACH *+
LACL NL
SACL *+
LACL NH
SACL *+
CALL F$$MUL
MAR *-
ZALH *-
ADDS *
LRLK AR1,STACK ;sin(i*2*3.14/N)
SACL *+
SACH *+
289
CALL _sin ;结果在 ACC
LRLK AR1,STACK ;0.5a*sin(i*2*3.14/N)
SACL *+
SACH *+
LACL AL
SACL *+
LACL AH
SACL *+
CALL F$$MUL
MAR *-
ZALH *-
ADDS * ;结果在 ACC
LRLK AR1,STACK ;D=0.5+A*sin(i*2*3.14/N)
SACL *+
SACH *+
LACL #0
SACL *+
LACL #3F00H ;3F00 0000h =0.5
SACL *+
CALL F$$ADD
MAR *-
ZALH *-
ADDS * ;结果在 ACC
LRLK AR1,STACK
SACL *+
SACH *+
LACL T3PR_TEMPL
SACL *+
LACL T3PR_TEMPH
SACL *+
CALL F$$MUL
MAR *-
ZALH *-
ADDS * ;结果在 ACC
LRLK AR1,STACK ;CMPR的浮点数转换为整数
SETC SXM
SACL *+
SACH *+
290
CALL F$$FTOI,AR1
CLRC SXM ;结果在 ACC
SACL DATIOL
LDP #5
LACC I
SUB N
BCND NSPWM,GEQ
LACC I
ADD #1
SACL I
B RRET
NSPWM: SPLK #0,I ;断是否是下一个周期 RRET: RET
PHANTOM:KICK_DOG ;复位WD计数器
RET
;(7)定时器3中断程序
GISR2: SST #0,ST0_CON1 ;保存状态寄存器
SST #1,ST1_CON1
LDP #0E0h ;DP指针指向 PIVR 所在的数据区
LACC PIVR,1 ;读 EVIVRB, 结果左移一位
ADD #PVECTORS ;加上偏移量
BACC
T3GP_ISR:LDP #5
LACC DFLAG
OR #1 ;设置DFLAG.15,1
SACL DFLAG
LACL DATIOL
LDP #DP_EVB
SACL CMPR4 ;更新比较寄存器的值
ADD #32H
SACL CMPR5
ADD #32H
SACL CMPR6
LDP #0
LST #1,ST1_CON1
LST #0,ST0_CON1
LDP #DP_EVB
SPLK #0FFFFH,EVBIFRA
291
CLRC INTM
RET
END
292
12.4 串行EEPROM的接口编程
; ~~~~~~~~~~~~~~~~~~~~~~~~~宏定义~~~~~~~~~~~~~~~~~~~~~~~
SBIT0: .macro DMA,MASK ;清除DMA单元的MASK位
LACC DMA
AND #(0FFFFh-MASK)
SACL DMA
.endm
SBIT1: .macro DMA,MASK ;置位DMA单元的MASK位
LACC DMA
OR #MASK
SACL DMA
.endm
B15_MSK .set 8000h ;常数定义 B14_MSK .set 4000h
B13_MSK .set 2000h
B12_MSK .set 1000h
B11_MSK .set 0800h
B10_MSK .set 0400h
B9_MSK .set 0200h
B8_MSK .set 0100h
B7_MSK .set 0080h
B6_MSK .set 0040h
B5_MSK .set 0020h
B4_MSK .set 0010h
B3_MSK .set 0008h
B2_MSK .set 0004h
B1_MSK .set 0002h
B0_MSK .set 0001h
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~端口初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LDP #225 ;7080h,70FFh
SBIT0 MCRB,B3_MSK ;设置IOPC3为I/O口
SBIT0 MCRC,B0_MSK ;设置IOPE0为I/O口
SBIT0 MCRC,B7_MSK ;设置IOPE7为I/O口
SBIT1 PCDATDIR,B11_MSK ;设置IOPC3为输出口
SBIT1 PEDATDIR,B8_MSK ;设置IOPE0为输出口
293
2 通用读写24LC16B子程序
EEPROM: LDP #225 ;7080h,70FFh
LAR AR0,*-,AR0 ;AR0:读写的字节数, AR1:指向控制字节
SBRK #1
MAR *,AR1
EEPROM1: CALL I2CStart ;设置开始状态
LACL *+ ;AR1:临时单元
AND #0FEH ;清除控制字节的第0位
SACL *
CALL I2CSendByte ;送出控制字节(R/W=0)
CALL I2CRecAck ;检查应答
BCND EEPROM2,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM2:SBRK #2 ;AR1: 24LC16B的块内地址
CALL I2CSendByte ;送出24LC16B的块内地址
CALL I2CRecAck ;检查应答
BCND EEPROM3,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM3: ADRK #1 ;AR1:控制字节
BIT *,15 ;读/写操作判断
BCND EEPROM4,TC
SBIT0 PCDATDIR,B3_MSK ;写操作,设置写允许:WP=0
SBRK #2
LAR AR1,* ;AR1:输出数据缓冲区 EEPROM31:CALL I2CSendByte ;写出一个字节数据
CALL I2CRecAck ;检查应答
BCND EEPROM30,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM30:ADRK #1 ;指向下一个字节待写数据
MAR *,AR0
BANZ EEPROM31,AR1
SBIT1 PCDATDIR,B3_MSK ;写操作完成,写保护:WP=1
B EEPROM5
EEPROM4: ;读操作
294
CALL I2CStart ;设置开始状态
CALL I2CSendByte ;送出控制字节(R/W=1)
CALL I2CRecAck ;检查应答
BCND EEPROM40,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM40:SBRK #2
LAR AR1,*,AR0 ;AR1:输入数据缓冲区
EEPROM43:BANZ EEPROM41,AR1
B EEPROM42
EEPROM41:CALL I2CRecByte ;接收一个字节数据
CALL I2CAck ;产生应答信号
MAR *,AR0
B EEPROM43
EEPROM42:CALL I2CRecByte ;接收最后一个字节数据
CALL I2CNoAck ;不产生应答信号
EEPROM5: CALL I2CStop ;设置结束状态
LACL #0 ;成功操作标志
EEPROMRET:
RET
2; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~启动IC总线~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I2CStart: SBIT0 PEDATDIR,B0_MSK ;SCL=0
SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
SBIT1 PEDATDIR,B7_MSK ;SDA=1
SBIT1 PEDATDIR,B0_MSK ;SCL=1
RPT #14
NOP ;600 ns
SBIT0 PEDATDIR,B7_MSK ;SDA=0
RPT #14
NOP
SBIT0 PEDATDIR,B0_MSK ;SCL=0
SBIT1 PEDATDIR,B7_MSK ;SDA=1
RET
2; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~停止IC总线~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I2CStop: SBIT0 PEDATDIR,B0_MSK ;SCL=0
SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
SBIT0 PEDATDIR,B7_MSK ;SDA=0
SBIT1 PEDATDIR,B0_MSK ;SCL=1
295
RPT #14
NOP
SBIT1 PEDATDIR,B7_MSK ;SDA=1
RPT #14
NOP
SBIT0 PEDATDIR,B0_MSK ;SCL=0
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~检查应答位~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I2CRecAck:SBIT0 PEDATDIR,B0_MSK ;SCL=0
SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
SBIT1 PEDATDIR,B7_MSK ;SDA=1
SBIT1 PEDATDIR,B0_MSK ;SCL=1
RPT #14
NOP
SBIT0 PEDATDIR,B15_MSK ;设置IOPE7为输入口
NOP
SBIT0 PEDATDIR,B0_MSK ;SCL=0
LACL PEDATDIR
AND #80H ;返回在ACC中
RET
2C总线产生应答~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~对I
I2CAck: SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
SBIT0 PEDATDIR,B7_MSK ;SDA=0
SBIT1 PEDATDIR,B0_MSK ;SCL=1
RPT #14
NOP
SBIT0 PEDATDIR,B0_MSK ;SCL=0
NOP
SBIT1 PEDATDIR,B7_MSK ;SDA=1
RET
2; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~不对IC总线产生应答~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I2CNoAck: SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
SBIT1 PEDATDIR,B7_MSK ;SDA=1
SBIT1 PEDATDIR,B0_MSK ;SCL=1
RPT #14
NOP
SBIT0 PEDATDIR,B0_MSK ;SCL=0
RET
296
2C总线写入数据~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~向I
I2CSendByte: LAR AR2,#7 ;位计数器:8位
LACL * ;AR1:指向待写的数据
RPT #7
SFL
SACL *
SBIT1 PEDATDIR,B15_MSK ;设置IOPE7为输出口
I2CS3: SBIT0 PEDATDIR,B0_MSK ;SCL=0
LACC *,16
SFL
SACH *,AR2
BCND I2CS1,C
SBIT0 PEDATDIR,B7_MSK ;SDA=0
B I2CS2
I2CS1: SBIT1 PEDATDIR,B7_MSK ;SDA=1 I2CS2: SBIT1 PEDATDIR,B0_MSK ;SCL=1
BANZ I2CS3,AR1
SBIT0 PEDATDIR,B0_MSK ;SCL=0
RET
2; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~从IC总线读取数据~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I2CRecByte:LAR AR2,#7 ;位计数器:8位
SBIT0 PEDATDIR,B15_MSK ;设置IOPE7为输入口
SBIT0 PEDATDIR,B0_MSK ;SCL=0
SPLK #0,*
I2CR1: SBIT1 PEDATDIR,B0_MSK ;SCL=1
LACL *
SFL
SACL *
LACL PEDATDIR
RPT #6
SFR
AND #1
OR *
SACL *,AR2
SBIT0 PEDATDIR,B0_MSK ;SCL=0
BANZ I2CR1,AR1
ADRK #1 ;AR1:指向下一个存储单元
RET
297
3 通用读写24LC16B子程序调用实例
MAR *,AR1
LAR AR1,#STACK ;AR1:堆栈指针
SPLK #200H,*+ ;待写数据存放空间的首地址
SPLK #00,*+ ;24LC16B的块内地址
SPLK #0A0H,*+ ;控制字节(R/W=0)
SPLK #10,* ;待写数据字节数
CALL EEPROM ;调用通用读写24LC16B子程序
12.4.6 24LC256的应用编程
1 初始化子程序
;----------------宏定义----------------- SBIT0: .macro DMA,MASK ;该宏用于清除DMA单元的MASK位
LACC DMA
AND #(0FFFFH-MASK)
SACL DMA
.endm
SBIT1: .macro DMA,MASK ;该宏用于置位DMA单元的MASK位
LACC DMA
OR #MASK
SACL DMA
.endm
;-----------------常数的定义--------------- B15_MSK .set 8000h
B14_MSK .set 4000h
B13_MSK .set 2000h
B12_MSK .set 1000h
B11_MSK .set 0800h
B10_MSK .set 0400h
B9_MSK .set 0200h
B8_MSK .set 0100h
B7_MSK .set 0080h
B6_MSK .set 0040h
B5_MSK .set 0020h
B4_MSK .set 0010h
B3_MSK .set 0008h
B2_MSK .set 0004h
298
B1_MSK .set 0002h B0_MSK .set 0001h COUNT .set 0325h ;----------------系统初始化子程序----------- SYSINITIAL:
SETC INTM ;关闭总中断
CLRC SXM
CLRC OVM
CLRC CNF ;B0被分配为数据空间
LDP #SCSR1>>7 ;取得SCSR1所在的页
SPLK #81FEH,SCSR1 ; CLKIN=6M,CLKOUT=24M
SPLK #0E8H,WDCR ; 关闭WDT
LDP #IMR>>7
SPLK #0h,IMR ;不使能所有中断
SPLK #0FFFFh,IFR ; 清除所有中断标志
LDP #0E1h
SBIT0 MCRB,B0_MSK
SBIT0 MCRB,B3_MSK
SBIT0 MCRB,B8_MSK ;定义IOPD0,IOPC3,IOPC0为通用I/O口
SBIT1 PCDATDIR,B11_MSK ;定义IOPC3口为输出
SBIT1 PDDATDIR,B8_MSK ;定义IOPD0口为输出
RET
2 通用读写24LC256子程序
.text
;-----------通用读写24LC256子程序------------ EEPROM:
LDP #225
LAR AR0,*-,AR0;AR0:读写的字节数, AR1:指向控制字节,ARP=AR0;
SBRK #1
MAR *,AR1
EEPROM1:
2 CALL I2Cstart ;设置IC总线的开始状态
LACL *+ ;AR1:临时单元
AND #0FEH ;清除控制字节的第0位
SACL *
CALL I2CsendByte ;送出控制字节(R/W=0)
CALL I2CRECACK ;检查应答位
BCND EEPROM2,EQ
299
LACL #1 ;出错
B EEPROMRET
EEPROM2:
SBRK #2 ;AR1:24LC256的块内地址的低字节 ;(在此之前AR1指向临时单元,比控制字adress多1)
CALL I2CsendByte ;送出24LC256的块内地址的低字节 CALL I2CRECACK ;检查应答位
BCND HIGHBYTE,EQ
LACL #1 ;出错
B EEPROMRET
HIGHBYTE:
SBRK #1 ;AR1:24LC256的块内地址的高字节
CALL I2CsendByte ;送出24LC256的块内地址的高字节
CALL I2CRECACK ;检查应答位
BCND EEPROM3,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM3:
ADRK #2 ;AR1控制字节
BIT *,15 ;读/写操作判断
BCND EEPROM4,TC
SBIT0 PDDATDIR,B0_MSK;设置写允许:WP=0
SBRK #3
LAR AR1,* ;AR1:输出数据缓冲区 EEPROM31:
CALL I2CSendByte ;写出一个字节数据
CALL I2CRECACK ;检查应答位
BCND EEPROM30,EQ
LACL #1 ;出错
B EEPROMRET
EEPROM30:
ADRK #1 ;指向下一个字节待写数据
MAR *,AR0
BANZ EEPROM31,AR1
B EEPROM5
EEPROM4: ;读操作
2 CALL I2CStart ;设置IC总线开始状态
CALL I2CSendByte ;送出控制字节(R/W=1)
300
CALL I2CRECACK ;检查应答位
BCND EEPROM40,EQ ;
LACL #1 ;出错
B EEPROMRET
EEPROM40:
SBRK #3
LAR AR1,*,AR0 ;AR1:输入数据缓冲区 EEPROM43:
BANZ EEPROM41,AR1
B EEPROM42
EEPROM41:
CALL I2CRecByte ;接收一个字节数据
CALL I2CAck ;产生应答信号
MAR *,AR0
B EEPROM43
EEPROM42:
CALL I2CRecByte ;接收最后一个字节数据
CALL I2CNoAck ;不产生应答信号 EEPROM5:
CALL I2CStop ;设置结束状态
LACL #0 ;成功标志,ACC=0 EEPROMRET:
RET ;返回
2C总线子程序--------------------- ;-----------启动I
I2CStart:
SBIT0 PCDATDIR,B3_MSK ;SCL=0
SBIT1 PCDATDIR,B8_MSK ;IOPC0(SDA为输出)
SBIT1 PCDATDIR,B0_MSK
SBIT1 PCDATDIR,B3_MSK ;SDA=1,SCL=1
RPT #14
NOP ;延时600ns
SBIT0 PCDATDIR,B0_MSK ;SDA=0
RPT #14
NOP ;延时600ns
SBIT0 PCDATDIR,B3_MSK ;SCL=0
SBIT1 PCDATDIR,B0_MSK ;SDA=1
RET
2;-----------向IC总线写入数据子程序------------
301
I2CSendByte:
LAR AR2,#7 ;位计数器为8
LACL * ;AR1指向待写的数据
RPT #7
SFL
SACL *
SBIT1 PCDATDIR,B8_MSK ;设置IOPC0为输出口 I2CS3:
SBIT0 PCDATDIR,B3_MSK ;SCL=0
LACC *,16
SFL
SACH *,AR2
BCND I2CS1,C
SBIT0 PCDATDIR,B0_MSK ;SDA=0,(该位为0)
B I2CS2
I2CS1:
SBIT1 PCDATDIR,B0_MSK ;SDA=1,(该位为1) I2CS2:
SBIT1 PCDATDIR,B3_MSK ;SCL=1,在SCL=1期间数据线上的
;状态必须保持不变
BANZ I2CS3,AR1
SBIT0 PCDATDIR,B3_MSK ;SCL=0
RET
;-------------检查应答位子程序----------- I2CRECACK:
SBIT0 PCDATDIR,B3_MSK;SCL=0
SBIT1 PCDATDIR,B3_MSK ;SCL=1
RPT #14
NOP
SBIT0 PCDATDIR,B8_MSK;IOPC0(SDA为输入)
NOP
NOP
LACL PCDATDIR
AND #01H ;返回在ACC中,若ACC=0表示操作成功,
;若ACC=1表示操作失败
RET
2C总线读取数据------------ ;------------从I
I2CRecByte:
302
LAR AR2,#7 ;位计数器为8
SBIT0 PCDATDIR,B8_MSK ;设置IOPC0为输入口
SBIT0 PCDATDIR,B3_MSK ;SCL=0
SPLK #0,*
I2CR1:
SBIT1 PCDATDIR,B3_MSK ;SCL=1
LACL *
SFL
SACL *
LACL PCDATDIR ;读取IOPC0上的数据
AND #1
OR *
SACL *,AR2
SBIT0 PCDATDIR,B3_MSK;SCL=0
BANZ I2CR1,AR1
ADRK #1 ;AR1:指向下一个存储单元
RET
;----------对I2C总线产生应答------------ I2CAck:
SBIT1 PCDATDIR,B8_MSK ;设置IOPC0为输出口
SBIT0 PCDATDIR,B0_MSK ;SDA=0
SBIT1 PCDATDIR,B3_MSK ;SCL=1
RPT #14
NOP ;延时600ns
SBIT0 PCDATDIR,B3_MSK ;SCL=0
NOP
SBIT1 PCDATDIR,B0_MSK ;SDA=1,数据线恢复为1,但此时 ;SCL=0,SDA在后来可以改变
RET
2C总线产生应答------------ ;-------------不对I
I2CNoAck:
SBIT1 PCDATDIR,B8_MSK ;设置IOPC0为输出口
SBIT1 PCDATDIR,B0_MSK ;SDA=1
SBIT1 PCDATDIR,B3_MSK ;SCL=1
RPT #14
NOP ;延时600ns
SBIT0 PCDATDIR,B3_MSK ;SCL=0
RET
303
2C总线------------ ;-------------停止I
I2CStop:
SBIT0 PCDATDIR,B3_MSK ;SCL=0
SBIT1 PCDATDIR,B8_MSK ;设置IOPC0为输出口
SBIT0 PCDATDIR,B0_MSK ;SDA=0
SBIT1 PCDATDIR,B3_MSK ;SCL=1
RPT #14
NOP
SBIT1 PCDATDIR,B0_MSK ;SDA=1
RPT #14
NOP
SBIT0 PCDATDIR,B3_MSK ;SCL=0
RET ;返回
3 通用读写24LC16B子程序调用实例
;----------------系统初始化子程序----------- SYSINITIAL:
SETCINTM ;关闭总中断
CLRC SXM
CLRC OVM
CLRC CNF ;B0 被分配为数据空间
LDP #SCSR1>>7 ;取得SCSR1所在的页
SPLK#81FEH,SCSR1 ; CLKIN=6M,CLKOUT=24M
SPLK#0E8H,WDCR ; 关闭 WDT
LDP #IMR>>7
SPLK#0h,IMR ;关闭所有中断
SPLK#0FFFFh,IFR ;清除所有中断标志
LDP #0E1h
SBIT0 MCRB,B0_MSK
SBIT0 MCRB,B3_MSK
SBIT0 MCRB,B8_MSK ;定义IOPD0,IOPC3,IOPC0为通用I/O引脚
SBIT1 PCDATDIR,B11_MSK ;定义IOPC3口为输出
SBIT1 PDDATDIR,B8_MSK ;定义IOPD0口为输出
RET
;--------------写数据子程序-------------------- LOADDATA:
MAR *,AR0
LAR AR0,#310H
LAR AR1,#09H ;写入10个数据到数据存储区
304
NEXT:
LACL #71h
SACL *+,AR1
BANZ NEXT,AR0
LDP #COUNT>>7
SPLK#0,COUNT
RET
_c_int0: ;主程序入口
CALL SYSINITIAL ;系统初始化
CALL LOADDATA ;预先向指定的存储区写入一些需要 ;写入EEPROM的数据
;先向24LC256写入10个数据
MAR *,AR1
LAR AR1,#300H ;AR1指向堆栈
SPLK#310H,*+ ;待写数据存放空间的首地址
SPLK#00,*+ ;24LC256的块内地址高字节
SPLK#00,*+ ;24LC256的块内地址低字节
SPLK#0A0H,*+ ;控制字(R/W=0)
SPLK#10,* ;待写数据的字节数
CALL EEPROM ;调用通用读写24LC16B子程序 ;再把这10个数据读出来放入相应的存储空间
READ:
LDP #COUNT>>7
LACL COUNT
ADD #01
SACL COUNT
MAR *,AR1
LAR AR1,#300H ;AR1指向堆栈
SPLK #31BH,*+ ;读入数据存放的首地址
SPLK #00,*+ ;待读的24LC256的块内地址高字节
SPLK #00,*+ ;待读的24LC256的块内地址低字节
SPLK #0A1H,*+ ;控制字(R/W=1)
SPLK #10,* ;需要读的字节数
CALL EEPROM ;调用通用读写24LC16B子程序
BCND READ,NEQ ;如果读出不成功则继续读 LOOP:
B LOOP
305
12.5 TMS320LF2407可屏蔽中断的实现
.include "F2407REGS.H" ;引用头部文件
.def _c_int0
;(1)建立中断向量表
.sect ".vectors" ;定义主向量段
RSVECT B _c_int0 ;PM 0 Reset Vector 1 INT1 B PHANTOM ;PM 2 Int level 1 4 INT2 B GISR2 ;PM 4 Int level 2 5 INT3 B PHANTOM ;PM 6 Int level 3 6 INT4 B PHANTOM ;PM 8 Int level 4 7 INT5 B PHANTOM ;PM A Int level 5 8 INT6 B PHANTOM ;PM C Int level 6 9 RESERVED B PHANTOM ;PM E (Analysis Int) 10 SW_INT8 B PHANTOM ;PM 10 User S/W int — SW_INT9 B PHANTOM ;PM 12 User S/W int — SW_INT10 B PHANTOM ;PM 14 User S/W int — SW_INT11 B PHANTOM ;PM 16 User S/W int — SW_INT12 B PHANTOM ;PM 18 User S/W int — SW_INT13 B PHANTOM ;PM 1A User S/W int — SW_INT14 B PHANTOM ;PM 1C User S/W int — SW_INT15 B PHANTOM ;PM 1E User S/W int — SW_INT16 B PHANTOM ;PM 20 User S/W int — TRAP B PHANTOM ;PM 22 Trap vector — NMI B PHANTOM ;PM 24 Non maskable Int 3 EMU_TRAP B PHANTOM ;PM 26 Emulator Trap 2 SW_INT20 B PHANTOM ;PM 28 User S/W int — SW_INT21 B PHANTOM ;PM 2A User S/W int — SW_INT22 B PHANTOM ;PM 2C User S/W int — SW_INT23 B PHANTOM ;PM 2E User S/W int — SW_INT24 B PHANTOM ;PM 30 User S/W int — SW_INT25 B PHANTOM ;PM 32 User S/W int — SW_INT26 B PHANTOM ;PM 34 User S/W int — SW_INT27 B PHANTOM ;PM 36 User S/W int — SW_INT28 B PHANTOM ;PM 38 User S/W int — SW_INT29 B PHANTOM ;PM 3A User S/W int — SW_INT30 B PHANTOM ;PM 3C User S/W int — SW_INT31 B PHANTOM ;PM 3E User S/W int —
306
.sect ".pvecs" ;定义子向量段
PVECTORS B PHANTOM ;Reserved pvector addr offset-0000h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0005h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-000ah
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0010h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0015h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-001Ah
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0020h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
307
B PHANTOM ;Reserved pvector addr offset-0025h
B PHANTOM ;Reserved pvector addr offset
B T1PINT_ISR ;Reserved pvector addr offset-0027h T1PINT中断
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-002Ah
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;pvector addr offset 0x02f - T3PINT
B PHANTOM ;Reserved pvector addr offset-0030h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0035h
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-003aAh
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-003Fh
B PHANTOM ;Reserved pvector addr offset
B PHANTOM ;Reserved pvector addr offset-0041h ;(2)主程序
.text
_c_int0
SETC INTM
CLRC SXM
CLRC OVM
CLRC CNF ;B0区被配置为数据空间
LDP #0E0H
SPLK #81FEH,SCSR1 ;CLKIN=6 M,CLKOUT=24 M
308
SPLK #0E8H,WDCR ;Disable WDT
LDP #0
SPLK #02H,IMR ;使能中断优先级INT2
SPLK #0FFFFh,IFR ;清中断标志
LDP #DP_PF2
LDP #DP_EVA
SPLK #80H,EVAIMRA ;使能T1PINT 中断
SPLK #0FFFFh,EVAIFRA ;清EVA中断标志
SPLK #0,GPTCONA
SPLK #177H,T1PR ;使定时器每1 ms产生一次中断
SPLK #0,T1CNT
SPLK #164CH,T1CON ;定时器1设置
CLRC INTM ;开总中断
WAIT: NOP
B WAIT
;(3)中断程序
GISR2: ;优先级INT2中断入口
;保护现场
LDP #0E0H
LACC PIVR,1 ;读取外设中断向量寄存器(PIVR),并左移一位
ADD #PVECTORS ;加上外设中断入口地址
BACC ;跳到相应的中断服务子程序 T1PINT_ISR: LDP #DP_EVA ;通用定时器1中断入口
SPLK#0,T1CNT
GISR2_RET: ;中断返回
;恢复现场
CLRC INTM ;开总中断,因为一进入中断就自动关闭总中断
RET
;(4)假中断程序
PHANTOM
KICK_DOG ;复位看门狗
RET
END
309
12.6 TMS320LF2407捕获单元CAP的应用
CAP4TEMP .usect ".data0",1 ;CAP4 临时寄存器
.include "F2407REGS.H" ;引用头部文件
.def _c_int0
;(1)建立中断向量表
.sect ".vectors" ;定义主向量段
RSVECT B _c_int0 ;PM 0 Reset Vector 1 INT1 B PHANTOM ;PM 2 Int level 1 4 INT2 B PHANTOM ;PM 4 Int level 2 5 INT3 B PHANTOM ;PM 6 Int level 3 6 INT4 B GISR4 ;PM 8 Int level 4 7 INT5 B PHANTOM ;PM A Int level 5 8 INT6 B PHANTOM ;PM C Int level 6 9 RESERVED B PHANTOM ;PM E (Analysis Int) 10
?
?
SW_INT31 B PHANTOM ;PM 3E User S/W int — ;中断子向量入口定义pvecs
.sect ".pvecs" ;定义子向量段
PVECTORS B PHANTOM ;Reserved pvector addr offset-0001h
?
?
B CAP4_ISR ;Reserved pvector addr offset-0036h CAP4中断
?
?
B PHANTOM ;Reserved pvector addr offset-0041h ;(2)主程序
.text
_c_int0
LDP #5
SPLK #00H, CAP4TEMP
CALL SYSINIT
CALL CAP_INIT ;调CAP4初始化程序
WAIT NOP
B LOOP
;(3)系统初始化程序
SYSINIT:SETC INTM
310
CLRC CNF ;B0区被配置为数据空间
LDP #0E0H ;指向7000h,7080h区
SPLK #81FEH,SCSR1 ;时钟4倍频,CLKIN=6 M,CLKOUT=24 M
SPLK #0E8H,WDCR ;不使能WDT
LDP #0
SPLK #0008H,IMR ;使能中断第4级INT4
SPLK #0FFFFH,IFR ;清全部中断标志
RET
;(4)捕获单元初始化程序
CAP_INIT:LDP #DP_PF2 ;指向7090h,7100h
LACL MCRC
OR #0380H ;IOPE7, IOPF0, IOPF1 被配置为
SACL MCRC ;特殊功能方式:CAP[4,6]
SETC INTM
LDP #DP_EVB
SPLK #049H,GPTCONB ;TCOMPOE=1,T4PIN=10,T3PIN=01
SPLK #0,T3CNT
SPLK #01742H,T3CON
SPLK #0FFFFH,T3PR ;定时器周期比较寄存器设为最大
SPLK #00H,EVBIMRA
SPLK #00H,EVBIMRB
SPLK #22C0H,CAPCONB ;CAP4 捕获允许,捕获上升沿
SPLK #01H,EVBIMRC ;CAP4 中断使能
SPLK #0FFFFh,EVBIFRA ;清 EVB 全部中断标志
SPLK #0FFFFh,EVBIFRB
SPLK #0FFFFh,EVBIFRC
CLRC INTM ;开总中断
RET
;(5)中断程序程序
GISR4: ;优先级INT4中断入口
;保护现场
LDP #0E0H
LACC PIVR,1 ;读取外设中断向量寄存器(PIVR),并左移一位
ADD #PVECTORS ;加上外设中断入口地址
BACC ;跳到相应的中断服务子程序 CAP4_ISR: ;捕获单元4中断程序入口
LDP #DP_EVB
LACL CAP4FIFO
311
LDP #5
SACL CAP4TEMP ;读出捕获的值
LDP #DP_EVB
SPLK #0,T3CNT ;清 T3 计数值,使其重新计数 GISR2_RET: ;中断返回
;恢复现场
CLRC INTM ;开总中断,因为一进中断就自动关闭总中断
RET
;(5)假中断程序
PHANTOM
KICK_DOG ;复位看门狗
RET
END
312
12.7 PID算法
PID: LDP #DP_B01 ;数据页4——0200h,0280h
SETC SXM ;允许符号扩展
LACL VREF ;V,Q.15*256 ref
SUB V ;V,Q.15*256
SACL VE2 ;e(k)= V,V,Q15*256 ref
SUB VE1 ;e(k-1),Q15*256
SACL PIDTMP1 ;Delta(e(k))=e(k)-e(k,1),Q15/256
SUB VE1
ADD VE0 ;e(k,2),Q15*256
SACL PIDTMP3 ;Delta(e(k)) ,Delta(e(k,1))= e(k)-2e(k,1)+e(k,2)
;Q15*256
LT KP ;Kp,Q15*32
MPY PIDTMP1
PAC ;Kp*Delta(e(k)),Q30*8192
RPT #4
SFL ;Kp*Delta(e(k)),Q30*256
SACH PIDTMP1,1 ;Kp*Delta(e(k)),Q15*256
LT KI ;Ki,Q15*32
MPY VE2
PAC ;Ki*e(k),Q30*8192
RPT #4
SFL ;Ki*e(k),Q30*256
SACH PIDTMP2,1 ;Ki*e(k),Q15*256
LT KD ;Kd,Q15*32
MPY PIDTMP3
PAC ;Kd* Delta(e(k))-Delta(e(k-1)),Q30*8192
RPT #4
SFL ;Kd* Delta(e(k))-Delta(e(k-1)),Q30*256
SACH PIDTMP3,1 ;Kd* Delta(e(k))-Delta(e(k-1)),Q15*256
LACL U ;u(k,1),Q15*256
ADD PIDTMP1
ADD PIDTMP2
ADD PIDTMP3
SACL U ;u(k),Q15*256
SUB #4B00H ;150V,Q15*256
313
BCND PID1,LEQ
SPLK #4A3DH,U ;上限幅
B PID2
PID1: BIT U,0
BCND PID2,NTC
SPLK #0,U ;下限幅 PID2: LACL VE1 ;平移保存
SACL VE0 ;e(k,2)=e(k,1)
LACL VE2
SACL VE1 ;e(k,1)=e(k)
RET
314