加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

嵌入式系统实验—通用异步收发器(UART)实验

(2011-06-24 10:16:46)
标签:

嵌入式系统实验

通用异步收发器

uart

mini2440

arm

j-link

keil-uvisio

分类: 实验报告

实验五:通用异步收发器(UART)实验


一、实验目的

1、掌握 UART 外设的操作原理和编程。

2、学习使用 UART 进行多机通讯。

二、实验设备

1、硬件:PC 机一台 Mini2440 ARM 实验板一套 J-link 仿真器一套

2、软件:WindowsXP 系统,Keil uVision 4.0 集成开发环境

三、实验内容

1)使用 C 语言编写 UART 基本收发数据程序,进行 2 个实验板之间的数据收发测试。

2)用两个实验板模拟嵌入式控制系统中的数据采集/控制实验,其中一个实验板模拟数据采集模块,将通过 UART 返回数据;另一块实验板模拟控制系统的主机,通过 UART 采集数据,并通过 UART 发出控制指令。

四、实验预习要求

(1)学习 UART 相关的原理概念;

(2)查阅 S3C2440 芯片手册,了解 UART0 结构和原理。

五、实验步骤

(1)启动 Keil uVision,新建一个工程ex05。不需要系统提供的 Startup 文件。建立汇编源文件 ex05.s,编写实验程序,然后添加到工程中。设置工程选项,存储器映射。设置工程调试选项。建立仿真初始化文件 RAM.ini

(2)建立 C 语言源文件 main.c,编写实验程序,然后添加到工程中。

(3)使用交叉串口电缆连接两个实验板。

(4)编译程序, 使用仿真器在目标板上调试运行程序, 使用单步、 设置断点,观察程序执行时,收发数据的值。

六、实验程序

C 语言实验程序见程序清单 5

程序清单 4.1 UART 实验程序

// Uart0

#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)

#define RdURXH0()   (*(volatile unsigned char *)0x50000024)

#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 divisor

#define rGPHCON    (*(volatile unsigned *)0x56000070) //Port H control

#define rGPHUP     (*(volatile unsigned *)0x56000078) //Pull-up control H

//PCLK:12MHz

#define PCLK 12000000

//( (int)(pclk/16./baud+0.5) -1 )

#define baud_value 12  //57600

void Uart_Init()

{

    int i;

    rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable

    rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable

    rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits

     //    [10]  [9]   [8]    [7]    [6]    [5]    [4]      [3:2]      [1:0]

     // Clock Sel,  Tx Int,  Rx Int, Rx Time Out, Rx err, Loop-back, Send break,  Transmit

Mode, Receive Mode

     //     0          1       0    ,     0          1        0           0     ,      

01          01

     //   PCLK       Level    Pulse    Disable    Generate  Normal      Normal       

Interrupt or Polling

    rUCON0  = 0x245;   // Control register

    rUBRDIV0= baud_value;   //Baud rate divisior register 0

    for(i=0;i<100;i++)

  ;

rGPHCON |= 0xaa;//use GPH port as uart0

 rGPHUP  =0x0f;//the pull up function is disabled

}

void Uart_SendByte(int data)

{

 WrUTXH0(data);

char Uart_Getch(void)

{

 while(!(rUTRSTAT0 & 0x1)) //Receive data ready

     return RdURXH0();

}

main()

{

 char c = 'a';

Uart_Init();   

Uart_SendByte(c); 

  while(1)

 {

  c = Uart_Getch();

  c++;

  Uart_SendByte(c); 

 }

 

七、实验现象

两块实验板在接收指令处设断点,然后实验板1全速运行,实验板2接着全速运行,实验板1自动暂停。此时实验板1接收到‘b’的ASIC码(之前储存的是‘a’),实验板2现在储存的是‘c’。

 

八、思考题

(1)UART FIFO 对改进通讯性能和可靠性有什么作用?

答:FIFO对通讯性能的改进:在进行UART通信时,中断方式比轮询方式要简便且效率高。但是,如果没有收发FIFO,则每传输一个数据(58位)都要中断处理一次,效率仍然不高。如果有了收发FIFO,则可以在连续收发若干个数据后才产生一次中断,然后一起处理。这就大大提高了收发效率。

FIFO对可靠性的作用:如果没有接收超时功能,则在对方已经发送完毕而接收FIFO未填满时并不会触发中断(FIFO满才会触发中断),结果造成最后接收的有效数据得不到处理的问题。有了接收超时功能后,如果接收FIFO未填满而对方发送已经停,则在不超过3个字的数据的接收时间内就会触发超时中断,因此数据会照常得到处理。

 

(2)两个实验板互连通讯,波特率设置满足什么关系时可以正确通讯?

答:当两个实验板用UART进行通讯时,如果打算使接受的第N位数据为正确位时,需要满足下式:

http://s7/middle/7bf0c30f4a66bcae533c6&amp;690

当字长度为8位数据位时,如果要确保数据接收正确,那么波特率误差必须在5%以内。例如:标准波特率为9600,那么ARM允许的波特率范围为912010080

所以当两个实验板通讯时,每次发送N位数据(包括起始位、数据位、停止位、奇偶校验位等),两个实验板的波特率误差应该满足:

http://s15/middle/7bf0c30f4a66bcaf219be&amp;690

九、选做题

(1) 使用一个实验板上的按键控制另一个实验板上的LED 指示灯状态。

两个实验板之间进行通讯需要用到UART,其中一个作为发送端,另一个作为接收端。

作为发送端的实验板需要增加代码用来处理按键,先设置GPIO,然后不停的读取按键的状态,写入到UART中,然后UART发送出去。

作为接收端的实验班需要增加爱代码用来处理指示灯,设置好GPIO之后,不停的从UART中读取数据,然后写入到控制灯的GPIO中去。

两个实验板UART的设置诸如波特率要相同,实验板1的按键状态每发生一次该变,实验板2的指示灯的状态也发生一次改变。

UART实际发送的数据可以不是按键装态,只需要发送一个能够反应实验板1的按键状态的值即可。约定当实验板1的按键状态发生变化时,通过UART向实验板2发送字符‘1’,否则发送字符‘0’;接收端收到字符‘1’时,就改变指示灯的状态,否则不改变。

最终的实验程序如下所示:

#define rGPBCON (*(volatile unsigned *)0x56000010 //Port B control register指示灯

#define rGPBDAT (*(volatile unsigned *)0x56000014 //Port B data register

 

#define rGPGCON (*(volatile unsigned *)0x56000060 //Port G control register按键

#define rGPGDAT (*(volatile unsigned *)0x56000064 //Port G data register

 

#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)

#define RdURXH0() (*(volatile unsigned char *)0x50000024)

#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 divisor

#define rGPHCON (*(volatile unsigned *)0x56000070) //Port H control

#define rGPHUP (*(volatile unsigned *)0x56000078) //Pull-up control H

#define PCLK 12000000//PCLK:12MHz

#define baud_value 12 //( (int)(pclk/16./baud+0.5) -1 )57600

 

void Uart_Init()

{

int i;

rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable

rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable

rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits

// [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0]

// Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit

Mode, Receive Mode

// 0 1 0 , 0 1 0 0 ,

01 01

// PCLK Level Pulse Disable Generate Normal Normal

Interrupt or Polling

rUCON0 = 0x245; // Control register

rUBRDIV0= baud_value; //Baud rate divisior register 0

for(i=0;i<100;i++)

;

rGPHCON |= 0xaa;//use GPH port as uart0

rGPHUP =0x0f;//the pull up function is disabled

}

 

void Uart_SendByte(int data)

{

WrUTXH0(data);

}

 

char Uart_Getch(void)

{

while(!(rUTRSTAT0 & 0x1)); //Receive data ready

return RdURXH0();

}

 

实验板1main函数(用于发送按键状态)

main()

{

int state=0x7fff;

Uart_Init();

 

rGPGCON= =0x15400

rGPGDAT=0x7fff    //initialize to default state

 

while(1)

{

if(state!=rGPGDAT)

{

state=rGPGDAT;

Uart_SendByte(‘1’);

}

else

Uart_SendByte(‘0’);

}

}

 

实验板2main函数,用于接受实验板1的按键状态:

main()

{

Uart_Init();

 

rGPBCON= 0x15400;

 

while(1)

{

if(Uart_Getch()==’1’)

{

rGPBDAT=0x1e0;

}

else

rGPBDAT=0x00;

}

}

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有