S3C2440——Using URAT0 interrupt mode to send and receive character strings

  • Set interrupt vector table

    ;文件ASM_Interrupt.s
    ;(1)设置中断向量表
    Mode_USR	EQU     0x50	;IRQ中断开放,FIQ中断关闭
    Mode_FIQ 	EQU     0xD1	;关闭IRQ、FIQ中断
    Mode_IRQ	EQU     0xD2	;关闭IRQ、FIQ中断
    Mode_SVC 	EQU     0xD3	;关闭IRQ、FIQ中断
    
    		GET	2440Reg_addr.inc
        	AREA    MyCode, CODE,READONLY
            IMPORT Uart_Init
    		IMPORT INT_UART0
        	ENTRY				;设置中断向量表
    		B	ResetHandler		;Reset中断服务程序
    		B	.			;handlerUndef
    		B	.			;SWI interrupt handler
    		B	.			;handlerPAbort
    		B	.			;handlerDAbort
    		B	.			;handlerReserved
    		B	HandlerIRQ		;HandlerIRQ
    		B	.			;HandlerFIQ
    
    ;(2)复位的中断处理程序
    ResetHandler
    		BL	Clock_Init		;初始化看门狗、时钟
    		;BL	MemSetup		;初始化SDRAM
     		LDR     	SP, =SvcStackSpace	;设置管理模式堆栈
            MSR	CPSR_c, #Mode_IRQ
            LDR	SP, =IrqStackSpace	;设置IRQ中断模式堆栈
            MSR	CPSR_c, #Mode_FIQ
            LDR	SP, =FiqStackSpace	;设置FIQ中断模式堆栈
            MSR	CPSR_c, #Mode_USR	;进入用户模式
    		LDR	SP, =UsrStackSpace	;设置用户与系统模式堆栈
     		;BL	Init_DATA		;初始化可读写数据
    
            LDR R0,=pclk    ;PCLK、波特率
            LDR R1,=baud
    
            BL Uart_Init ;清除三个挂起寄存器,打开总中断和收发中断寄存器
    
            ;各种中断控制器已经设置好
            ;但需要解决:当进入中断服务程序HandlerIRQ后执行哪段程序的问题
    		LDR	R0,=pINT_UART0  ;INT_UART0在中断入口散转表中的地址
    		LDR	R1,=INT_UART0	;R1中断服务程序入口地址
    		STR	R1,[R0]		;EINT8_23中断程序入口地址写入中断散转表
    MAIN_LOOP
     		NOP
    		B      	MAIN_LOOP	;死循环,被IRQ中断;初始化可读写数据区
    Clock_Init
    		GET	Clock_Init.s		;初始化看门狗、时钟
    MemSetup
    		GET	MemSetup.s		;初始化SDRAM
    Init_DATA
    		GET	Init_DATA.s		;初始化可读写数据区
    
    ;(3)IRQ中断处理程序
    HandlerIRQ
    		SUB	LR,LR, #4		;计算返回地址
        	STMFD	SP!, {LR}		;保存断点到IRQ模式的堆栈
    		LDR	LR,= Int_Return 	;修改LR,执行完INT_UART0的处理程序后返回到Int_Return处
            LDR R0,=INTSUBMSK   ;屏蔽发送和接收中断
            LDR R1,[R0]
            ORR R1,R1,#0x3
            STR R1,[R0]
    		LDR	R0,=INTOFFSET		;取得中断源的编号
    		LDR	R1,[R0]
    		LDR	R2,=Int_EntryTable	;中断散转表起始地址
    		LDR	PC,[R2,R1,LSL#2]	;查中断散转表,取得INT_UART0的处理程序入口地址,相当于无参的子程序调用,但没保存断点
    Int_Return			;执行完INT_UART0的处理程序后须返回此处
            LDR R0,=INTSUBMSK   ;打开发送和接收中断
            LDR R1,[R0]
            MVN R2,#0x3
            and R1,R1,R2
            STR R1,[R0]
    		LDMFD  	SP!, {PC }^	;IRQ中断服务程序返回, ^表示将SPSR的值复制到CPSR
    
    		 AREA    MyRWData, DATA, READWRITE	;设置RW Base=0x33ffe700
    Int_EntryTable
    		GET	Int_EntryTable.s		;中断散转表,共32个入口
            	AREA    MyZIData, DATA, READWRITE, NOINIT,ALIGN=8
    ;下推式堆栈,根据对齐方式,段起始地址为0x33ffe800,各栈区空间均为1k
    			SPACE	0x100 * 4	;管理模式堆栈空
    SvcStackSpace	SPACE	0x100 * 4	;中断模式堆栈空间
    IrqStackSpace	SPACE	0x100 * 4	;快速中断模式堆栈空间
    FiqStackSpace	SPACE	0x100 * 4
    UsrStackSpace
    		END
    
    ;文件Int_EntryTable.s,定义中断散转表
    ;共32路,对应仲裁器32路输入
    pEINT0		DCD  0		;存放EINT0-3中断服务程序入口地址
    pEINT1		DCD  0
    pEINT2		DCD  0
    pEINT3		DCD  0
    
    pEINT4_7	DCD  0 		;存放EINT4_7中断服务程序入口地址
    pEINT8_23	DCD  0	;存放EINT8_23中断服务程序入口地址——EINT8_23
    
    pINT_CAM	DCD  0		;存放26个内部中断服务程序入口地址
    pnBATT_FLT	DCD  0
    pINT_TICK 	DCD  0
    pINT_WDT_AC97	DCD  0
    ……
    pINT_UART0  DCD  0
    pINT_SPI1   DCD  0
    pINT_RTC 	DCD  0
    pINT_ADC	DCD  0
    			END
    
  • test program

    #include "2440Reg_addr.h"
    #define WrUTXH0(ch)  ( * (volatile unsigned char * )0x50000023)=(unsigned char)(ch)
    char[100] string1;
    char[100] string2;
    int flag1=0;
    int flag2=0;
    int UART_INT_SET(void)
    {
          
          
        rSRCPND|=0x1<<28;//清除串口中断挂起SPCPNG[28]
        rSUBSRCPND|=0x3;//清除收发中断SUBSRCPND[1:0]
        rINTPND|=0x1<<28;//清除串口中断请求
    
        //打开总中断屏蔽和收发中断屏蔽
        rINTMSK&=~(0x1<<28);
        rINTSUBMSK&=~(0x3);
        return 0;
    }
    void Uart_Init(int pclk,int baud)
    {
          
          
        int i;
        rGPHCON|=0xa0; //GPH2,GPH3 as TXD0,RXD0
        rGPHUP = 0x0;    //GPH2,GPH3内部上拉
        if(pclk == 0)
        pclk = PCLK;
        rUFCON0 = 0x0; //禁止3个通道的FIFO控制寄存器
        rUFCON1 = 0x0;
        rUFCON2 = 0x0;
        rUMCON0 = 0x0;
        rUMCON1 = 0x0;
        rUMCON2 = 0x0;    //初始化3个通道的MODEM控制寄存器,禁止AFC
        //Line control register 0: Normal,No parity,1 stop,8 bits.
        rULCON0=0x3;
        // Control register 0
        rUCON0  = 0x325;//rUCN0[9:8]=11 rUCN0[5]=1 rUCN0[3:2]=01 rUCN0[1:0]=01
        //Baud rate divisior register 0
        UART_INT_SET();
        rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );
    }
    
    void INT_UART0()
    {
          
          
        int oft=rSUBSRCPND;
        switch (oft)
        {
          
          
        case 0x0040:{
          
          
            char c;
            if((c = Uart_Getch())!='\r'){
          
          
                string1[flag1];
                flag1++;
            }
            break;
        }
        case 0x0080:{
          
          
            char c;
            if(c=string2[flag2]!='\r'){
          
          
                Uart_SendByte(c);
                flag2++;
            }
            break;
        }
        case 0x0100:{
          
          
            Uart_Getch();
            break;
        }
        default:
            break;
        }
        rSRCPND = rSRCPND;	//清除SRCPND寄存器
    	rSUBSRCPND = rSUBSRCPND;	//清除EINTPEND寄存器
    	rINTPND = rINTPND;	//清除INTPND寄存器
    }
    //发送一字节
    //#define WrUTXH0(ch)  ( * (volatile unsigned char * )0x50000023)=(unsigned char)(ch)
    void Uart_SendByte(int data)
    {
          
          
        WrUTXH0(data);
    }
    
    //接收一字节数据
    char Uart_Getch(void)
    {
          
          
        return RdURXH0;  //0x50000027
    }
    
  • 2410addr.h defines the header file of each register of UART

    //2410addr.h  定义UART各个寄存器的头文件
    #define rULCON0 ( * (volatile unsigned * )0x50000000)  //UART 0 Line control
    #define rUCON0 ( * (volatile unsigned * )0x50000004)  //UART 0 control
    #define rUFCON0 ( * (volatile unsigned * )0x50000008)  //UART 0 FIFO control
    #define rUMCON0 ( * (volatile unsigned * )0x5000000c)  //UART 0 Modem control
    #define rUTRSTAT0 ( * (volatile unsigned * )0x50000010)  //UART 0 Tx/Rx status
    #define rUERSTAT0 ( * (volatile unsigned * )0x50000014)  //UART 0 Rx error status
    #define rUFSTAT0 ( * (volatile unsigned * )0x50000018)  //UART 0 FIFO status
    #define rUMSTAT0 ( * (volatile unsigned * )0x5000001c)  //UART 0 Modem status
    #define rUBRDIV0 ( * (volatile unsigned * )0x50000028)  //UART 0 Baud rate diviaor
    #define rULCON1 ( * (volatile unsigned * )0x50004000)  //UART 1 Line control
    #define rUCON1 ( * (volatile unsigned * )0x50004004)  //UART 1 Control
    #define rUFCON1 ( * (volatile unsigned * )0x50004008)  //UART 1 FIFO control
    #define rUMCON1 ( * (volatile unsigned * )0x5000400c)  //UART 1 Modem control
    #define rUTRSTAT1  ( * (volatile unsigned * )0x50004010)  //UART 1 Tx/Rx status
    #define rUERSTAT1  ( * (volatile unsigned * )0x50004014)  //UART 1 Rx error status
    #define rUFSTAT1 ( * (volatile unsigned * )0x50004018)  //UART 1 FIFO status
    #define rUMSTAT1  ( * (volatile unsigned * )0x5000401c)  //UART 1 Modem status
    #define rUBRDIV1  ( * (volatile unsigned * )0x50004028)  //UART 1 Baud rate divisor
    #define rULCON2  ( * (volatile unsigned * )0x50008000)  //UART 2 Line control
    #define rUCON2 ( * (volatile unsigned * )0x50008004)  //UART 2 Control
    #define rUFCON2 ( * (volatile unsigned * )0x50008008)  //UART 2 FIFO control
    #define rUMCON2 ( * (volatile unsigned * )0x5000800c)   //UART 2 Modem control
    #define rUTRSTAT2  ( * (volatile unsigned * )0x50008010)  //UART 2 Tx/Rx status
    #define rUERSTAT2  ( * (volatile unsigned * )0x50008014)  //UART 2 Rx error status
    #define rUFSTAT2 ( * (volatile unsigned * )0x50008018)  //UART 2 FIFO status
    #define rUMSTAT2  ( * (volatile unsigned * )0x5000801c)  //UART 2 Modem status
    #define rUBRDIV2  ( * (volatile unsigned * )0x50008028)  //UART 2 Baud rate divisor
    #if def_BIG_ENDIAN
    #define rUTXH0  ( * (volatile unsigned char * )0x50000023)  //UART 0 Transmission Hold
    #define rURXH0  ( * (volatile unsigned char * )0x50000027)  //UART 0 Receive buffer
    #define rUTXH1  ( * (volatile unsigned char * )0x50004023)  //UART 1 Transmission Hold
    #define rURXH1  ( * (volatile unsigned char * )0x50004027)  //UART 1 Receive buffer
    #define rUTXH2  ( * (volatile unsigned char * )0x50008023)  //UART 2 Transmission Hold
    #define rURXH2  ( * (volatile unsigned char * )0x50008027)  //UART 2 Receive buffer
    #define WrUTXH0(ch)  ( * (volatile unsigned char * )0x50000023)=(unsigned char)(ch)
    #define RdURXH0  ( * (volatile unsigned char * )0x50000027)
    #define WrUTXH1(ch)  ( * (volatile unsigned char * )0x50004023)=(unsigned char)(ch)
    #define RdURXH1()  ( * (volatile unsigned char * )0x50004027)
    #define WrUTXH20(ch)  ( * (volatile unsigned char * )0x50008023)=(unsigned char)(ch)
    #define RdURXH2()  ( * (volatile unsigned char * )0x50008027)
    #define UTXH0     (0x50000020+3)  //Byte_access address by DMA
    #define URXH0     (0x50000024+3)
    #define UTXH1     (0x50004020+3)
    #define URXH1     (0x50004024+3)
    #define UTXH2     (0x50008020+3 )
    #define URXH2     (0x50008024+3)
    #else//Little Endian
    #define rUTXH0  ( * (volatile unsigned char * )0x50000020)//UART 0 Transmission Hold
    #define rURXH0  ( * (volatile unsigned char * )0x50000024)//UART 0 Receive buffer
    #define rUTXH1  ( * (volatile unsigned char * )0x50004020)//UART 1 Transmission Hold
    #define rURXH1  ( * (volatile unsigned char * )0x50004024)//UART 1 Receive buffer
    #define rUTXH2  ( * (volatile unsigned char * )0x50000820)//UART 2 Transmission Hold
    #define rURXH2  ( * (volatile unsigned char * )0x50008024)//UART 2 Receive buffer
    #define WrUTXH0(ch)  ( * (volatile unsigned char * )0x50000020)=(unsigned char)(ch)
    #define RdURXH0  ( * (volatile unsigned char * )0x50000024)
    #define WrUTXH1(ch)  ( * (volatile unsigned char * )0x50004020)=(unsigned char)(ch)
    #define RdURXH1()  ( * (volatile unsigned char * )0x50004024)
    #define WrUTXH2(ch)  ( * (volatile unsigned char * )0x50008020)=(unsigned char)(ch)
    #define RdURXH2()  ( * (volatile unsigned char * )0x50008024)
    #define UTXH0     (0x50000020+3)  //Byte_access address by DMA
    #define URXH0     (0x50000024+3)
    #define UTXH1     (0x50004020+3)
    #define URXH1     (0x50004024+3)
    #define UTXH2     (0x50008020+3 )
    #define URXH2     (0x50008024+3)
    #endif
    

Guess you like

Origin blog.csdn.net/qq_49588762/article/details/118674044