📄 timer.asm
字号:
*********************************************************************************
* UART.ASM v1.00 *
* 版权(c) 2003- 北京合众达电子技术有限责任公司 *
* 设计者: 段立锋 *
*********************************************************************************
.copy "vc54x.inc" ; VC5402 Memory-Mapped Register Declaration
.copy "dec5416.inc" ; SEED DEC5416 Memory-Mapped Register Declaratio
.mmregs
.global _main
.def _timer_isr
.ref IV_RESET
****************************************************************************
* I/O空间: 插2×2个等待 ? *
* 数据空间低32K: 插2×2个等待 ? *
* 数据空间高32K: 插5×2个等待 ? *
* 程序空间低512K:?插2×2个等待 ? *
* 程序空间高512K: 插5×2个等待 ? *
****************************************************************************
SWWSR_VAL .set 07492H
SWCR_VAL .set 0001H ; 等待×2
__STACK_SIZE .set 0x100 ; 堆栈长度为256字
OVLY_0 .set 005FH ; OVLY = '0'
PLLX2 .set 01007H
****************************************************************************
*串口测试参数 *
****************************************************************************
buad_9k6h .set 00H
buad_9k6l .set 09CH
buad_19k2h .set 00
buad_19k2l .set 04EH
uart_format .set 03H ;数据长度为8个,一个停止位,没有较验
****************************************************************************
*定时器设置参数 *
****************************************************************************
;PRD_DATA .set 07D00H ;the period of timer is 0.001s
PRD_DATA .set 06000H ;the period of timer is 0.001s
TCR_START .set 0c61H ;start the timer
***************************************************************************
*命令分类 *
***************************************************************************
TIME_SET .set 0A2H
RESET .set 0A5H
****************************************************************************
* Declare the stack. Size is determined by the linker option -stack. The *
* default value is 256 words. *
****************************************************************************
__stack: .usect ".stack",0 ; set the stack memory
*串口接收缓冲区
*缓冲区的格式:
*第一个字节:要接收的数据长度
*第二个字节以后为要接收的数据
_uarta_rec: .usect ".uarta_rbuff",128,0,0
*串口发送缓冲区
*缓冲区格式
*第一个字节为要发送数据的长度
*第二个字节以后为要发送的数据
_uarta_tra: .usect ".uarta_tbuff",128,0,0
*系统状态缓冲区
*系统缓冲区的定义:
*第0个字节 :IO寻址缓冲;
*第一个字节:IO寻址缓冲;
*第二个字节:1秒钟记时满;
*第三个字节:当前小时值;
*第四个字节:当前的分钟值;
*第五个字节:当前的秒值;
*第六个字节:接收是否出错
*第七个字节:计数器的累加值;
_sys_statbuff: .usect ".sys_buffer",32,0,0
.text
_main:
****************************************************************************
* INIT STACK POINTER. REMEMBER STACK GROWS FROM HIGH TO LOW ADDRESSES. *
****************************************************************************
STM #__stack,SP ; set to beginning of stack memory
ADDM #(__STACK_SIZE-1),*(SP) ; add size to get to top
ANDM #0fffeh,*(SP) ; make sure it is an even address
SSBX SXM ; turn on SXM for LD #cinit,A
****************************************************************************
* 中断向量表重定位,配置软件等到寄存器 *
****************************************************************************
ANDM #OVLY_0,*(PMST) ; OVLY = 0
ORM #IV_RESET,*(PMST) ; 中断向量表重定位
STM #SWWSR_VAL,SWWSR ; 配置软件等待寄存器
STM #SWCR_VAL,SWCR
****************************************************************************
* SET UP REQUIRED VALUES IN STATUS REGISTER *
****************************************************************************
RSBX CPL ; turn on compiler mode bit
RSBX OVM ; clear overflow mode bit
RSBX INTM ; enable the interuption
STM #0,IMR ; enable the timer interuption
****************************************************************************
*设置系统时钟为32MHz *
****************************************************************************
STM #0B,CLKMD ;switch to DIV mode
TstSatu: LDM CLKMD,B
AND #01B,B ;poll STATUS bit
BC TstSatu,BNEQ
STM #PLLX2,CLKMD ;switch to PLL X 2 mode
PllSatu: LDM CLKMD,B
AND #01B,B ;poll STATUS bit
BC PllSatu,BEQ
****************************************************************************
*系统状态缓冲区清零 *
****************************************************************************
STM #_sys_statbuff,AR0
RPT #01FH
ST #0,*AR0+
****************************************************************************
*主程序 *
****************************************************************************
;接收主机命令
STM #_sys_statbuff,AR0;取系统状态缓冲区的首址
ST #03E7H,*AR0(7) ;设置每秒需要的中断次数
CALL _uart_init ;初始化串口
timer: CALL _uart_reciever ;接收数据
;是否有错误
LD *AR0(6),A
STM #0,AH
BC timer_err,ANEQ
;是否要设定时间
STM #_uarta_rec,AR1
LD *AR1+,A
STM #0,AH
SUB #TIME_SET,A
BC time_set,AEQ
;是否要系统复位
STM #_uarta_rec,AR1
LD *AR1,A
STM #0,AH
SUB #RESET,A
BC sys_reset,AEQ
B timer
time_set: LD *AR1+,A
STL A,*AR0(3) ;设置当前小时
LD *AR1+,A
STL A,*AR0(4) ;设置当前分钟
LD *AR1+,A
STL A,*AR0(5) ;设置当前秒
STM #_uarta_tra,AR2
RPT #07FH
ST #0,*AR2+
CALL _timer_start
STM #8,IMR ; enable the timer interuption
NOP
NOP
NOP
B timer
sys_reset: ST #04H,*AR0
PORTW *AR0, syscntl ;打开看门狗,使系统复位
B $
timer_err: ST #0,*AR0(6)
STM #_uarta_tra,AR2 ;取发送缓冲区的首址
ST #1,*AR2(0)
ST #0FFFFH,*AR2(1)
CALL _uart_send ;通知主机接收出错,重发
B timer
****************************************************************************
*A通路串口初始化 *
****************************************************************************
;设置波待率
_uart_init: STM #0,AH
STM #080H,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_lcr;将数据80写入到lcr寄存器
NOP
NOP
NOP
STM #buad_19k2l,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_dll;将buad_9k6l写入到dll寄存器
NOP
NOP
NOP
STM #buad_19k2h,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_dlh;将buad_9k6l写入到dll寄存器
NOP
NOP
NOP
;设置波待率分频数为1
; STM 0BFH,AL
; STL A,*AR0(0)
; PORTW *AR0(0),uart_a+_lcr;将0BF写入到lcr寄存器
; STM #010,AL
; STL A,*AR0(0)
; PORTW *AR0(0),uart_a+_efr;将010写入到efr寄存器
; STM #0,AL
; STL A,*AR0(0)
; PORTW *AR0(0),uart_a+_lcr;将0写入到lcr寄存器
; STM #0,AL
; STL A,*AR0(0)
; PORTW *AR0(0),uart_a+_mcr;将0写入到mcr寄存器
;设置数据格式
STM #uart_format,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_lcr;将0写入到lcr寄存器
NOP
NOP
NOP
;设置串口不使用FIFO方式
STM #0,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_fcr;将0写入到fcr寄存器
NOP
NOP
NOP
;开中断,串口输出无限制
STM #09H,AL
STL A,*AR0(0)
PORTW *AR0(0),uart_a+_fcr;将09写入到Mcr寄存器
NOP
NOP
NOP
RET
**************************************************************************
* 串口接收子程序 *
**************************************************************************
_uart_reciever: STM #_uarta_rec,AR1
STM #0,BH
STM #04H,BL
data_rec: PORTR (uart_a + _lsr),*AR0(0);读取接收状态
ANDM #01H,*AR0(0) ;检查接收是否有错
LD *AR0(0),A
STM #0,AH
BC data_rec,AEQ ;通知主机通讯错
PORTR (uart_a + _rhr),*AR1+ ;读接收数据
ANDM #0ffh,*AR1(-1)
SUB #1,B
STM #0,BH
BC data_rec,BNEQ
B uart_exit
;uart_err: ST #1,*AR0(6)
uart_exit: NOP
RET
****************************************************************************
*串口的发送子程序 *
****************************************************************************
_uart_send: STM #_uarta_tra,AR2
LD *AR2+,B
STM #0,BH
uart_check: PORTR (uart_a + _lsr),*AR0(1);读取接收状态
ANDM #020H,*AR0(1) ;是否已发送成功
LD *AR0(1),A
STM #0,AH
BC uart_check,AEQ
LD *AR2,A
NOP
NOP
PORTW *AR2+,(uart_a + _thr) ;发送数据
NOP
NOP
NOP
SUB #1,B
BC uart_check,BNEQ
RET
****************************************************************************
*定时器操做函数 *
* 操作内容:1、初始化定时器,定时间隔为千分之一秒,运行方式,连续运行, *
* 自动重装 *
* 2、启动定时器
****************************************************************************
_timer_start: STM #PRD_DATA,PRD ;set the period of the Timer0
STM #PRD_DATA,TIM
STM #TCR_START,TCR ;start the timer
RET
****************************************************************************
*定时器中断服务程序 *
****************************************************************************
_timer_isr: PSHM AL
PSHM AH
PSHM BL
PSHM BH
LD *AR0(7),A ;取出计时值
SUB #1,A
STL A,*AR0(7)
BC change_time, AEQ
B isr_exit
change_time: ST #03E7H,*AR0(7) ;1秒计时已到
LD *AR0(5),A ;取回当前秒
ADD #1,A ;当前秒加1
STL A,*AR0(5) ;保存当前秒
SUB #60,A
BC send_time,ANEQ
ST #0,*AR0(5)
ADDM #1,*AR0(4) ;分钟加1
LD *AR0(4),A
SUB #60,A
BC send_time,ANEQ
ST #0,*AR0(4)
ADDM #1,*AR0(3) ;小时加1
LD *AR0(3),A
SUB #24,A
BC send_time,ANEQ
ST #0,*AR0(3) ;小时复位
send_time: STM #_uarta_tra,AR2 ;将时间数据放入发送缓冲区
ST #04H,*AR2+ ;数据长度
ST #0A3H,*AR2+ ;类型
LD *AR0(3),A
STL A,*AR2+ ;送数据
LD *AR0(4),A
STL A,*AR2+
LD *AR0(5),A
STL A,*AR2+
CALL _uart_send ;发送数据
isr_exit: POPM BH
POPM BL
POPM AH
POPM AL
POPM ST1
POPM ST0
RETE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -