在线时间0 小时
UID319324
注册时间2011-9-22
NXP金币0
该用户从未签到
新手上路

- 积分
- 173
- 最后登录
- 1970-1-1
|
看datasheet,说UART0使用的是内核时钟, UART1和UART2使用的是总线时钟。
我采用例程上的UART0初始化函数,
uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 2), 19200);
我发现初始化后UART0实际的波特率是9600,
而当:uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 4), 19200);
初始化后UART0实际的波特率是19200。所以感觉到很奇怪。
我的系统采用的是外部晶振,16MHz,内核时钟频率为48MHz。
UART初始化部分代码如下:
PORTA_PCR1 = PORT_PCR_MUX(0x2); //UART0 Rx
PORTA_PCR2 = PORT_PCR_MUX(0x2); //UART0 Tx
SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1); // select the PLLFLLCLK as UART0 clock source
uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 4 ), 19200);
uart0初始化函数如下:
void uart0_init (UART0_MemMapPtr uartch, int sysclk, int baud)
{
uint8 i;
uint32 calculated_baud = 0;
uint32 baud_diff = 0;
uint32 osr_val = 0;
uint32 sbr_val, uart0clk;
uint32 baud_rate;
uint32 reg_temp = 0;
uint32 temp = 0;
SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
// Disable UART0 before changing registers
UART0_C2 &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK);
// Verify that a valid clock value has been passed to the function
if ((sysclk > 50000) || (sysclk < 32))
{
sysclk = 0;
reg_temp = SIM_SOPT2;
reg_temp &= ~SIM_SOPT2_UART0SRC_MASK;
reg_temp |= SIM_SOPT2_UART0SRC(0);
SIM_SOPT2 = reg_temp;
// Enter inifinite loop because the
// the desired system clock value is
// invalid!!
while(1)
{}
}
// Verify that a valid value has been passed to TERM_PORT_NUM and update
// uart0_clk_hz accordingly. Write 0 to TERM_PORT_NUM if an invalid
// value has been passed.
if (TERM_PORT_NUM != 0)
{
reg_temp = SIM_SOPT2;
reg_temp &= ~SIM_SOPT2_UART0SRC_MASK;
reg_temp |= SIM_SOPT2_UART0SRC(0);
SIM_SOPT2 = reg_temp;
// Enter inifinite loop because the
// the desired terminal port number
// invalid!!
while(1)
{}
}
// Initialize baud rate
baud_rate = baud;
// Change units to Hz
uart0clk = sysclk * 1000;
// Calculate the first baud rate using the lowest OSR value possible.
i = 4;
sbr_val = (uint32)(uart0clk/(baud_rate * i));
calculated_baud = (uart0clk / (i * sbr_val));
if (calculated_baud > baud_rate)
baud_diff = calculated_baud - baud_rate;
else
baud_diff = baud_rate - calculated_baud;
osr_val = i;
// Select the best OSR value
for (i = 5; i baud_rate)
temp = calculated_baud - baud_rate;
else
temp = baud_rate - calculated_baud;
if (temp 3) && (osr_val < 9))
UART0_C5|= UART0_C5_BOTHEDGE_MASK;
// Setup OSR value
reg_temp = UART0_C4;
reg_temp &= ~UART0_C4_OSR_MASK;
reg_temp |= UART0_C4_OSR(osr_val-1);
// Write reg_temp to C4 register
UART0_C4 = reg_temp;
reg_temp = (reg_temp & UART0_C4_OSR_MASK) + 1;
sbr_val = (uint32)((uart0clk)/(baud_rate * (reg_temp)));
/* Save off the current value of the uartx_BDH except for the SBR field */
reg_temp = UART0_BDH & ~(UART0_BDH_SBR(0x1F));
UART0_BDH = reg_temp | UART0_BDH_SBR(((sbr_val & 0x1F00) >> 8));
UART0_BDL = (uint8)(sbr_val & UART0_BDL_SBR_MASK);
/* Enable receiver and transmitter */
UART0_C2 |= (UART0_C2_TE_MASK
| UART0_C2_RE_MASK );
}
else
{
// Unacceptable baud rate difference
// More than 3% difference!!
// Enter infinite loop!
while(1)
{}
}
}
|
|