Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2017-дек-17 09:05

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: UART проблеммы
СообщениеДобавлено: 2016-ноя-07 09:45 
Не в сети

Зарегистрирован: 2016-июн-21 21:35
Сообщения: 5
Возникла проблемма с UART. При использование старой библиотеке (не mdr) принимаются нормальные данные. Но при использовании библиотеке mdr принимаются неверный данные (мусор). Настройки не изменял. В чем может быть проблемма?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2016-ноя-15 19:28 
Не в сети

Зарегистрирован: 2011-ноя-22 21:39
Сообщения: 36
Откуда: Тула, КБП
milander писал(а):
Но при использовании библиотеке mdr принимаются неверный данные (мусор).
В чем может быть проблемма?

Прием мусора из за неправильной скорости скорее всего.

_________________
 ‌   ‌  __________
___/_#_(О)_**_\____
[==]\________/[==]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-авг-31 00:52 
Не в сети

Зарегистрирован: 2014-сен-16 11:58
Сообщения: 74
У меня точно такая же проблема, я решил не создавать новую тему.
Код:
int main()
{
   unsigned char led = 0;
   init_clock();
   init_led();
   led_set(0);

   init_usart();
   usart_tx("", 0);
   usart_tx("=====", 5);
   while(1)
   {
      led_set(led);
      led++;
      if(led > 7) led = 0;
      usart_tx_byte(0x30 + led);
      delay_ms(100);
   }
}
А вот код настройки. У меня есть отладочная плата от LDM, так вот на ней от кварца 8 МГц на тактовой 80 МГц код UART работал отлично, и задержки мигания светодиодов вначале ровно секунда (по осциллу видно). Так вот в новой версии вижу те же задержки. У меня кварц на своей плате 16 МГц, так я поставил RST_CLK_CPU_PLLsrcHSEdiv2 RST_CLK_CPU_PLLmul10 делим на 2 и умножаем на 10 - вот наши 80 МГц снова.
Открыть "инициализация..."
Код:
void init_led()
{
   MDR_PORTB->OE     = 0x0000000F;
   MDR_PORTB->FUNC   = 0x00000000;
   MDR_PORTB->ANALOG = 0x0000FFFF;
   MDR_PORTB->PULL   = 0x0F;
   MDR_PORTB->PD     = ~(0x0F);
   MDR_PORTB->PWR    = 0x55555555;
   MDR_PORTB->GFEN   = 0;
   MDR_PORTB->RXTX   = 0x0000;
}

void led_set(unsigned char value)
{
   int i;
   for(i = 0; i < 3; i++)
   {
      if(value & (1<<i)) MDR_PORTB->RXTX |= (1<<(i + 1));
      else MDR_PORTB->RXTX &= ~(1<<(i + 1));
   }
}

void init_usart()
{
   PORT_InitTypeDef port;
   UART_InitTypeDef usart;
   
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_UART1, ENABLE);
   UART_BRGInit(MDR_UART1, UART_HCLKdiv1);
   
   PORT_StructInit(&port);
   port.PORT_PULL_UP = PORT_PULL_UP_OFF;
   port.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;
   port.PORT_PD_SHM = PORT_PD_SHM_OFF;
   port.PORT_PD = PORT_PD_DRIVER;
   port.PORT_GFEN = PORT_GFEN_OFF;
   port.PORT_FUNC = PORT_FUNC_ALTER;
   port.PORT_SPEED = PORT_SPEED_MAXFAST;
   port.PORT_MODE = PORT_MODE_DIGITAL;

   port.PORT_OE = PORT_OE_OUT;
   port.PORT_Pin = PORT_Pin_5;
   PORT_Init(MDR_PORTB, &port);

   port.PORT_OE = PORT_OE_IN;
   port.PORT_Pin = PORT_Pin_6;
   PORT_Init(MDR_PORTB, &port);

   usart.UART_BaudRate = 9600;
   usart.UART_WordLength = UART_WordLength8b;
   usart.UART_StopBits = UART_StopBits1;
   usart.UART_Parity = UART_Parity_No;
   //usart.UART_FIFOMode = UART_FIFO_ON;
   usart.UART_FIFOMode = UART_FIFO_OFF;
   usart.UART_HardwareFlowControl = UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;
   //usart.UART_HardwareFlowControl = UART_HardwareFlowControl_None;

   UART_Init(MDR_UART1, &usart);
   UART_Cmd(MDR_UART1, ENABLE);
}

unsigned char usart_receive(char *ok)
{
   char timeout = 100;
   *ok = 0;
   while((!(MDR_UART1->FR & (1<<6))) && (timeout > 0))
   {
      delay_10us(1);
      timeout--;
   }
   if(timeout > 0)
   {
      *ok = 1;
      return (MDR_UART1->DR & 0xFF);
   }
   return 0;
}

void usart_tx_byte(const char data)
{
   while(!(MDR_UART1->FR & (1UL << 7)));
   MDR_UART1->DR = (data & 0xFF);
}

void uart_tx_buffer(unsigned char *buf, unsigned char size)
{
   unsigned char i = 0;
   for(i = 0; i < size; i++)
   {
      usart_tx_byte(buf[i]);
   }
}

void usart_t(char *str, int len)
{
   int i;
   for(i = 0; i < len; i++) usart_tx_byte(str[i]);
}

void usart_tx(char *str, int len)
{
   int i;
   for(i = 0; i < len; i++) usart_tx_byte(str[i]);
   usart_tx_byte(0x0D);
   usart_tx_byte(0x0A);
}

void init_clock()
{
   NVIC->ICPR[0] = 0xFFFFFFFF;
   NVIC->ICER[0] = 0xFFFFFFFF;
   MDR_DMA->CHNL_REQ_MASK_CLR = 0xFFFFFFFF;
   MDR_DMA->CHNL_USEBURST_CLR = 0xFFFFFFFF;

   RST_CLK_HSEconfig(RST_CLK_HSE_ON);
   while(RST_CLK_HSEstatus() != SUCCESS);
   //!!!RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul10);
   RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv2, RST_CLK_CPU_PLLmul10); // quartz 16 MHz
   RST_CLK_CPU_PLLcmd(ENABLE);
   if(RST_CLK_CPU_PLLstatus() == ERROR) while(1);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
   RST_CLK_CPU_PLLuse(ENABLE);
   RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);
   RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_SSP2, ENABLE);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTD, ENABLE);
}
Закрыть

Тем не менее на любых скоростях, пробовал 115200, 57600, 9600 - везде по осциллографу вижу биты правильные при посылке (перед UART->USB-UART), но скорость неверная. Для 9600 она в 2.25 раза выше, судите сами: на картинке осциллограмма (шум не знаю откуда, не должен мешать, на питании такого не вижу).
Тут где-то 46 мкс на бит: 1÷(46×10^−6) = 21739 = 2,26 * 9600.

Разумеется комп принимает мусор: подозреваю аппаратную ошибку, либо ошибку в библиотеке, которая считает эти делители. Я так понимаю, библиотека сама видит настройки делителей и подстраивает под мои usart.UART_BaudRate = 9600;

Прошу помощи, не знаю как отладить, у мну нету JTAG, я вообще-то на этот UART полагался :)
Когда я пробовал перекинуться на UART по которому шьюсь, кажется была такая же проблема - байты шли, но билибердовые. Только я тогда не догадался осциллом смотреть.


Вложения:
milandr_failed_baud.png
milandr_failed_baud.png [ 11.39 КБ | Просмотров: 790 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-авг-31 08:37 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1039
Откуда: Тула
Скорее всего не все настройки в проекте или конфигурационных файлах заданы правильно.
Так библиотека вычисляет скорость ядра от значения, определённого HSE_Value, у Вас оно 16 МГц во втором случае?
Вообще, по возможности всегда стоит ознакамливаться с кодом используемых библиотек.
Так например в MDR32F9Qx_uart.c считаются делители.
Код:
   /* Determine the integer part */
   divider = cpuclock / (UART_InitStruct->UART_BaudRate >> 2);
   integerdivider = divider >> 6;
   /* Determine the fractional part */
   fractionaldivider = (divider & FBRD_Fract_Mask);

Хотя в спецификации они считаются иначе: BAUDDIV = FUARTCLK/(16 * Baud_rate) и даже есть пример на уровне ученика 5 класса.

Например я считаю делители так:
Открыть
Код:
void uart1_init()
{
    uint32_t temp;

    MDR_RST_CLK->PER_CLOCK |= RST_CLK_PER_CLOCK_PCLK_EN_UART1; //тактирование UART1
    temp = MDR_RST_CLK->UART_CLOCK;
    temp &= ~0xFFUL; // установка делителя для UART_CLK = HCLK/1
    temp |= RST_CLK_UART_CLOCK_UART1_CLK_EN;  // разрешение тактовой частоты UART1
    MDR_RST_CLK->UART_CLOCK = temp;
    // pg 338
    // Параметры делителя при частоте = 16000000 Гц и скорости = 38 400 бит/с
//    MDR_UART1->IBRD = 0x1A; //целая часть делителя скорости
//    MDR_UART1->FBRD = 0x3; //дробная часть делителя скорости
    // BRD = (128*CLK / (16*BAUD) = 8*CLK/BAUD) / 128
    // математика с фиксированной точкой на 7 разрядов
    temp = (8*SystemCoreClock)/UART1_BAUDRATE;
    if(temp & 1)
        temp += 1;
      MDR_UART1->IBRD=temp>>7;
    MDR_UART1->FBRD = (temp>>1)&0x3F;

    MDR_UART1->LCR_H =((0 << 1) // разрешение проверки четности
                      |(0 << 2) // четность/нечетность (Нет контроля)
                      |(0 << 3) // стоп-бит = 1 стоп-бит
                      |(1 << 4) // разрешение работы FIFO RX&TX
                      |(3 << 5) // длина слова = 8 бит
                      |(0 << 7)); // передача бита четности

      MDR_UART1->IFLS = (4<<3)|4; //
      MDR_UART1->IMSC = UART_IMSC_RTIM  // тайм-аут
                      | UART_IMSC_RXIM; // приём (с учётом фифо)
    MDR_UART1->CR = ((1 << 8)|(1 << 9)|1);
    //передачик и приемник разрешен, разрешение работы приемопередатчика
      NVIC_EnableIRQ(UART1_IRQn);
}
Закрыть

Но для этого обязательно надо определить HSE_Value и вызвать SystemCoreClockUpdate() после настройки тактирования. Всё это дело работает на FUARTCLK = HCLK.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-авг-31 20:41 
Не в сети

Зарегистрирован: 2014-сен-16 11:58
Сообщения: 74
prostoRoman писал(а):
Но для этого обязательно надо определить HSE_Value и вызвать SystemCoreClockUpdate() после настройки тактирования. Всё это дело работает на FUARTCLK = HCLK.
Исправил HSE_Value и сделал RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul5);
Теперь осциллограф на скоростях 9600 и 115200 всегда говорит об ошибке 8.5%, причем ровно на 8 с половиной процентов скорость выше по факту чем запрошенная.
Попробую использовать Ваш код настройки.

У меня есть подозрение, что мой кварц, хоть на нем и 16.000 написано, но МК с ним работает не с той частотой. Есть такая вероятность. Потому что чудес не бывает. Я даже вручную считал эти I/FBDR и четко ставил - все равно неверная скорость, и к тому же:
Код:
   usart.UART_BaudRate = 115200;
   usart.UART_WordLength = UART_WordLength8b;
   usart.UART_StopBits = UART_StopBits1;
   usart.UART_Parity = UART_Parity_No;
   usart.UART_FIFOMode = UART_FIFO_OFF;
   usart.UART_HardwareFlowControl = UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;
   UART_Init(MDR_UART1, &usart);
   MDR_UART1->IBRD = 43;
   MDR_UART1->FBRD = 26;
   UART_Cmd(MDR_UART1, ENABLE);

80 000 000 / (16 * 115200) = 43,402777778 = 43 @ 26


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-сен-01 08:08 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1039
Откуда: Тула
Подозрение обязательно надо проверить - настроить таймер на счёт до ARR=999 при предделителях 1 и вывести шим на ножку.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-сен-06 23:18 
Не в сети

Зарегистрирован: 2014-сен-16 11:58
Сообщения: 74
prostoRoman писал(а):
Подозрение обязательно надо проверить - настроить таймер на счёт до ARR=999 при предделителях 1 и вывести шим на ножку.

Моя проблема теперь решена - я просто запаял другой кварц на 8.000 МГц. Вся странность шла от кварца. Я не знаю что думать - то ли генератор в МК всё-таки плохо работает на своей предельной частоте 16 МГц, либо бракованный кварц (что маловероятно, их же тестируют, он был аккуратно запаян). Для себя пометил галочку что брать для Миландра только 8 МГц кварцы :) Честно, не принципиально ведь, ни по стоимости ни по любой другой причине.

Единственная разница... Старый кварц был высокий, а новый в 4-5 раз ниже (ниже не видел в природе). Может там конденсаторы неверные были, их ведь не от балды номинал ставят...

P.S. Почему от внутреннего RC нормально не работало - останется загадкой, однако у меня была еще одна проблема - мощные помехи по питанию от регулятора (пока подал напрямую 3.3В на схему), так что питание было с пилообразной помехой. Моя догадка что это могло сбивать частоту встроенного RC-генератора.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-сен-07 00:50 
Не в сети

Зарегистрирован: 2016-окт-14 19:39
Сообщения: 31
Откуда: СПБ
У меня на платах от LDM-Systems кварцы почему-то на 16 МГц. Работает без проблем (обе две платы). Правда, разгонял только до 64 МГц. Конденсаторы у кварца по 12 пФ. А от встроенного RC генератора и не обязано стабильно работать, большой разброс частоты.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-сен-08 11:44 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1039
Откуда: Тула
LinuxFanatic писал(а):
...однако у меня была еще одна проблема - мощные помехи по питанию от регулятора (пока подал напрямую 3.3В на схему), так что питание было с пилообразной помехой. Моя догадка что это могло сбивать частоту встроенного RC-генератора.
И частоту и, особенно, PLL на больших множителях. Загляните в эррату на эту тему (не помню, кажется подвержены этому и ве1 и ве9х).

Ещё высокочастотные кварцы обычно рассчитаны на работу на ГАРМОНИКЕ, третьей или пятой. Для стабильной и надёжной работы им нужен LC контур на частоту требуемой гармоники...

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART проблеммы
СообщениеДобавлено: 2017-сен-09 12:41 
Не в сети

Зарегистрирован: 2014-сен-16 11:58
Сообщения: 74
prostoRoman писал(а):
И частоту и, особенно, PLL на больших множителях. Загляните в эррату на эту тему (не помню, кажется подвержены этому и ве1 и ве9х)
Да, так и есть, прям эррата категория 2. Чем отличается профессионал от дилетанта - тем, что первый начинает с эрраты, а ламер заканчивает на эррате как я :)
МК оказался ни при чем, совпало сразу несколько факторов - неверные номиналы конденсаторов для выбранного ранее кварца (ибо сбой частоты не пропал даже после нормализации питаний путем прямой подачи 3.3 В на схему), а про помехи по вине регулятора и говорить не приходится :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Bing [Bot] и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB