ARM入门笔记(6)

第六章 RS232串口通信
――串口USART0通讯实验
一.实验目的
利用串口调试软件能够正确接收到AT91SAM7S64发出的数据,AT91SAM7S64也能正确接收到调试软件发出的数据。
二.实验程序和参数设置
1>连接器选项设置和启动代码都与上个实验相同
2>C语言的代码
#i nclude "AT91SAM7S64.h"
#i nclude "Board.h"
unsigned char RBuff[256];   //定义接收缓冲区
unsigned char index;
int main(void)
{
unsigned int i, delay;
*AT91C_CKGR_MOR = 0x701; //使能主振荡器和设置起振时间
*AT91C_PMC_MCKR = 0x01; //选择Mster Clock is main clock, divided by 0  
*AT91C_PMC_SCER = AT91C_CKGR_MOSCEN;//使能系统时钟寄存器的处理器时钟
*AT91C_PMC_PCER = AT91C_ID_US0; //使能USART0时钟
*AT91C_PIOA_PDR = US_RXD_PIN | US_TXD_PIN;//禁止该两个管脚的I/O口功能
*AT91C_PIOA_ASR= US_RXD_PIN | US_TXD_PIN;//将该两个I/O口分配给外围A  
*AT91C_US1_MR =0x8c0;  //正常模式,时钟为MCK,8位长度,无校验,1位停止位,
*AT91C_US0_IDR  = 0xf3fff; //禁止所有UART相关的中断
*AT91C_US0_BRGR = 30;  //设置波特率为38400Hz,AT91C_US0_BRGR为CD值
//Baudrate=SelectedClock/(8(2-Over)CD) = MCK/16CD = 18432000/(16*30) = 38400
*AT91C_US0_CR   = 0x15c; //复位接收器、发送器和状态位;使能接收与发送
index = 0;
while (1)
{
  for (i = 0; i
  { //发送程序
   if ((*AT91C_US0_CSR) & AT91C_US_TXEMPTY) //判断发送器是否为空
   {
    *AT91C_US0_THR = i; //空,则发送数据
   }
   for (delay = 0; delay
  }
  if ((*AT91C_US0_CSR) & AT91C_US_RXRDY)
  {//接收程序,在调试该部分时,要将发送部分程序注示掉
   RBuff[index++] = *AT91C_US0_RHR;
  }
}
}
三.出现的问题与解决方法
1> 状态寄存器中的发送准备位( TXRDY)和发送空标志位( TXEMPTY)一直为 0,表示发送器未准备好和缓冲区不空。
原 因是发送器复位后还未使能。不能同时进行发送器(或接收器)复位与使能操作(*AT91C_US0_CR= 0x15c),这样使能操作会无效,必须将它们分开,即先进行复位(*AT91C_US0_CR= 0x10c),再进行使能(*AT91C_US0_CR = 0x50)。
2> 串口接收、发送的数据不对
原因是系统主时钟和分频后的时钟计算错误,引起波特率也计算错误。很有必要深入研究关于时钟的产生、分频及波特率计算等内容。
3> 每次从串口调试软件收到的数据中,低四位正确,高四位错误。
原 因是将“*AT91C_US0_MR =0x8c0;”写成了“*AT91C_US1_MR =0x8c0;”,而引起通讯模式根本不对。可以说这是一个非常低级的错误,但它却花费了我很久的时间才找到症结所在。在找原因的过程中,使我对串口相关 的(如各种时钟的产生、波特率的计算等)内容有了更深刻的理解。
四.总结
在本实验中串口为异步模式,波特率的计算如下式所示:
Baudrate = SelectedClock/(8(2-Over)CD)
其中在USART模式寄存器(AT91C_US0_MR)中设置SelectedClock为MCK;Over为1则上式变成如下所示:
Baudrate = SelectedClock/(8(2-Over)CD) = MCK/16CD
在Master Clock Register(AT91C_PMC_MCKR)中将MCK设置为Main Clock且不分频,即为外部振荡时钟(接在XIN和XOUT管脚间的晶振)的频率,因为外部晶振是18.432MHz,所以MCK就为 18432000,则上式变成如下所示:
Baudrate=SelectedClock/(8(2-Over)CD) = MCK/16CD = 18432000/(16*30) = 38400

你可能感兴趣的:(职场,休闲)