我的波特率應該是115200,但它是892.9ARM LPC1768 UART0的配置,錯誤的波特率
void UART0_Init(int pclk, int baudrate)
{
unsigned long int DLest;
//unsigned long int pclk;
unsigned int temp;
// Turn on power to UART0
SC->PCONP |= PCUART0_POWERON;
// Set PINSEL0 so that P0.2 = TXD0, P0.3 = RXD0
PINCON->PINSEL0 = (PINCON->PINSEL0 & ~0xf0) | (1 << 4) | (1 << 6);
UART0->LCR = 0x83; // 8 bits, no Parity, 1 Stop bit, DLAB=1
DLest = (pclk/16)/baudrate; // Set baud rate
UART0->DLM = DLest/256;
UART0->DLL = DLest % 256;
// UART0->FDR =
UART0->IER = 0x7; //enable RBR (b0), THRE(b1), RLS(b2)
UART0->LCR = 0x03; // 8 bits, no Parity, 1 Stop bit DLAB = 0
UART0->FCR = 0x07; // Enable and reset TX and RX FIFO
}
void prvSetupHardware(void)
{
/* Disable peripherals power. */
SC->PCONP = 0;
/* Enable GPIO power. */
SC->PCONP = PCONP_PCGPIO;
/* Disable TPIU. */
PINCON->PINSEL10 = 0;
if (SC->PLL0STAT & (1 << 25))
{
/* Enable PLL, disconnected. */
SC->PLL0CON = 1;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
SC->PLL0CON = 0;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Enable main OSC. */
SC->SCS |= 0x20;
while(!(SC->SCS & 0x40));
/* select main OSC, 12MHz, as the PLL clock source. */
SC->CLKSRCSEL = 0x1;
SC->PCLKSEL0 = 0xAAAAAAAA; /* PCLK is 1/2 CCLK */
SC->PCLKSEL1 = 0xAAAAAAAA;
/*Fcc0 = 400MHz, M = 50, N = 3*/
SC->PLL0CFG = 0x20031;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
SC->PLL0CON = 1;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Set clock divider. */
/*Clock = 100MHz, Fcc0 = 400MHz*/
SC->CCLKCFG = 0x03;//divided by 4.
/* Configure flash accelerator. */
SC->FLASHCFG = 0x403a;
/* Check lock bit status. */
while(((SC->PLL0STAT & (1 << 26)) == 0));
/* Enable and connect. */
SC->PLL0CON = 3;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
while(((SC->PLL0STAT & (1 << 25)) == 0));
/* Configure the clock for the USB. */
if(SC->PLL1STAT & (1 << 9))
{
/* Enable PLL, disconnected. */
SC->PLL1CON = 1;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
SC->PLL1CON = 0;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
SC->PLL1CFG = 0x23;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
SC->PLL1CON = 1;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
while(((SC->PLL1STAT & (1 << 10)) == 0));
/* Enable and connect. */
SC->PLL1CON = 3;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
while(((SC->PLL1STAT & (1 << 9)) == 0));
/* Configure the LEDs. */
vParTestInitialise();
/*pclk = 100MHZ/2, baud = 115200 */
UART0_Init(100000000/2, 115200);
/* Set the sleep mode to highest level sleep*/
SC->PCON = 0x0;
SCB->SCR = 0x0;
/*set push button interrupt */
PINCON->PINSEL4 |= 0x00100000;
SC->EXTMODE =0;
NVIC_SetPriority(EINT0_IRQn, configUIButton1_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(EINT0_IRQn);
NVIC_SetPriority(UART0_IRQn, configUIButton1_INTERRUPT_PRIORITY + 1);
NVIC_EnableIRQ(UART0_IRQn);
}
我已經證實,我的CCLK爲在100MHz運行。
我通過Kunil(uart_interrupt_demo)與代碼替換UART初始化代碼從一個示例項目:
void uart_init(int baudrate) {
int errorStatus = -1; //< Failure
long int SystemFrequency = 100000000;
// UART clock (FCCO/PCLK_UART0)
unsigned int uClk = SystemFrequency/4;
unsigned int calcBaudrate = 0;
unsigned int temp = 0;
unsigned int mulFracDiv, dividerAddFracDiv;
unsigned int divider = 0;
unsigned int mulFracDivOptimal = 1;
unsigned int dividerAddOptimal = 0;
unsigned int dividerOptimal = 0;
unsigned int relativeError = 0;
unsigned int relativeOptimalError = 100000;
// Turn on power to UART0
SC->PCONP |= PCUART0_POWERON;
// Change P0.2 and P0.3 mode to TXD0 and RXD0
PINCON->PINSEL0 = (1 << 4) | (1 << 6);
// Set 8N1 mode
UART0->LCR = 0x83;
// Set the baud rate
uClk = uClk >> 4; /* div by 16 */
/*
* The formula is :
* BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv)/(16 * DLL)
*/
/*
* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
* 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15
*/
for (mulFracDiv = 1; mulFracDiv <= 15; mulFracDiv++) {
for (dividerAddFracDiv = 0; dividerAddFracDiv <= 15; dividerAddFracDiv++) {
temp = (mulFracDiv * uClk)/(mulFracDiv + dividerAddFracDiv);
divider = temp/baudrate;
if ((temp % baudrate) > (baudrate/2))
divider++;
if (divider > 2 && divider < 65536) {
calcBaudrate = temp/divider;
if (calcBaudrate <= baudrate) {
relativeError = baudrate - calcBaudrate;
} else {
relativeError = calcBaudrate - baudrate;
}
if (relativeError < relativeOptimalError) {
mulFracDivOptimal = mulFracDiv;
dividerAddOptimal = dividerAddFracDiv;
dividerOptimal = divider;
relativeOptimalError = relativeError;
if (relativeError == 0)
break;
}
}
}
if (relativeError == 0)
break;
}
if (relativeOptimalError
< ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR)/100)) {
UART0->LCR |= DLAB_ENABLE;
UART0->DLM = (unsigned char) ((dividerOptimal >> 8) & 0xFF);
UART0->DLL = (unsigned char) dividerOptimal;
UART0->LCR &= ~DLAB_ENABLE;
UART0->FDR = ((mulFracDivOptimal << 4) & 0xF0) | (dividerAddOptimal
& 0x0F);
errorStatus = 0; //< Success
}
// Enable TX and RX FIFO
UART0->FCR |= FIFO_ENABLE;
// Set FIFO to trigger when at least 14 characters available
UART0->FCR |= (3 << 6);
// Enable UART RX interrupt (for LPC17xx UART)
UART0->IER = RBR_IRQ_ENABLE;
// Enable the UART interrupt (for Cortex-CM3 NVIC)
NVIC_EnableIRQ(UART0_IRQn);
}
和它的作品!
我必須經歷,看看我錯了什麼。我懷疑寄存器設置的順序是關閉的。
對於25MHz的pclk和波特率115200,DLest出來到13.56。用戶手冊中有一個使用12MHz和115200的例子,它給出了我計算出的DLest的大約一半。所以我知道這個部分是有效的。我認爲我的pclk實際上並沒有設置爲cclk/4,但我是這個平臺的新手,並且無法確定一個堅如磐石的測試來確定這一點。 – michael 2010-09-10 22:34:34
您是否看過恩智浦爲lpc17xx設備提供的CMSIS庫? – 2010-09-10 23:58:36
實際上,現在我將100MHz除以4而不是4,波特率爲2 * 892.9 – michael 2010-09-11 00:07:40