⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialr.asm

📁 大学微型计算机接口技术实验源代码,直接就可以运行,包含了C++和asm代码,比较前面.
💻 ASM
字号:
;*------------------------------------------------------*/
;*  SerialR.asm(查询方式半双工串行通信接口实验-接收端程序)  */
;*  查询方式半双工串行通信接收程序 Source File            */
;*  Copyright (c) 2001 by HUST                          */
;*		Modify	 Date	2005.4.10											*/
;*------------------------------------------------------*/

stack1 segment para 'stack'
	dw 200 dup(?)
stack1 ends

data51   equ  308h            ;8251A数据口
ctr151   equ  309h            ;8251A命令/状态口
ctr155   equ  303h            ;8255命令口
timer2   equ  306h            ;8253的2号计数器端口
timctl   equ  307h            ;8253命令口
clk00    equ  12h             ;8251输入时钟频率(十六进制表示)这是多少?
clk01    equ  34deh
factor   equ  16              ;波特率因子16

data segment para public 'data'
	int0a_off dw(?)
	int0a_seg dw(?)
	bps00    dw (?)
	receive db 100 dup(?)		   ;缓冲区
	resize  dw (?)			      ;缓冲区长度
	data51   equ  308h         ;8251A数据口
	ctr151   equ  309h         ;8251A命令/状态口
	ctr155   equ  303h         ;8255命令口
	timer2   equ  306h         ;8253的2号计数器端口
	timctl   equ  307h         ;8253命令口
	clk00    equ  12h          ;8251输入时钟频率(十六进制表示)这是多少?
	clk01    equ  34deh
	factor   equ  16           ;波特率因子16
mes1     db 'now enter the serial communication(receive)',0ah,0dh
         db 'end with q/Q',0ah,0dh,'$'
input_message  db '0:110 1:150 2:300 3:600'
               db 0dh,0ah
               db '4:1200 5:2400 6:4800 7:9600'
               db 0dh,0ah 
               db 'please take a choice(0~7)of baud_rate:'
               db 0dh,0ah,'$'
error_message  db 'input error! try again'
               db 0dh,0ah,'$'
data      ends

code      segment
assume  cs:code, ds:data, ss:stack1

charout proc near                ;送数子程
		out   dx,al                 
		push  cx
		mov   cx,100                ;延时
gg:	loop  gg
		pop   cx
		ret
charout	endp

int51 proc  near                 ;8251A初始化子程
		mov   dx,ctr151             ;8251A命令口
		xor   ax,ax                 ;空操作
		call  charout               ;送数子程
		mov   al,40h                ;内部复位
		call  charout
		mov   al,4ah                ;8251A方式命令
		call  charout
		mov   al,27h                ;8251A工作命令
		call  charout
		ret
int51	endp 

set_bps proc near                 ;8253-5计数初值计算与装入子程
		mov  dx,clk00                ;取8253-5输入时钟频率clk作被除数
		mov  ax,clk01               
		mov  bx,bps00                ;取所选波特率作第一个除数
		div  bx                      ;除法运算,商数送ax
		mov  dx,0                    ;余数清零
		mov  bx,factor               ;取波特率因子作第二个除数
		div  bx                      ;除法运算,得计数初值(商数)送ax
		mov  bx,ax                   ;保存计数初值至bx
		mov  dx,timctl               ;8253-5命令口
		mov  al,0b6h                 ;8253-5初始化命令
		out  dx,al
		mov  dx,timer2               ;8253-5计数器2的端口
		mov  ax,bx                   ;取计数初值
		out  dx,al                   ;装计数初值低字节
		mov  al,ah                   ;装计数初值高字节
		out  dx,al                    
		ret                          ;返回
set_bps  endp

serv_int proc far                 ;中断服务程序
		push bx
		push ax
		push dx
		push di
		push ds
		mov  ax,data		            ;载入数据段
		mov  ds,ax
		cli
		mov  dx,data51               ;已准备好,即有数据传送过来,则接收1个字符
		in   al,dx

		mov  di,resize		          ;载入缓冲区指针
		mov  [di],al		             ;将数据放入缓冲区
		inc  di			                ;缓冲区指针加1
		mov  resize,di		          ;保存缓冲区指针

		mov  al,62h              	  ;发中断结束命令(OCW2)
		mov  dx,0a0h
		out  dx,al                    ;向从片8259发EOI命令
		mov  al,20h
		out  020h,al		             ;向主片8259发EOI命令
		sti
		pop ds
		pop di
		pop dx
		pop ax
		pop bx
		iret
serv_int endp

main  proc  far                    ;通信(接收)主程序
		mov    ax,data
		mov    ds,ax
		mov    ah,9                   ;提示选择波特率
		mov    dx,seg input_message
		mov    ds,dx
		mov    dx,offset input_message
		int    21h
input:mov  ah,8                     ;输入波特率
		int  21h 
		cmp  al,'0'                    ;输入’0’,表示选择110baud
		jne  next1 
		mov  bps00,110                 ;存入bps00
		jmp  begin                     ;跳转开始begin处
next1:cmp  al,'1'
		jne  next2
		mov  bps00,150                 ;’1’表示150b/s
		jmp  begin 
next2:cmp  al,'2'
		jne  next3
		mov  bps00,300                 ;’2’表示300b/s
		jmp  begin 
next3:cmp  al,'3'
		jne  next4
		mov  bps00,600                  ;’3’表示600b/s
		jmp  begin 
next4:cmp  al,'4'
		jne  next5
		mov  bps00,1200                 ;’4’表示1200b/s
		jmp  begin 
next5:cmp  al,'5'
		jne  next6
		mov  bps00,2400                  ;’5’表示2400b/s
		jmp  begin 
next6:cmp  al,'6'
		jne  next7
		mov  bps00,4800                  ;’6’表示150b/s
		jmp  begin 
next7:cmp  al,'7'
		jne  error                       ;若波特率选择有错,则重新输入
		mov  bps00,9600                  ;’7’表示9600b/s
		jmp  begin 
error:  
		mov  ah,9                        ;提示波特率选择出错,则重新输入
		mov  dx,seg error_message 
		mov  ds,dx
		mov  dx,offset error_message
		int  21h
		jmp  input 
begin:call set_bps                     ;调用set_bps子程序,设置所选波特率的计算初初值
		call int51                        ;调用int51子程序,初始化8251A
		mov  ax,offset receive
		mov  resize,ax
		lea  dx,mes1
		mov  ah,09
		int  21h
		mov  dx,303h                     ;初始化8255A
		mov  al,80h
		out  dx,al
		mov  al,0dh                       ;置PC6=1,打开8253-5的GATE2,开始输出方波
		out  dx,al

		mov  ax,3572h	                    ;获取原中断向量
		int  21h
		mov  int0a_off,bx	               ;保存原中断向量
		mov  bx,es
		mov  int0a_seg,bx
		
		cli                               ;关中断
		mov  ax,2572h	                    ;设置新中断向量
		mov  dx,seg serv_int
		push ds
		mov  ds,dx
		mov  dx,offset serv_int
		int  21h		
		pop  ds                       

		in   al,0a1h		                 ;打开IRQ10(OCW1)
		and  al,0fbh
		out  0a1h,al	
		in   al,21h                       ;打开IRQ2
		and  al,0fbh
		out  21h,al			
		sti				                    ;开中断				
		hlt                               ;等待中断

isq:	mov  ah,0bh                      ;是否有键按下
		int  21h
		inc  al
		jnz  show
       
		mov  ah,08h		                ;是q/Q键就退出
		int  21h
		cmp  al,071h
		je   over
		cmp  al,051h
		je   over
		
show:	mov  ax,offset receive	       ;获取缓冲区首位地址偏移量
		mov  di,ax		
		cmp  di,resize		            ;比较,若相等,就循环等待;不相等,就显示接收的数据
		je   isq
snext:mov  dl,[di]
		mov  ah,02h
		int  21h
		inc  di
		cmp  di,resize
		jne  snext

		mov  ax,offset receive	       ;缓冲区指针复位为首地址偏移量,为下次接收准备好缓冲区
		mov  resize,ax

		jmp  isq
	
over:	mov  ax,2572h         	       ;恢复原中断向量
		mov  dx,int0a_seg
		push ds
		mov  ds,dx
		mov  dx,int0a_off
		int  21h	
		pop  ds
		in   al,0a1h    		            ;屏蔽IRQ10(OCW1)
		or   al,04h 
		out  0a1h,al	
		in   al,21h                     ;屏蔽IRQ2
		or   al,04h
		out  21h,al 	 
		mov  al,0ch                     ;置PC6=0,关闭8253-5的GATE2,停止输出方波
		mov  dx,303h
		out  dx,al
		mov  ax,4c00h                   ;程序退出
		int  21h
main   endp
code  ends
       end  main

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -