1.相关原理图

2.相关寄存器介绍与配置

 

    1)与管脚相关

 

①GPHCON

 

注:

配置成UART0功能:

GPHCON |= 10 10 10 10b(还要在GPHUP里把管脚禁止上拉)

 

    2)与中断相关

上传图片好麻烦,跟以前相关的这里就不贴了

 

    3)与UART0相关

①ULCON0   

注:

Infrared Mode :选择普通模式

Parity Mode : 选择不执行奇偶校验

Number of stop :选择1个结束位

Word length :8-bits字长

ULCON0 = 0x03

 

②UBRDIV0和UCON0

注:

UBRDIVn      =  (int)(UART clock /(baud rate * 16)) - 1,因为下面我们选择了PCLK作为UARTclock。所以UBRDIV0=(int)PCLK/(baudrate*16)) - 1。其中PCLK=101.25MHz,波特率选择115200

UBRDIV0=(int)(     101250000/(115200*16)   ) - 1 = 54.

选择UBRDIV0= 0x36

 

注:

Clock selection :时钟源选择,选择PCLK,根据上个定时器实验得知PCLK使用101.25MHz。00b

 


脉冲触发:指的是在Tx buffer从有数据跳变为空时(对于接收模式来说,则是Rx buffer从空跳变为有数据)触发一次边沿中断,之后即使为空,但是没有这个跳变是不会触发中断的(Non-FIFO)。对于使用FIFO来说,一旦到达Tx/Rx FIFO的触发水平时才产生一个边沿中断,其它时候都不会触发中断。

 

水平触发:指的是只要Tx buffer为空(对于接收模式来说,则是只要Rx buffer有数据)则一直产生中断请求 (电平中断)。对于使用FIFO来说,只要是高于(接收模式)/低于(发送模式)或等于触发水平就一直产生中断(电平中断)。

   

①如果发送中断采用了脉冲触发,在发送中断处理里执行太长时间的情况下,导致下个脉冲中断请求在中断处理函数里产生了,那么如果请求中断请求位是在后面清除的,则会引起下个脉冲中断请求被清除了而无法再次进入发送中断(因为数据已经被发送出去了,则不会再达到触发水平(FIFO)或者从从有数据到空的跳变(non-FIFO))。而如果是采用水平触发则不会发生这种情况,因为只要是空的(non-FIFO)或低于等于触发水平(FIFO),即便被清除了请求位,还是会产生请求,但是这样会连绵不断的触发中断。

②如果接收中断采用了脉冲触发,在接收中断处理里执行太长时间的情况下,也会导致下一个脉冲中断请求在中断处理函数里产生了,那么如果请求中断请求位是在后面清除的,则会引起下个脉冲中断请求被清除了而无法再次进入发送中断(因为之前的数据还没被取出,则不会再达到触发水平(FIFO)或者从空到有数据的跳变(non-FIFO))。而如果是采用水平触发则不会发生这种情况,因为只要有数据(non-FIFO)或高于等于触发水平(FIFO),即便被清除了请求位,还是会产生请求,但是这样会连绵不断的触发中断。

 

举个栗子:

①只使能发送中断,选择FIFO,触发水平为empty,在发送中断里发送一个字节,延迟3秒,这段时间足够让Tx FIFO里从一个数据跳变到empty(2),即发送中断请求(1)在中断处理函数里产生了。

·使用脉冲触发:退出中断处理函数清除了中断请求,也就把(1)给清掉了,进不了发送中断无法给数据,并且Tx FIFO一直为空(无法出现(2)) , 因此不再产生中断。

·使用水平触发:退出中断处理函数清除了中断请求,也把(1)给清掉了,但是只要是低于或等于empty在FIFO里,则电平中断还会产生,能够再次进入中断。

 

②只使能接收中断,选择FIFO,触发水平为1-byte,PC机上发一个字节触发中断,在接收中断里接收一个字节,延迟3秒,在这段时间里再发1个字节,这样会有一个从empty到1-byte的跳变(2),这样就在中断服务函数里产生了中断请求,即接收中断请求(1)在中断处理函数里产生了。

·使用脉冲触发:退出中断处理函数清除了中断请求,也就把(1)给清掉了,进不了接收中断无法取出数据,并且Rx FIFO一直1-byte数据(无法出现(2)) ,因此不再产生中断。

·使用水平触发:退出中断处理函数清除了中断请求,也把(1)给清掉了,但是只要是高于或等于1-byte数据在FIFO里,则电平中断还会产生,能够再次进入中断。

经测试成立。

Tx interrupt type :保险点选择水平触发就行了,不过这个我们只在需要发送数据再打开,发送完数据再关闭,这样就防止老是进入中断。1b

Rx interrupt type :同理 ,选择水平触发就好了,只要有数据就进入中断处理数据。1b

Rx timeout enable :选择禁止。0b

Rx error status interrupt enable :禁止接收错误状态中断。0b

Loopback mode :选择普通模式。0b

Send break signal :选择正常传输。0b

注:

Transmit mode :选择中断请求或者轮询模式。01b

Receive mode :选择中断模式或者轮询模式。01b

UCON0  = 0x305

 

③UFCON0

注:

Tx FIFO trigger level :选择emply,只有在FIFO到达空了才会触发中断。00b

Rx FIFO trigger level :选择1-bype,这样只要接收到1个字节就直接进入中断取出处理。00b

Tx FIFO reset :选择normal。0b

Rx FIFO reset :选择normal。0b

FIFO enable :使能FIFO。1b

UFCON0 = 0x01

 

④UMCON0

注:

AFC flow control:不使能自动流控。0b

Request to send:不使能自动流控,这个位也不需要用到

初始化时:UMCON0 = 0;

 

⑤UTRSTAT0

注:只读

Transmitter empty:当发送缓冲寄存器(FIFO)已经没有有效数据可以发送并且发送数据移位器为空。该域会被置为‘1’。

Transmit buffser empty:当发送缓冲寄存器空时被置为‘1’。(只针对于Non-FIFO,Tx FIFO模式需要检测UFSTAT寄存器的count 位和Tx FIFO Full 位)

Receive buffer data ready:当接收缓冲寄存器包含了从PXDn端口接收到的有效数据时被设置为‘1’。(只针对于Non-FIFO,Rx FIFO模式需要检测UFSTAT寄存器的count位和Rx FIFO Full 位)

 

⑥UERSTAT0

注:(当这个状态寄存器被读取时会自动清零)

Break detect:当一个break 信号被接收到了这个位会被置‘1’。

Frame Error :当一个帧错误在接收操作期间产生时被置‘1’。

Parity error :当一个奇偶校验错误在接收期间产生时被置‘1’。

Overrun error:当一个overrun错误在接收期间产生时被置‘1’。

 

⑦UFSTAT0

注:

Tx FIFO full :当发送FIFO在发送期间满了,这个位会被置‘1’。

Tx FIFO count :Tx FIFO里的data数。

Rx FIFO Full :当接收FIFO在接收期间满了,这个位会被置‘1’。

Rx FIFO count :Rx FIFO里的data数。

 

⑧UMSTAT0

注:

Delta CTS:指明了nCTS输入到S3C2440A状态是否改变了知道该位被CPU读取了才自动清零。

Clear to send:要发送数据时需要检查该位是否有效,有效才可以写数据到Tx FIFO。

这两个都用在自动流控功能里。如果双方都不使用自动流控。这个也可以不管。

 

 

⑨UTXH0(UART0发送缓冲寄存器)

注:

TXDATA0:存放用户要发送的数据

 

⑩URXH0(UART0接收缓冲寄存器)

注:

(当overrun error发生时,URXH0必须被读出,否则,下一个接收到的数据也会造成overrun error尽管UERSTAT0的overrun位已经被清除了)

RXDATA:存放接收到的数据

 

 

3.流程图设计

 

    ①主流程图

                                                                       

    ②中断处理子程序

                                                                             

    ③中断服务子

4.程序设计

 

     ①Makefile

uart0.bin : head.o demoUart0.o

    arm-linux-ld -Tuart0.lds -o uart0_elf $^

    arm-linux-objcopy -O binary -S uart0_elf $@

    arm-linux-objdump -D -m arm uart0_elf > uart0.dis


%.o : %.S

    arm-linux-gcc -Wall -c -o $@ $<


%.o : %.c

    arm-linux-gcc -Wall -c -o $@ $<

clean:

    rm -f uart0.dis uart0.bin uart0_elf *.o *.bak 

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

     ②uart0.lds

SECTIONS { 

    first    0x00000000 : { head.o }

    second    0x30000000 : AT(2048) { demoUart0.o }

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

       ③head.S

 

@与内存相关

.equ    BWSCON   ,    0x48000000

.equ    BANKCON6 ,     0x4800001C

.equ    REFRESH  ,    0x48000024

.equ    BANKSIZE ,    0x48000028

.equ    MRSRB6     ,    0x4800002C


@与中断相关

.equ    INTMSK    ,    0x4A000008

.equ  INTSUBMSK    ,    0x4A00001C

.equ  SUBSRCPND ,    0x4A000018

.equ    SRCPND    ,    0x4A000000

.equ    INTPND    ,    0x4A000010


@与看门狗相关

.equ    WTCON    ,    0x53000000


@与管脚配置相关的

.equ    GPHCON    ,    0x56000070

.equ    GPHUP    ,    0x56000078


@与UART0配置相关的

.equ    ULCON0    ,    0x50000000

.equ    UBRDIV0    ,    0x50000028

.equ    UCON0   ,    0x50000004

.equ    UFCON0    ,    0x50000008

.equ    UMCON0    ,    0x5000000C

.equ   UTRSTAT0    ,    0x50000010    @read-only

.equ   UERSTAT0    ,    0x50000014

.equ    UFSTAT0    ,    0x50000018

.equ    UMSTAT0    ,    0x5000001C

.equ    UTXH0    ,    0x50000020    @little-endian

.equ    URXH0    ,    0x50000024    @little-endian


@时钟相关寄存器

.equ    MPLLCON    ,    0x4C000004

.equ    UPLLCON    ,    0x4C000008

.equ    CLKDIVN    ,    0x4C000014

.equ    CAMDIVN ,    0x4C000018


@与灯光配置相关的

.equ    GPBCON    ,    0x56000010

.equ    GPBDAT    ,    0x56000014


.text

.global _start

_start:

/***********设置中断向量表*************/

    b    ResetInit    @复位异常入口

HandlerUndef:

    b    HandlerUndef    @未定义异常入口

HandlerSWI:

    b    HandlerSWI    @软中断异常入口

HandlerPabort:

    b    HandlerPabort    @取指中止异常入口

HandlerDabort:

    b    HandlerDabort    @数据中止异常入口

HandlerNotUsed:

    b    HandlerNotUsed    @保留


    b    HandlerIRQ    @中断异常入口

HandlerFIQ:

    b    HandlerFIQ    @快中断异常入口

/************END设置中断向量表***********/


ResetInit:

/*************关闭看门狗****************/

    ldr    r0 , =WTCON

    mov    r1 , #0x0

    str    r1 , [r0]

/************END关闭看门狗**************/


/**********初始化LED灯管脚************

    @把LED1-4管脚置为输出

    ldr    r0 , =GPBCON

    ldr    r1 , [r0]        @把GPBCON里的内容加载到r1里

    ldr    r2 , =(0xFF<<10)

    bic    r1 , r1 ,r2    @操作数取反码或上r1,用于清零工作

    ldr    r2 , =(0x55<<10)

    orr    r1 , r1 , r2 

    str    r1 , [r0]

    

    ldr    r0 , =GPBDAT

    ldr    r1 , [r0]    

    ldr    r2 , =(0x0F<<5)

    bic    r1 , r1 , r2

    orr    r1 , r1 , r2

    str    r1 , [r0]

***********END***************/    


/**********初始化相关管脚为UART0功能************/

    ldr    r0 , =GPHCON

    ldr    r1 , [r0]        @把GPHCON里的内容加载到r1里

    ldr    r2 , =0xFF

    bic    r1 , r1 ,r2    @操作数取反码&r1,用于清零

    ldr    r2 , =0xAA

    orr    r1 , r1 , r2 

    str    r1 , [r0]    

    

    ldr    r0 , =GPHUP

    ldr    r1 , [r0]

    bic    r1 , r1 , #0x0f

    orr    r1 , r1 , #0x0f

    str    r1 , [r0]    @管脚禁止上拉功能

/***********END***************/    



/***********配置时钟相关寄存器***********/

    ldr    lr , =Memconf

    ldr    pc , =ClkConfigure

/**********END配置时钟相关寄存器*********/


    

/***********配置内存相关寄存器***********/

Memconf:

    ldr    lr , =InitSystemSp

    ldr    pc , =MemConfigure

/**********END配置内存相关寄存器*********/



/***********设置系统模式下的sp***********/

InitSystemSp:

    @复位默认进入系统模式

    ldr    sp , =0x34000000

/********END设置系统模式下的sp***********/



/**********配置UART0相关寄存器***********/

    ldr    lr , =CopyToSdram

    ldr    pc , =Uart0Configure

/*******************END******************/


/************拷贝中断处理子函数到内存****/

CopyToSdram:

    ldr    lr , =Uart0IntConf

    ldr    pc , =copy_bootsram_to_sdram

/*******************END******************/


/********配置UART0中断相关寄存器*******/

Uart0IntConf:

    ldr    r0 , =INTMSK     @使能UART0中断

    ldr    r1 , [r0]

    bic    r1 , r1 , #(0x01<<28)

    str    r1 , [r0]

    

    ldr    r0 , =INTSUBMSK        @禁止INT_ERR0(1<<2),

    ldr    r1 , [r0]        @使能INT_TXD0(0<<1),INT_RXD0(0<<0),中断

    bic    r1 , r1 , #0x07

    orr    r1 , r1 , #0x06

    str    r1 , [r0]

/******END配置UART0中断相关寄存器******/



/*进入中断模式设置中断模式下的sp退出到系统模式

*使能IRQ中断*/    

    msr    cpsr_c , 0xd2        @进入中断模式,禁止中断,其中cpsr后的_c表示cpsr[7:0]

    ldr    sp , =0x33500000    @设置sp

    msr    cpsr_c , 0x5f        @退出到系统模式,使能IRQ中断

/*END进入中断模式设置中断模式下的sp退出到系统模式*/



/*************等待中断******************/

halt_loop:

    b    halt_loop

/*********************END****************/    

    

    

    

/*************IRQ中断服务子程序**********/

HandlerIRQ:


    @因为在产生中断异常时,lr存的是当前指令的下一条指令,所以要减四

    sub    lr , lr , #4

    

    @把相关寄存器压入中断模式下的栈

    @db表示sp每次传送内容前减1

    stmdb    sp! , {r0-r12 , lr}

    

    @禁止IRQ中断

    mrs    r1 , cpsr_all

    orr    r1 , r1 , #(1<<7) 

    msr    cpsr_all , r1

    

    @调用中断服务处理函数

    ldr    lr , =IRQ_Return

    ldr    pc , =main

    

IRQ_Return:

/*    ldr    r0 , =GPBDAT

    ldr    r1 , [r0]    

    ldr    r2 , =(0x0F<<5)

    bic    r1 , r1 , r2

    orr    r1 , r1 , r2

    str    r1 , [r0]*/

    @把栈里面的内容推出到相应寄存器里,并把lr推到pc寄存器实现跳转

    @ia表示每次传送后加1 , 当寄存器列表中包含了pc寄存器,选用^为后缀,就会把spsr拷贝到cpsr

    ldmia    sp! , {r0-r12 , pc}^


        

/********END IRQ中断服务子程序***********/



/*配置Uart0相关寄存器*/

Uart0Configure:

    ldr    r0 , =ULCON0

    mov    r1 , #0x03

    str    r1 , [r0]    @普通模式,禁止奇偶校验,1个结束位,8-bit字长

    

    ldr    r0 , =UBRDIV0

    mov    r1 , #0x36      

    str    r1 , [r0]    @波特率选择115200,所以UBRDIV0=54

    

    ldr    r0 , =UCON0

    ldr    r1 , =0x305

    str    r1 , [r0]    @时钟源=PCLK

                @Rx,Tx水平触发,禁止接收超时中断,禁止接收错误状态中断,

                @不使用回路模式,不发送break信号

                @中断方式发送接收数据到缓冲寄存器

    ldr    r0 , =UFCON0

    mov    r1 ,#0x01

    str    r1 , [r0]    @Tx FIFO触发水平选择空时触发,

                @Rx FIFO触发水平选择>=1字节触发

                @使能FIFO

    

    ldr    r0 , =UMCON0

    mov    r1 , #0x0

    str    r1 , [r0]    @禁止自动流控功能。

    

    bx    lr

    

/******************END******************/


/***********配置时钟相关寄存器***********/

ClkConfigure:

    @UPLL选择MDIV=0x38,PDIV=2,SDIV=1.得UPLL clock=96MHz

    @这里先设置UPLL是为了与设置MPLL隔开至少7个NOP的时间间隔

    ldr    r0 , =UPLLCON

    ldr    r1 , =(0x38<<12)|(0x02<<4)|(0x01<<0)

    str    r1 , [r0]

    

    @分频比FCLK:HCLK:PCLK=1:4:4 , UCLK=UPLL_clock/2=48MHz

    ldr    r0 , =CLKDIVN

    mov    r1 , #(0x01<<3)|(0x02<<1)|(0x00<<0)

    str    r1 , [r0]    

    ldr    r0 , =CAMDIVN

    ldr    r1 , [r0]

    bic    r1 , r1 , #(0x03<<8)

    str    r1 , [r0]

    

    @因为HDIVN不是0 , 所以CPU总线模式要从高速总线模式改变

    @为异步总线模式

    mrc    p15 , 0 , r1 , c1 , c0 , 0

    orr    r0 , r0 , #0xC0000000

    mcr    p15 , 0 , r0 , c1 , c0 , 0


    @MPLL选择MDIV=0x7f,PDIV=2,SDIV=1,得MPLL clock=405MHz 

    ldr    r0 , =MPLLCON

    ldr    r1 , =(0x7f<<12)|(0x02<<4)|(0x01<<0)

    str    r1 , [r0]

    

    bx    lr

/***************END*************************/


/*******内存初始化子程序*********/

MemConfigure:

    @BWSCON[27:24] = 0 0 10B

    ldr    r0 , =BWSCON

    ldr    r1 , [r0]

    ldr    r2 , =(0x0F<<24)

    bic    r1 , r1 , r2

    ldr    r2 , =(0x02<<24)

    orr    r1 , r1 , r2

    str    r1 , [r0]    


    @BANKCON6[16:15]=11B,BANKCON6[3:0]=00 01B

    ldr    r0 , =BANKCON6

    ldr    r1 , [r0]

    ldr    r2 , =(0x03<<15)

    bic    r1 , r1 , r2

    orr    r1 , r1 , r2

    ldr    r2 , =0x0F

    bic    r1 , r1 , r2

    ldr    r2 , = 0x01

    orr    r1 , r1 , r2

    str    r1 , [r0]


    @这里的Trp要大于20ns , Trc要大于70ns,HCLK=101.25MHz

    @故时钟周期=1s/HCLK=9.8ns,Trp*9.8>20ns ==> Trp>=3 ==> Trp域=01b 

    @Trp*9.8+Tsrc*9.8>70ns ==> Tsrc>=5 ==> Tsrc域=01b

    @REFRESH[23:18] = 1 0 01 01B,REFRESH[10:0] = 0x4E8

    ldr    r0 , =REFRESH

    ldr    r1 , [r0]

    ldr    r2 , =(0x3F<<18)

    bic    r1 , r1 , r2

    ldr    r2 , =(0x25<<18)

    orr    r1 , r1 , r2

    ldr    r2 , =0x7FF

    bic    r1 , r1 , r2

    ldr    r2 , =0x4E9

    orr    r1 , r1 , r2

    str    r1 , [r0]


    @BANKSIZE[7:0] = 1 0 1 1 0 001 B

    ldr    r0 , =BANKSIZE

    ldr    r1 , [r0]

    ldr    r2 , =0xFF

    bic    r1 , r1 , r2

    ldr    r2 , =0xB1

    orr    r1 , r1 , r2

    str    r1 , [r0]    


    @MRSRB6[11:0] = 0 00 011 0 000 B

    ldr    r0 , =MRSRB6

    ldr    r1 , [r0]

    ldr    r2 , =0x3FF

    bic    r1 , r1 , r2

    ldr    r2 , =0x030

    orr    r1 , r1 , r2

    str    r1 , [r0]    


    bx    lr    @函数返回

/******END内存初始化子程序*******/




/******拷贝后2048到4096之间的代码到sdram*******/

copy_bootsram_to_sdram:

    ldr    r0 , =0x800

    ldr    r1 , =0x30000000

    ldr    r2 , =0x1000

copy:

    ldr    r3 , [r0] , #4

    str    r3 , [r1] , #4

    cmp    r0 , r2

    bne    copy

    bx    lr

/*****END拷贝前4K代码到sdram*****/


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

     ④demoUart0.h

#ifndef    DEMOUART0_H

#define DEMOUART0_H


#define    GPBCON        (*(volatile unsigned long *)0x56000010)

#define    GPBDAT        (*(volatile unsigned long *)0x56000014)


#define    INTOFFSET    (*(volatile unsigned long *)0x4A000014)

#define SRCPND        (*(volatile unsigned long *)0x4A000000)

#define INTPND        (*(volatile unsigned long *)0x4A000010)

#define    SUBSRCPND    (*(volatile unsigned long *)0x4A000018)

#define INTSUBMSK    (*(volatile unsigned long *)0x4A00001C)


#define    UTXH0        (*(volatile unsigned long *)0x50000020)

#define URXH0        (*(volatile unsigned long *)0x50000024)

#define    UFSTAT0        (*(volatile unsigned long *)0x50000018)

#define    UMCON0        (*(volatile unsigned long *)0x5000000C)


#define    INT_TXD0    (0x01<<1)

#define    INT_RXD0    (0x01)


#define    TFIFO_FULL    (0x01<<14)    

#define    RFIFO_DATA_NUM    (0x1f)


/*消息队列大小*/

#define    QUEUE_SIZE    100

unsigned char p[QUEUE_SIZE];

/*

*选择了水平触发所以这里可以直接把所以中断请求清除,

*退出之后只要满足触发条件还是会触发中断

**/

#define    cleanIQR() \

    do {\

        SUBSRCPND = SUBSRCPND;\

        SRCPND = SRCPND;\

        INTPND = INTPND;\

    } while(0)


    

/*接收数据的消息队列结构体*/    

typedef    struct MSG_QUEUE 

{

    unsigned char *Qmsg;

    unsigned char *write;

    unsigned char *read;

    unsigned char size;

} MSG_QUEUE;


/***************函数声明********************/

/*把消息队列qmsg里的消息通过uart0发送出去*/

void uart0_sent_msg(MSG_QUEUE *qmsg);


/*把接收到的消息存入到qmsg消息队列里*/

void uart0_revice_msg(MSG_QUEUE *qmsg);


/*延时函数*/

void delay(volatile unsigned long second);

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




/*********************函数定义************************/


void delay(volatile unsigned long second)

{

    volatile unsigned long i;

    while(second--){

        i=1000000;

        while(--i);

    }    

}


void uart0_sent_msg(MSG_QUEUE *qmsg)

{

    while( !(UFSTAT0&TFIFO_FULL) && qmsg->size ) {

    /*如果Tx FIFO还被满,并且队列还有数据要发送,则一直循环填入UTXH0*/

    

        UTXH0 = *qmsg->read++;

        --qmsg->size;    

        

        if(qmsg->read == (qmsg->Qmsg+QUEUE_SIZE-1) ){

            qmsg->read = qmsg->Qmsg;    

        }

    }    

    return ;        

}


void uart0_revice_msg(MSG_QUEUE *qmsg)

{

    while( (UFSTAT0 & RFIFO_DATA_NUM) && (qmsg->size < QUEUE_SIZE) ){   

    /*如果接收FIFO里还有数据并且消息队列uart0_qmsg里数据没满,则继续取出数据*/

    

        *qmsg->write++ = (volatile unsigned char)URXH0;

        ++qmsg->size;

        

        if(qmsg->write == (qmsg->Qmsg+QUEUE_SIZE-1) ) {

            qmsg->write = qmsg->Qmsg;    

        }    

    }    

    return;

}


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

#endif

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

     ⑤demoUart0.c

#include "demoUart0.h"



int main()

{

    

    static unsigned char i;

    static MSG_QUEUE *uart0_qmsg;


    if( INTOFFSET != 28 ){

        cleanIQR();

        return 0;    

    }

    

    /*第一次进来初始化队列*/

    if(i==0){

        uart0_qmsg->Qmsg = p;

        uart0_qmsg->write = p;

        uart0_qmsg->read = p;

        uart0_qmsg->size=0;

        i = 1;

    }

    

    /*接收中断处理*/

    if(SUBSRCPND&INT_RXD0){ 


        uart0_revice_msg(uart0_qmsg);

        

        /*如果消息队列里有数据,则使能INT_TXD0中断*/

        if(uart0_qmsg->size){   

            INTSUBMSK &= ~(1<<1);

        }

        

        

        cleanIQR();

        

        return 0;        

    }


    /*发送中断处理*/

    if(SUBSRCPND&INT_TXD0){


        uart0_sent_msg(uart0_qmsg);

        

        /*关闭INT_TXD0中断使能*/

        INTSUBMSK |= (1<<1);  

        

        cleanIQR();

        

        return 0;    

    }

    

    

    /*选择了水平触发所以这里可以直接把所以中断请求清除,退出之后只要满足触发条件还是会触发中断*/

    cleanIQR();

    return 0;

}