mini2440+jlink v8+mkd4.54 uart串口通信调试心得体会(11.20补完中断部分)

原创 2013年11月17日 23:59:04

开发环境如题。uart串口通信可分为两种方式:轮询(polling)和中断

今天先把uart串口通信方式中的轮询说说,日后补上中断

采用uart0,串口调试助手4.2

这里只讲需要配置的寄存器,其他寄存器采用默认值:

(1)配置数据格式的寄存器ULCON0,8位数据位,无奇偶校验,1停止位

(2)配置波特率的寄存器UBRDIV0:这个需要往寄存器写一个数字UBRDIV,这个数字是由UART CLOCK和你期望的波特率算出来的

UBRDIV=[UART CLOCK/(BAUD RATE*16)]-1

寄存器上电默认选PCLK为UART CLOCK(我这里配置PCLK为50MHz),BAUD RATE为115200Hz,算出UBRDIV=26.12,四舍五入取26

(3)配置GPHCON寄存器,把GPH0-3功能复用为nCTS0,nRTS0,TXD0,RXD0。

程序这边的准备工作做好了,串口调试助手那的数据格式也选为8位数据位,无奇偶校验,1停止位,波特率115200Hz就OK,其他不用设置。下面说下发送和接收。

发送:

不断地检测寄存器UTRSTAT0寄存器的[1]位,只要为1(即表示transmit buffer register为空),就代表我们可以向寄存器UTXH0写我们想发出去的数据了,一旦向UTXH0写入某个8位二进制数据(这里是和寄存器ULCON0里的数据格式对应的,8位正好可以一次通信就传完,不对应的情况我还没试过),瞬间就会发到串口调试助手上了(所以我从memory watch窗口也看不到[1]位的变化,因为从写入数据到到发送完数据(空→满→空)是一瞬间的事)。

接收:

不断地检测寄存器UTRSTAT0寄存器的[0]位,只要为0(即表示receive buffer register收到了一个数据),接着就可以从寄存器URXH0上读从串口调试助手上发过来的数据了。这里有一点要注意,如果你开着mdk的memory watch窗口,并且监视着寄存器UTRSTAT的地址0x50000010,程序本身很有可能会读不到寄存器UTRSTAT的[0]位的变化,因为memory watch在每执行一条指令,或者你对着地址按回车的时候,都会读一遍memory watch窗口里出现的地址的值。当UTRSTAT0的[0]位为1的时候(当receive buffer register接收到了一个数据后,[0]位会自动置1),如果访问了这个寄存器,它的[0]位就会自动清零。

总结:可以发现,用轮询这个方式完成串口收发数据非常简单,其实当相关寄存器配置好后,收发数据只要两条指令,发送是往transmit buffer register写数据,接收是从receive buffer register读数据,而先读寄存器UTRSTAT0的状态再往寄存器读写数据只是为了保证通信的正确性罢了(避免上一个数据,还没发送完毕,你又写新数据进去;避免上个数据,还没从寄存器读出来,又被一个新数据覆盖了)。

这个模式的缺点也显而易见,如果想串口通信,cpu就不能干别的,得一直在查询寄存器UTRSTAT0的值,所以轮询方式只适合简单的程序,如果你的程序复杂到不能让cpu一直读寄存器UTRSTAT0的值,那你就得用中断方式了(中断方式过些日子补完,后面先贴上轮询的代码)。

程序流程:start:配置寄存器 1:发送字节 0:接收字节(调试串口助手那边设的每过1秒发送一个字节)

	AREA uart,CODE,READONLY
	entry
start
	mov r0,#0x50000000 		;uart channel 0 line control register
	add r0,r0,#0x00
	mov r1,#0x3
	str r1,[r0]
	mov r0,#0x50000000 		;uart channel 0 control register
	add r0,r0,#0x4
	mov r1,#0x000
	add r1,r1,#0x05
	str r1,[r0]
	mov r0,#0x50000000 		;uart channel 0 moden register
	add r0,r0,#0xc
	mov r1,#0x0
	str r1,[r0]
	mov r0,#0x50000000 		;uart channel 0 baud rate divisor register
	add r0,r0,#0x28			;115200hz
	mov r1,#26
	str r1,[r0]
	mov r0,#0x56000000 		;GPHCON register
	add r0,r0,#0x70
	mov r1,#0xaa
	str r1,[r0]
1	
	mov r0,#0x50000000 		;read"transmit register empty"
	add r0,r0,#0x10
	ldr r1,[r0]
	and r1,r1,#0x1<<1
	cmp r1,#1<<1
	bne %b1
	mov r0,#0x50000000 		;write a byte to UTXH0
	add r0,r0,#0x20
	mov r1,#90
	strb r1,[r0]

0	
	mov r0,#0x50000000 		;read"receive buffer data ready"
	add r0,r0,#0x10
	ldr r1,[r0]
	and r1,r1,#0x1
	cmp r1,#1
	bne %b0
	
	mov r0,#0x50000000		;read a byte from URXH0
	add r0,r0,#0x24
	ldrb r1,[r0]
	b %b1
	
	
	end

中断方式:

uart0一共能触发三种子中断:INT_RXT0,INT_TXD0,INT_ERR0,他们同属于INT_UART0中断。

本次实验目标:接收从串口调试助手发来的字符,并发回串口调试助手。很简单,就是熟悉中断方式下的UART通信。

相较轮询方式,这里要多配置几个寄存器,主要是一些和中断有关的寄存器。分别是清这三个子中断的mask,清uart0的mask,使能irq中断,其他默认配置。

这里就强调几个要注意的事情,其他细节见代码:

(1)清中断请求,要写1。我因为忘了这件事,就耽误了一些时间,一直在找其他地方的错误。

(2)SUBS PC,LR,#0X4   这里要注意subs一定要加s,这样才能顺利退出IRQ模式回到管理,因为irq默认是关掉irq中断的,不退出的话,没办法响应下次中断。当然你也可以试试,在irq模式里使能irq中断

(3)大概说一下,程序流程:先执行start部分,都是一些寄存器的配置和把异常向量表复制从0x30000000到0x00000000。接着,进入循环l,等待串口调试助手发来字符。receive buffer register收到字符后,就会触发中断,cpu跳转到中断程序执行。把接收到的字符再写入transmit buffer register送出去。然后退出中断,又回到循环l。

	AREA UART,CODE,READONLY
	ENTRY
EXCEPTION_VECTOR
	b START
	NOP
	NOP
	NOP
	NOP
	NOP
	b interrupt_jump
	NOP
interrupt_jump
	MOV r0,#0X30000000			;这里只能给一个绝对地址,至于为什么看
	ADD R0,R0,#0x2c				;我的裸机按键中断那篇博文
	mov pc,r0
INTERRUPT_HANDLE
	MOV R0,#0X50000000			;URXTH0 read"receive buffer register"
	ADD R0,R0,#0x24
	LDR R2,[R0]	
	MOV R0,#0X50000000			;UTRSTAT read"transmit buffer register empty"
	ADD R0,R0,#0x10
1	LDR R1,[R0]
	AND R1,R1,#0X1<<1
	CMP R1,#0X2
	BNE %B1
	MOV R0,#0X50000000			;UTXD0 WRITE "transmit buffer register"
	ADD R0,R0,#0x20
	STR R2,[R0]
	MOV R0,#0X4a000000			;SUBSRCPND clear RXD0 interrupt request
	ADD R0,R0,#0x18
	mov r1,#0x3
	STR R1,[R0]
	MOV R0,#0X4a000000			;SRCPND clear UART0 interrupt request
	ADD R0,R0,#0x0
	mov r1,#0x1<<28
	STR R1,[R0]
	MOV R0,#0X4a000000			;INTPND clear UART0 interrupt request
	ADD R0,R0,#0x10
	mov r1,#0x1<<28
	STR R1,[R0]
	
	SUBS PC,LR,#0X4
START
	MOV R0,#0X30000000			;COPY EXCEPTION_VECTOR TO 0X00000000
	MOV R1,#0X30000000
	MOV R2,#0X00000000
	ADD R1,R1,#48
2	LDMIA R0!,{R3-R6}			
	STMIA R2!,{R3-R6}
	CMP R0,R1
	BNE %B2
	MOV R0,#0X56000000			;GPHCON
	ADD R0,R0,#0x70
	MOV R1,#0XAA
	STR R1,[R0]
	MOV R0,#0x50000000			;ULCON0
	MOV R1,#0x3
	STR R1,[R0]
	MOV R0,#0x50000000			;UCON0
	ADD R0,R0,#0x4				
	MOV R1,#0x05
	ADD R1,R1,#0x0
	STR R1,[R0]
	MOV R0,#0x50000000			;UBRDIV0 115200HZ
	ADD R0,R0,#0x28				
	MOV R1,#26
	ADD R1,R1,#0x0
	STR R1,[R0]	
	MOV R0,#0X4A000000			;INTMASK clear uart0 mask
	ADD R0,R0,#0x8
	MOV R1,#0xFFFFFFFF
	EOR R1,R1,#0x1<<28
	STR R1,[R0]	
	MOV R0,#0X4A000000			;INTSUBMASK clear RXD0 TXD0 ERR0 mask
	ADD R0,R0,#0x1c
	MOV R1,#0x000EF000
	ADD R1,R1,#0X00000FF0
	ADD R1,R1,#0X0000000E
	STR R1,[R0]
	MRS R0,cpsr				;enable irq mode
	eor r0,#0x1<<7
	MSR cpsr_c,r0
	
l
	b l
	end
	



dsPIC33F串口发送一个数组到发送寄存器-UART

/* **************************************************************** ** 功能描述: 串口测试,发送一个数组到发送寄存器 *****...
  • Augusdi
  • Augusdi
  • 2013年08月13日 14:33
  • 2357

UART0串口编程系列 串口编程(UART0)之中断方式(一)

本文章针对的是ARM2200环境下编写串口程序,其中设计轮循方式,中断方式,以及在UC/OS-II操作系统下的串口编程。 使用轮循和中断两种方式来实现串口编程。 (当然了,用中断实现串口编...
  • yyyljw
  • yyyljw
  • 2015年12月09日 17:11
  • 1564

STM32 UART常用的3种中断接收

#include "sys.h" #include "usart.h"   #include "main.h" //如果使用ucos,则包括下面的头文件即可. #if SYSTEM_S...
  • li_qcxy
  • li_qcxy
  • 2017年01月08日 11:00
  • 3685

关于单片机中断模块的心得体会

单片机中断的理解。 1.首先52单片机里6个中断源(比51多一个T2),具体如下图1.1所示。 图1.1  52单片机6个中断源 在这里我们需要注意的是,定时系统是单片机硬件的组成部分,52单片...
  • DylanDong
  • DylanDong
  • 2015年01月28日 11:03
  • 1200

stm8s中UART的用法(四种UART中断)

一、应用实例 1.1系统功能  使用STM8的USART进行自发自收(将发送引脚RXD短接到接收引脚TXD),发出数据:0,1,2。。。数据,能接收到自己发出的数据:0,1,2。。。使用LED作出简单...
  • u014186096
  • u014186096
  • 2015年06月18日 15:51
  • 5346

STM8 UART中断发,中断收

STM8 UART 初始化配置STM8 UART的几个常用寄存器分别为: UART1_CR1:控制寄存器1 UART1_CR3:控制寄存器3 UART1_BRR2:波特率寄存器2 UART1_...
  • yuanquanzheng
  • yuanquanzheng
  • 2017年01月23日 16:46
  • 2024

uart接收中断,带解释,可以拷贝直接用

main.c #include "LPC17xx.h" #include "uart.h" int main(void) { // CMSIS的启动代码里面已经调用了 Syst...
  • alangdangjia
  • alangdangjia
  • 2013年03月11日 18:19
  • 6104

UART0串口编程系列 串口编程(UART0)之中断方式(二)

三.        中断方式的串口编程 1.用中断方式编写串口程序由那几部分组成 2.硬件上的支持 1>UART0 发送FIFO缓冲区 A.        UART0含有1...
  • yyyljw
  • yyyljw
  • 2015年12月09日 17:12
  • 1283

Zynq 自定义模块中断触发实例

最近,设计PL与PS数据交互,用到自定义IP模块,同时需要给ARM侧一个ACK信号,考虑到实时性,采用PL-PS的IRQ。 参考官网文档: The_Zynq_Book_ebook.pdf U...
  • wangbaodong070411209
  • wangbaodong070411209
  • 2016年11月22日 14:17
  • 1441

UART通信程序-中断方式

UART通信程序-中断方式
  • w89436838
  • w89436838
  • 2014年09月02日 16:33
  • 583
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mini2440+jlink v8+mkd4.54 uart串口通信调试心得体会(11.20补完中断部分)
举报原因:
原因补充:

(最多只允许输入30个字)