реклама на сайте
подробности

 
 
> Сбой приёма при низкой частоте тактирования uart, lpc17xx
mempfis_
сообщение Apr 11 2012, 14:19
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Всем добрый день. Столкнулся с непонятной проблемой.
Пытаюсь снизить Fcclk для снижения энергопотребления. Опустил до 2МГц. При этом пытаюсь настроить uart0 для работы на скорости 115200.
Задействовал дробный делитель, частота тактирования uart 1:1 Fcclk.
2000000/1843200 = 1,085
по таблице выбрал коэффициенты 1 и 12 что даёт 2000000/(1+1/12) = 1846153
настройки делителя U0DLM/U0DLL 1846153/(115200*16) = 1,001 т.е. 1
пересчёт на баудрайт даёт 1846153/16 = 115384 (погрешность (115384-115200)/115200 = 0,16 процента)

В итоге получаю:
- отправка данных идёт как положено
- приём со сбоем.

для теста сдела воврат эха из терминала - получаю кашу типа ff ff
вставил возврат двух символов - первый - то что принял, второй 'r'
получаю через один ff 'r' ff 'r'
иногда приходит 254

На входах все pullup/pulldown отключены, делители PCCLK0 не смотря на эррату меняются.
Проблема не пропадает вплоть до 10 МГц.
При поднятии Fcclk до 12Мгц всё работает абсолютно корректно.
К сожалению проверить работу с нормальным кварцем для uart нет возможности

Может кто встречался с такой проблемой и знает решаема ли она без поднятия частоты.
Привожу пример обработчика прерываний и инициализации уарт
CODE
void UART0_IRQHandler (void)
{

unsigned char IIRValue, LSRValue;
volatile unsigned char Dummy;


IIRValue = U0IIR;
IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if ( IIRValue == IIR_RLS ) /* Receive Line Status */
{
LSRValue = U0LSR;
/* Receive Line Status */
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
/* There are errors or break interrupt */
/* Read LSR will clear the interrupt */
Dummy = U0RBR; /* Dummy read on RX to clear interrupt, then bail out */


NVIC_ClrPend(NVIC_UART0);
return;
}

if ( LSRValue & LSR_RDR ) /* Receive Data Ready */
{
/* If no error on RLS, normal ready, save into the data buffer. */
/* Note: read RBR will clear the interrupt */

//приём завершён, ложим байт в фифо
Rx0Buf[Rx0Head++] = U0RBR;
if (Rx0Head >= US0_RXBUFSIZE) Rx0Head = 0;

}
}
else if ( IIRValue == IIR_RDA ) /* Receive Data Available */
{
/* Receive Data Available */

//приём завершён, ложим байт в фифо
Rx0Buf[Rx0Head++] = U0RBR;
if (Rx0Head >= US0_RXBUFSIZE) Rx0Head = 0;

}
else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */
{
/* Character Time-out indicator */
/* Bit 9 as the CTI error */
}
else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
LSRValue = U0LSR; /* Check status in the LSR to see if valid data in U3THR or not */
if ( LSRValue & LSR_THRE )
{

//передача байта завершена
if (Tx0Tail != Tx0Head)
{
U0THR = Tx0Buf[Tx0Tail++];
if (Tx0Tail >= US0_TXBUFSIZE) Tx0Tail = 0;
}
else
{
//запрещаем прерывания по опустошению передающего буффера
U0IER &= ~IER_THRE;
}

}
}

NVIC_ClrPend(NVIC_UART0);
return;
}


CODE
void UART0_init(unsigned int fcclk, unsigned int baudrate )
{
//разрешаем переферийное питание uart3
PCONP |= PCUART0;


//выбираем альтернативные ф-ии выводов
PINSEL0 |= TXD0_line_on|RXD0_line_on; /* RxD1 and TxD1 */

PCLKSEL0 &= ~UART0_div_msk;
PCLKSEL0 |= UART0_div_val_1;

U0LCR = DLC_ENA|STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */

unsigned int Fdiv, int_path, fract_path, res_frq;

//устанавливаем дробный делитель частоты и вычисляем результирующую частоту
//работаем на 2МГц
U0FDR = (1<<4)|(12<<0);
res_frq = (fcclk*12)/(1+12);


Fdiv = ((((10ul*res_frq)/Fcclk_UART0_div) / 16) / baudrate) ; /*baud rate */
int_path = Fdiv/10;
fract_path = Fdiv%10;
if(fract_path >= 5) int_path += 1;
Fdiv = int_path;

U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */
U0FCR = FIFO_LEV_0|RES_TX_FIFO|RES_RX_FIFO|FIFO_ENA; /* Enable and reset TX and RX FIFO. */

//инсталлируем обработчик прерываний
install_irq( NVIC_UART0, UART0_PRIO );

U0IER = IER_RBR | IER_RLS; /* Enable UART0 interrupt */
}


Сообщение отредактировал mempfis_ - Apr 11 2012, 14:22
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 19:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01357 секунд с 7
ELECTRONIX ©2004-2016