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