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

📄 main.asm

📁 本程序为调试ADI BF533DSP串行口通讯功能的小程序
💻 ASM
字号:
/*****************************************************************************
**																			**
**	 Name: 	UART  Software Interface										**	
**																			**
******************************************************************************

(C) Copyright 2006 - Analog Devices, Inc.  All rights reserved.

File Name:		main.asm

Date Modified:	04/03/03		Rev 1.0

Software:       VisualDSP++ 4.5

Hardware:		ADSP-BF533 EZ-KIT Lite Board
				ADSP-BF533 Blackfin Processor Rev 0.1

Special Connections:  
				EIA-232 Serial Cable (1:1)
				Terminal Program (i.e. Hyperterminal for Windows)
				- bit rate doesn't matter
				- 8-bit, no parity, 1 stop bit
				- no handshake
				- echo off

Purpose:		Illustration of UART usage
				- Autobaud Detection using GP Timer 2	 
				- Polling Operation
				- Interrupt Operation
				

******************************************************************************/

 
#include <defBF533.h>
#include "uartlib.h"
#include "sicnames.h"


/*****************************************************************************
 *
 *  Example requires a simple hello-world string.
 *  Initialize on-chip SRAM at boot time accordingly.  
 *
 ****************************************************************************/ 

.section data1;

.byte sHead[] = 13,10,'-------------------------------',
                13,10,'ADSP-BF533 Blackfin is speaking',
                13,10,'(DL =',0;
.byte sTail[] = ')',
                13,10,'-------------------------------',
                13,10,0;
.byte sEcho[] =       'Type any character. The Blackfin UART',                
                13,10,'returns the echo> ',0;

.align 4;                                
.var aEchoFifo[16];                

/*****************************************************************************
 *
 *  Main program starts here!
 *
 ****************************************************************************/ 

.section L1_code;
.global _main;
_main:

	[--sp] = rets;
	

/*****************************************************************************
 *
 *  First of all, initialize p0 to UART_GCTL register address.
 *  p0 must not be changed within this example
 *
 ****************************************************************************/ 
	
 	p0.l = lo(UART_GCTL);
	p0.h = hi(UART_GCTL);
		
	call uart_autobaud;
	
	
/*****************************************************************************
 *
 *  r0 holds the timer period value, now.
 *  Apply formula DL = PERIOD / (16 x 8 bits) and call uart_init that writes
 *  the result to the two 8-bit DL registers (DLH:DLL).
 *
 ****************************************************************************/ 

 	r0 >>= 7;	
 	
 	call uart_init;
  
 	
/*****************************************************************************
 *
 *  Transmit a Hello World string and the content of the DL registers.
 *
 ****************************************************************************/ 
		
	p1.l = sHead;
	p1.h = sHead;
	call uart_puts;
	
	
/*****************************************************************************
 *
 *  Note that r0 still contains the DLH:DLL value 
 *
 ****************************************************************************/ 
		
	call uart_putreg;
	
	p1.l = sTail;
	p1.h = sTail;
	call uart_puts;
	
/*****************************************************************************
 *
 *  Wait until operation has finished completely. This is optional.
 *
 ****************************************************************************/ 

	call uart_wait4temt;
	

/*****************************************************************************
 *
 *  Transmit another string, but use interrupt mode, this time.
 *  First TX interrupt channel must be assigned and enabled.
 *  Assign to EVT9.
 *
 *  p3 points to the NULL-terminated string.
 *
 *  Important: if you enable all three UART interrupts channels, it is
 *  recommended to keep this order of priorities:
 *  PRIORITY(Error) >= PRIORITY(RX) >= PRIORITY(TX)
 *
 ****************************************************************************/ 	
 
	p1.l = lo(IMASK);
	p1.h = hi(IMASK);
	
	p3.l = sEcho;
	p3.h = sEcho;

/*****************************************************************************
 *
 *  Register TX service routine at EVT9. 
 *
 ****************************************************************************/ 	
		
	r0.l = isr_uart_tx;
	r0.h = isr_uart_tx;
	[p1 + EVT9 - IMASK] = r0;

/*****************************************************************************
 *
 *  Unmask EVT9 interrupt.
 *
 ****************************************************************************/ 	
	
	r0 = [p1 + IMASK - IMASK];
	bitset(r0, bitpos(EVT_IVG9));
	[p1 + IMASK - IMASK] = r0;
	

/*****************************************************************************
 *
 *  Enable UART TX interrupt and assign it to EVT9.
 *  Constants used below are defined in "sicnames.h" header.
 *
 ****************************************************************************/ 	
		
	p1.l = lo(SIC_IMASK);
	p1.h = hi(SIC_IMASK);	
			
	r0.l = lo(IVG_SPT0_ERROR(15) | IVG_PPI_ERROR(15)  | IVG_DMA_ERROR(15)  | IVG_PLL_WAKEUP(15));
	r0.h = hi(IVG_RTC(15)        | IVG_UART_ERROR(15) | IVG_SPT1_ERROR(15) | IVG_SPI_ERROR(15));	
	[p1 + SIC_IAR0 - SIC_IMASK] = r0;	
	r0.l = lo(IVG_SPT1_RX(15)    | IVG_SPT0_TX(15)    | IVG_SPT0_RX(15)    | IVG_PPI(15));
	r0.h = hi(IVG_UART_TX( 9)    | IVG_UART_RX(16)    | IVG_SPI(15)        | IVG_SPT1_TX(15));	
	[p1 + SIC_IAR1 - SIC_IMASK] = r0;			
	r0.l = lo(IVG_PFA(15)        | IVG_TIMER2(15)     | IVG_TIMER1(15)     | IVG_TIMER0(15));
	r0.h = hi(IVG_SWDT(15)       | IVG_MEMDMA1(15)    | IVG_MEMDMA0(15)    | IVG_PFB(15));	
	[p1 + SIC_IAR2 - SIC_IMASK] = r0;
			
	r0.l = lo(IRQ_UART_TX);
	r0.h = hi(IRQ_UART_TX);
	[p1 + SIC_IMASK - SIC_IMASK] = r0;

/*****************************************************************************
 *
 *  Enable Interrupt Nesting.
 *
 ****************************************************************************/ 	
			
	[--sp] = reti;	


/*****************************************************************************
 *
 *  Finally enable interrupts inside UART module, by setting proper bits
 *  in the IER register. It is good programming style to clear potential
 *  UART interrupt latches in advance, by reading RBR, LSR and IIR.
 *
 *  Setting the ETBEI bit automatically fires a TX interrupt request. 
 *
 ****************************************************************************/ 	
		
	r0 = w[p0+UART_RBR-UART_GCTL] (z);
	r0 = w[p0+UART_LSR-UART_GCTL] (z);
	r0 = w[p0+UART_IIR-UART_GCTL] (z);
				
	r0 = ETBEI;
	w[p0+UART_IER-UART_GCTL] = r0;	
	
 
/*****************************************************************************
 *
 *  Wait until operation has finished completely. Again, this is optional.
 *
 ****************************************************************************/ 
 
	call uart_wait4temt;	 
 
			
/*****************************************************************************
 *
 *  Disable UART TX interrupt again, and enable UART RX interrupt and UART 
 *  Line Error Interrupt.
 *  Simply echo all received characters back to TX. 
 *
 *  Disable nesting during the setup.
 *
 ****************************************************************************/ 	
	
	reti = [sp++];	
	
	p1.l = lo(IMASK);
	p1.h = hi(IMASK);
	
/*****************************************************************************
 *
 *  i0 and i1 are used to implement a little FIFO
 *
 ****************************************************************************/ 		
	
	i0.l = aEchoFifo;
	i0.h = aEchoFifo;
	
	i1 = i0;	
	b0 = i0;
	b1 = i0;
	l0 = length(aEchoFifo);
	l1 = l0;

/*****************************************************************************
 *
 *  Register RX service routine at EVT8 and error routine to EVT7. 
 *
 ****************************************************************************/ 	
		
	r0.l = isr_uart_error;
	r0.h = isr_uart_error;
	[p1 + EVT7 - IMASK] = r0;
	
	r0.l = isr_uart_rx;
	r0.h = isr_uart_rx;
	[p1 + EVT8 - IMASK] = r0;	

/*****************************************************************************
 *
 *  Mask EVT9 interrupt and unmask EVT7 and EVT8.
 *
 ****************************************************************************/ 	
	
	r0 = [p1 + IMASK - IMASK];
	bitclr(r0, bitpos(EVT_IVG9));
	bitset(r0, bitpos(EVT_IVG7));
	bitset(r0, bitpos(EVT_IVG8));
	[p1 + IMASK - IMASK] = r0;
	

/*****************************************************************************
 *
 *  Enable and assign interrupts.
 *
 ****************************************************************************/ 	
		
	p1.l = lo(SIC_IMASK);
	p1.h = hi(SIC_IMASK);	
			
	r0.l = lo(IVG_SPT0_ERROR(15) | IVG_PPI_ERROR(15)  | IVG_DMA_ERROR(15)  | IVG_PLL_WAKEUP(15));
	r0.h = hi(IVG_RTC(15)        | IVG_UART_ERROR( 7) | IVG_SPT1_ERROR(15) | IVG_SPI_ERROR(15));	
	[p1 + SIC_IAR0 - SIC_IMASK] = r0;	
	r0.l = lo(IVG_SPT1_RX(15)    | IVG_SPT0_TX(15)    | IVG_SPT0_RX(15)    | IVG_PPI(15));
	r0.h = hi(IVG_UART_TX(15)    | IVG_UART_RX( 8)    | IVG_SPI(15)        | IVG_SPT1_TX(15));	
	[p1 + SIC_IAR1 - SIC_IMASK] = r0;			
	r0.l = lo(IVG_PFA(15)        | IVG_TIMER2(15)     | IVG_TIMER1(15)     | IVG_TIMER0(15));
	r0.h = hi(IVG_SWDT(15)       | IVG_MEMDMA1(15)    | IVG_MEMDMA0(15)    | IVG_PFB(15));	
	[p1 + SIC_IAR2 - SIC_IMASK] = r0;
			
	r0.l = lo(IRQ_UART_RX | IRQ_UART_ERROR);
	r0.h = hi(IRQ_UART_RX | IRQ_UART_ERROR);
	[p1 + SIC_IMASK - SIC_IMASK] = r0;	
 
 
 /*****************************************************************************
 *
 *  Enable Interrupt Nesting.
 *
 ****************************************************************************/ 	
			
	[--sp] = reti;	

 
/*****************************************************************************
 *
 *  Finally enable interrupts inside UART module, by setting proper bits
 *  in the IER register. It is good programming style to clear potential
 *  UART interrupt latches in advance, by reading RBR, LSR and IIR.
 *
 ****************************************************************************/ 	
		
	r0 = w[p0+UART_RBR-UART_GCTL] (z);
	r0 = w[p0+UART_LSR-UART_GCTL] (z);
	r0 = w[p0+UART_IIR-UART_GCTL] (z);
				
	r0 = ELSI | ERBFI;
	w[p0+UART_IER-UART_GCTL] = r0;	

	
/*****************************************************************************
 *
 *  The following endless loop tests whether data is ready in the aEchoFifo
 *  and trasnmits it, if required. The FIFO is filled by the UART RX ISR.
 *
 ****************************************************************************/ 	
		
echo:
	
	r0 = i0;
	r1 = i1;
	CC = r0 == r1;
	if CC jump echo;
	
		r0 = [i1++];
		call uart_putc;

	jump echo;
	

_main.end: nop;	
	


/*****************************************************************************
 *
 *  UART TX Interrupt Service Rouine.
 *
 *  Load next byte from p3 pointer and moves it to THR register until
 *  p3 points to NULL character. Note that a write to THR clears the
 *  TX interrupt request.
 *
 ****************************************************************************/ 

isr_uart_tx:
	
	[--sp] = r0;

	r0 = b[p3++] (z);
	CC = r0 == 0;
	
	if CC jump isr_tx_done;
	
	w[p0+UART_THR-UART_GCTL] = r0;	

	r0 = [sp++];
	
	nop;
	
	ssync;
	rti;		
	
/*****************************************************************************
 *
 *  Once a NULL character was detected, the transmission should stop.
 *  There is a need to clear the TX interrupt request. Since we don't
 *  want to write to THR again, we can clear the request by reading the
 *  IIR register. Note that system design needs to ensure that neigher
 *  an UART RX or Line Status interrupt should be pending!
 *
 *  Note the double ssync instruction, required due to system latencies.
 *
 ****************************************************************************/ 	
	
isr_tx_done:

	r0 = w[p0+UART_IIR-UART_GCTL] (z); 
	
	r0 = [sp++];
	
	ssync;
	ssync;	

	rti;		

isr_uart_tx.end:	

	
/*****************************************************************************
 *
 *  UART RX Interrupt Service Rouine.
 *
 *  When new data is received this ISR puts the new data into the aEchoFifo.
 *  Special handling is required for carriage return and backspace.
 *
 *  Note that reading RBR clears the interrupt request.
 *
 ****************************************************************************/ 

isr_uart_rx:
	
	[--sp] = r0;
	[--sp] = r1;

	r0 = w[p0+UART_RBR-UART_GCTL] (z);
		
	[i0++] = r0;
	
	r1 = 8;		// backspace
	CC = r0 == r1; 
	if !CC jump isr10;
	
		r1 = 32 (z); // blank
		[i0++] = r1;
		
		r1 = 8 (z); // another backspace
		[i0++] = r1;
	
isr10:	
	
	r1 = 13;	// carriage return
	CC = r0 == r1; 
	if !CC jump isr20;
	
		r1 = 10 (z); // line feed
		[i0++] = r1;
		
isr20:
	
	r1 = [sp++];
	r0 = [sp++];
	
	ssync;
	rti;
	
isr_uart_rx.end:	



/*****************************************************************************
 *
 *  UART Error/Line Status Interrupt Service Rouine.
 *
 *  If an error is reported by the UART Line Status, then this ISR reads
 *  the LSR register to determine the cause of the error (and to clear the
 *  interrupt request).
 *
 *  To indicate the error a 0xFF character will be written to the FIFO. 
 *
 ****************************************************************************/ 
			
isr_uart_error:

	[--sp] = r0;	
	
	r0 = w[p0+UART_LSR-UART_GCTL] (z);
		
	r0 = 0xFF (z);
	[i0++] = r0;
	
	r0 = [sp++];
	ssync;
	rti;	

isr_uart_error.end:		
	
		

⌨️ 快捷键说明

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