转自:http://blog.csdn.net/shengnan_wu/article/details/8309417

版权声明:本文为博主原创文章,未经博主允许不得转载。

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;
}

【作者】张昺华
【出处】http://www.cnblogs.com/sky-heaven/
【博客园】 http://www.cnblogs.com/sky-heaven/
【新浪博客】 http://blog.sina.com.cn/u/2049150530
【知乎】 http://www.zhihu.com/people/zhang-bing-hua
【我的作品---旋转倒立摆】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【我的作品---自平衡自动循迹车】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

八、mini2440裸机程序之UART(2)UART0与PC串口通信【转】相关推荐

  1. Keil5 平台 S3C2440裸机程序开发-----UART

    目录 前言 一.时钟频率 二.代码 main.c uart.c uart.h led.c led.h S3C2440.h 三.编译,烧录,打开串口助手,接收到数据. 前言 本博文介绍mini2440开 ...

  2. 单片机 串口 波特率 c语言 9600 11.0592mhz t1,C51语言编程:单片机与 PC 串口通信程序...

    单片机接收PC机发来的指令信号,然后单片机又向PC机发送字符串.具体要求如下: 当接收指令信号为:'go',单片机向PC机发送字符串:WELCOME TO CHINA!; 当接收指令信号为:'who' ...

  3. STM32与PC串口通信 实现步进电机转速可调 程序及调试过程分享

    在读书期间,需要用到步进电机.用STM32F103ZET6作为下位机,采用计时器产生PWM波,通过改变改变ARR的值,改变PWM波的频率,实现步进电机调速,LCD屏幕显示串口收到的数值. PC作为上位 ...

  4. 九.mini2440实现I2C协议裸机程序(完成)

    ** I2C协议的mini2440裸机程序实现 ** 上篇博客说道了I2C的理论知识,但是实际应用的时候,遇到很多的问题,加上程序的庞大,一直在调试.这几天重新看了一下,最终解决问题. 首先的问题是程 ...

  5. 使用 NOR Flash 中的supervivi 下载裸机程序到NandFlash

    不容易啊,终于把 将MDK程序下载到我的mini2440开发板上的nand flash的方法找到了,我是利用韦东山老师的那套方法即利用DNW和supervivi下载到nand flash的.当然,只是 ...

  6. 单片机:11.UART串口通信

    原文地址:https://blog.csdn.net/Qingzhusshuiyun/article/details/78236798 通信按照传统的理解就是信息的传输与交换.对于单片机来说,通信则与 ...

  7. RS232与UART串口通信

    通信,按照传统的理解就是信息的传输与交换.对于单片机来说,通信则与传感器.存储芯片.外围控制芯片等技术紧密结合,成为整个单片机系统的"神经中枢".没有通信,单片机所实现的功能仅仅局 ...

  8. c语言uart串口通讯,UART串口通信的基本应用

    通信的三种基本类型 常用的通信从传输方向上可以分为单工通信.半双工通信.全双工通信三类. 单工通信就是指只允许一方向另外一方传送信息,而另一方不能回传信息.比如电视遥控器.收音机广播等,都是单工通信技 ...

  9. c语言uart串口通讯,uart串口通信c语言实现

    通信,按照传统的理解就是信息的传输与交换.对于单片机来说,通信则与传感器.存储芯片.外围控制芯片等技术紧密结合,成为整个单片机系统的"神经中枢".没有通信,单片机所实现的功能仅仅局 ...

最新文章

  1. RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个
  2. 数据预处理之独热编码(One-Hot Encoding)
  3. 项目中常用的19条MySQL优化
  4. oracle:对视图DML操作
  5. 实用windows short cut
  6. Web Api 基于Zookeeper的服务注册与发现
  7. python字母大小写排序_Python中sorted()排序与字母大小写的问题
  8. C# MVC的博客开发(三)注册
  9. repo/git下载android源码断后重新下载
  10. windows环境下的YOLO3入门,及opencv344配置
  11. Eclipse \ MyEclipse \Scala IDEA for Eclipse里如何将控制台console输出的过程记录全程保存到指定的文本文件(图文详解)...
  12. LeNet论文全文翻译《Gradient-based learning applied to document recognition》(上)
  13. 闽什么什么院第二课堂网课破解-----微信内置浏览器
  14. 【转】收集各种反编译工具 常用EXE文件反编译工具下载
  15. 凯利公式计算器安卓_华为MatePad Pro 5G评测:一屏双任务,打破安卓平板生态限制...
  16. 在matlab中输出怎么表示什么意思,matlab中基于帧输出是什么意思
  17. Liang-Barskey裁剪算法(计算机图形学)
  18. 容易遗忘的几个js知识点(一)
  19. OpenGL 之 EGL 使用实践
  20. package.josn中^和~的区别

热门文章

  1. #招聘# C++高级攻城师一枚
  2. iOS 与OS X多线程和内存管理 笔记 ARC与所有权修饰符
  3. 用Understand阅读 VS2010项目源码
  4. Mac自定义终端的欢迎页
  5. Spring @Scheduled
  6. CentOS 7 搭建docker仓库
  7. Kali Linux 64位安装WPS
  8. 解决Xcode The selected destination does not support the architecture 错误错误
  9. 高性能 Windows C++ 通用组件 VC-Logger v2.0.3 正式发布
  10. Arrays类、大数据运算