上篇講到問題 UART接收錯誤的問題.
這篇會繼續討論 UART 相關 register 設定的部分.
使用ICE 設定中斷點在這程式中,讀取一些數值.
PortNum = 0 or 1,差異在於設定 UART 0 or UART 1相關暫存器.
baudrate 當然就是我們要設定的 baud rate值.
這篇我們著重在爲得到正確 Baud Rate 值,所計算該填寫的暫存器.
順著程式看下來,
我得到
pclkdiv = 0
SystemFrequency = 72000000
因此
pclk ( 上式中的 PCLK ) = SystemFrequency/4 = 18000000
依照上圖流程:
(1)
BR : Baud Rate
DLest = PCLK/(16xBR)
= 18000000/(16x115200)
=9.7656
(2)
DLest 非整數,
FRest =1.5
帶入下式.
(3)
DLest = PCLK/(16xBRxFRest)
DLest = 6.5104
(4)
FRest = PCLK/(16xBRxDLest) = 18000000/(16x115200x6) = 1.627
(5) 1.1< FRest < 1.9 ,True
(6) 查下表 FR = 1.625
DIVADDVAL = 5
MULVAL = 8
(7)
DLM = DLest [15:8] = 0
DLL =DLest [7:0] = 6
代入公式 1計算 Baud Rate值
18000000/(16x6x1.625)= 115384
(115384-115200)/115200 = 0.001597
這篇會繼續討論 UART 相關 register 設定的部分.
/*LPC17xx */
uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate )
{
uint32_t Fdiv;
uint32_t pclkdiv, pclk;
if ( PortNum == 0 )
{
LPC_PINCON->PINSEL0 &= ~0x000000F0;
LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */
/* By default, the PCLKSELx value is zero, thus, the PCLK for
all the peripherals is 1/4 of the SystemFrequency. */
/* Bit 6~7 is for UART0 */
pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
switch ( pclkdiv )
{
case 0x00:
default:
pclk = SystemFrequency/4;
break;
case 0x01:
pclk = SystemFrequency;
break;
case 0x02:
pclk = SystemFrequency/2;
break;
case 0x03:
pclk = SystemFrequency/8;
break;
}
LPC_UART0->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */
LPC_UART0->DLM = Fdiv / 256;
LPC_UART0->DLL = Fdiv % 256;
LPC_UART0->LCR = 0x03; /* DLAB = 0 */
LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
NVIC_EnableIRQ(UART0_IRQn);
LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */
return (TRUE);
}
else if ( PortNum == 1 )
{
LPC_PINCON->PINSEL4 &= ~0x0000000F;
LPC_PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */
/* By default, the PCLKSELx value is zero, thus, the PCLK for
all the peripherals is 1/4 of the SystemFrequency. */
/* Bit 8,9 are for UART1 */
pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03;
switch ( pclkdiv )
{
case 0x00:
default:
pclk = SystemFrequency/4;
break;
case 0x01:
pclk = SystemFrequency;
break;
case 0x02:
pclk = SystemFrequency/2;
break;
case 0x03:
pclk = SystemFrequency/8;
break;
}
LPC_UART1->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */
LPC_UART1->DLM = Fdiv / 256;
LPC_UART1->DLL = Fdiv % 256;
LPC_UART1->LCR = 0x03; /* DLAB = 0 */
LPC_UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
NVIC_EnableIRQ(UART1_IRQn);
LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART1 interrupt */
return (TRUE);
}
return( FALSE );
}
使用ICE 設定中斷點在這程式中,讀取一些數值.
PortNum = 0 or 1,差異在於設定 UART 0 or UART 1相關暫存器.
baudrate 當然就是我們要設定的 baud rate值.
這篇我們著重在爲得到正確 Baud Rate 值,所計算該填寫的暫存器.
公式 1 |
順著程式看下來,
我得到
pclkdiv = 0
SystemFrequency = 72000000
因此
pclk ( 上式中的 PCLK ) = SystemFrequency/4 = 18000000
依照上圖流程:
(1)
BR : Baud Rate
DLest = PCLK/(16xBR)
= 18000000/(16x115200)
=9.7656
(2)
DLest 非整數,
FRest =1.5
帶入下式.
(3)
DLest = PCLK/(16xBRxFRest)
DLest = 6.
(4)
FRest = PCLK/(16xBRxDLest) = 18000000/(16x115200x6) = 1.627
(5) 1.1< FRest < 1.9 ,True
(6) 查下表 FR = 1.625
DIVADDVAL = 5
MULVAL = 8
(7)
DLM = DLest [15:8] = 0
DLL =DLest [7:0] = 6
LPC_UART0->DLM = 0;
LPC_UART0->DLL = 6;
LPC_UART0->FDR = ((8<<4)|5); // DIVADDVAL, MULVAL
代入公式 1計算 Baud Rate值
18000000/(16x6x1.625)= 115384
(115384-115200)/115200 = 0.001597
0 留言:
張貼留言