Миландр
https://forum.milandr.ru/

1986ВЕ1Т, коэффициент деления для UART
https://forum.milandr.ru/viewtopic.php?f=34&t=3924
Страница 1 из 1

Автор:  Dmitry_S [ 2018-окт-03 14:39 ]
Заголовок сообщения:  1986ВЕ1Т, коэффициент деления для UART

Доброго времени суток.

Имеется плата LDM-HELPER-K1986BE1QI-FULL от LDM-Systems.

При настройке UART1 возникла проблема с подбором коэффициента деления.
Если вычислять его способом, указанным в описании, то получается:

F_UART = ~8 МГц (HSITRIM = 22).
Требуемая скорость - 115200 бод.

m = 8000000 / (16 * 115200) = 4,34.
IRBD = 4.
FRBD = integer((0,34 * 64) + 0,5) = 22 (При использовании функции UART_init из SPL получается 21).
"Реальная" скорость с этим коэффициентом(4 и 22) должна получиться 115107 бод.

При попытке передачи данных между компьютером и контроллером были получены следующие результаты:

Длина слова - 8 бит,
1 стоповый бит,
без проверок четности и FIFO.
Передаваемое значение - 0x55 в обе стороны (выбрано для наглядности).

При просмотре линии приемника МК с помощью осциллографа получается:
Открыть
Вложение:
[ attachment ]
uart PC-MK 115200.BMP [ 76.05 КБ | 2951 просмотр ]
9 бит(не считая стоп-бита) со стороны компьютера передаются примерно за 78 мкс. Это соответствует скорости передачи ~115380 бод.
Закрыть
При просмотре линии передатчика МК получается:
При IRBD = 4, FRBD = 22:
Открыть
Вложение:
[ attachment ]
TEK0001.BMP [ 76.05 КБ | 2951 просмотр ]
9 бит(не считая стоп-бита) передаются примерно за 60 мкс. Это соответствует скорости передачи ~150000 бод.
Закрыть
При этом слово принимается некорректно обеими сторонами.

Если же выставить больший коэффициент(в данном случае IRBD = 5, FRBD = 40), то получится:
Открыть
Вложение:
[ attachment ]
TEK0002.BMP [ 76.05 КБ | 2951 просмотр ]
9 бит(не считая стоп-бита) передаются примерно за 78 мкс, что аналогично линии приемника при передаче от компьютера.
Закрыть
При этом слово принимается корректно обеими сторонами.

Хотелось было попросить помощи чтобы узнать причину. Вполне возможно что я настраиваю что-то неправильно, поэтому архив с проектом во вложении (Используется GNU MCU Eclipse).
Заранее спасибо.

Вложения:
MDR1986BE1T.tar.gz [565.14 КБ]
528 скачиваний

Автор:  ЧумА [ 2018-окт-03 16:27 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Похоже, что Вы UART тактируете от HSI (т.е. внутреннего RC-генератора), а его начальная уставка и стабильность ±1 км :).

Автор:  Dmitry_S [ 2018-окт-03 16:51 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

ЧумА писал(а):
Похоже, что Вы UART тактируете от HSI (т.е. внутреннего RC-генератора), а его начальная уставка и стабильность ±1 км :).
Тактируется от HSI, поэтому и указал что HSITRIM = 22, что должно соответствовать 8 МГц.

Если, например, использовать SSP с делителями 8(SSP1BRG) и 2(CPSR), то сигналы выдаются с частотой примерно 500 кГц. Тоже тактируется от HSI:
Открыть
Вложение:
[ attachment ]
ssp(HSITRIM=22, делитель 16).BMP [ 76.05 КБ | 2938 просмотров ]
Закрыть

Автор:  vasili [ 2018-окт-03 17:29 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Dmitry_S писал(а):
...архив с проектом во вложении (Используется GNU MCU Eclipse).
Заранее спасибо.
Вызывает сомнение строка
MDR_UART1->LCR_H |= 0x60;
попробуйте
MDR_UART1->LCR_H = 0x60;

Автор:  ЧумА [ 2018-окт-03 17:48 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Цитата:
Тактируется от HSI, поэтому и указал что HSITRIM = 22, что должно соответствовать 8 МГц.
Для UART допустимое отклонение скорости примерно ±2...3%. В диапазоне отклонения напряжения питания и температур отклонение может быть больше. Т.е. "на столе" подстроиться можно, а в серии сомнительно. И зачем, если на LDM-овском модуле есть кварцевый резонатор?

Автор:  Dmitry_S [ 2018-окт-04 11:02 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

vasili писал(а):
Вызывает сомнение строка
MDR_UART1->LCR_H |= 0x60;
попробуйте
MDR_UART1->LCR_H = 0x60;
Ничего не изменилось (LCR_H = 0x00 после сброса, поэтому и не должно было измениться). Контроллер отправляет 0x01, компьютер принимает 0xC1.
Открыть
Вложение:
[ attachment ]
TEK0003.BMP [ 76.05 КБ | 2909 просмотров ]
Закрыть
Поменял свой код на тот, что был в примере к SPL - тоже ничего не поменялось.

Автор:  prostoRoman [ 2018-окт-04 11:49 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Попробуйте поменять эти строки
	init_UART();
	MDR_RST_CLK->TIM_CLOCK = 0x01000000;
	MDR_RST_CLK->UART_CLOCK = 0x01000000;
на такой вид:
	MDR_RST_CLK->TIM_CLOCK = 0x01000000;
	MDR_RST_CLK->UART_CLOCK = 0x01000000;
	init_UART();

Автор:  Dmitry_S [ 2018-окт-04 12:00 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

prostoRoman писал(а):
Попробуйте поменять эти строки
	init_UART();
	MDR_RST_CLK->TIM_CLOCK = 0x01000000;
	MDR_RST_CLK->UART_CLOCK = 0x01000000;
на такой вид:
	MDR_RST_CLK->TIM_CLOCK = 0x01000000;
	MDR_RST_CLK->UART_CLOCK = 0x01000000;
	init_UART();
Поменял, при этом REG_0F поставил перед TIM_CLOCK. Не помогло.

Автор:  prostoRoman [ 2018-окт-04 12:43 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Что-то ничего умнее, чем замерить реальную тактовую частоту в голову не приходит.
Лучше всего это делать через таймер в режиме ШИМ с PSG=0; ARR=999; и CCR=499; с выводом меандра на ножку.

UPD: а так же переключиться на внешний кварц и попробовать с ним.

Автор:  Dmitry_S [ 2018-окт-04 14:21 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

prostoRoman писал(а):
Что-то ничего умнее, чем замерить реальную тактовую частоту в голову не приходит.
Лучше всего это делать через таймер в режиме ШИМ с PSG=0; ARR=999; и CCR=499; с выводом меандра на ножку.
С ARR=999 и CCR=499 должно получиться 8 кГц(СLK / ARR) при использовании внутреннего генератора? Получается 7,8, если я ничего не путаю.
Открыть
Вложение:
[ attachment ]
TEK0005.BMP [ 76.05 КБ | 2887 просмотров ]
Закрыть
Использовал этот пример к SPL:
Открыть
/* Includes ------------------------------------------------------------------*/
#include "MDR32F9Qx_config.h"
#include "MDR32F9Qx_timer.h"
#include "MDR32F9Qx_rst_clk.h"
#include "MDR32F9Qx_port.h"

/** @addtogroup __MDR32F9Qx_StdPeriph_Examples MDR32F9Qx StdPeriph Examples
* @{
*/

/** @addtogroup __MDR1986VE1T_EVAL MDR1986VE1T Opora Evaluation Board
* @{
*/

/** @addtogroup TIMER_5PWM_Output_1T TIMER_5PWM_Output
* @{
*/

/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIMER_CntInitTypeDef sTIM_CntInit;
TIMER_ChnInitTypeDef sTIM_ChnInit;
TIMER_ChnOutInitTypeDef sTIM_ChnOutInit;
PORT_InitTypeDef PORT_InitStructure;

uint16_t CCR1_Val = 499;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
* @brief Main program
* @param None
* @retval None
*/
#ifdef __CC_ARM
int main(void)
#else
void main(void)
#endif
{
RST_CLK_DeInit();
RST_CLK_CPU_PLLconfig (RST_CLK_CPU_PLLsrcHSIdiv1,0);
/* Enable peripheral clocks --------------------------------------------------*/
RST_CLK_PCLKcmd((RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_TIMER4),ENABLE);
RST_CLK_PCLKcmd((RST_CLK_PCLK_PORTA | RST_CLK_PCLK_BKP), ENABLE);

MDR_BKP->REG_0F |= 0x16000000;

/* Reset PORTB settings */
PORT_DeInit(MDR_PORTA);

/* Configure TIMER4 pins: CH1, CH1N, CH2, CH2N, CH3 */
/* Configure PORTA pins 6, 7, 8, 9, 10 */
PORT_InitStructure.PORT_Pin = (PORT_Pin_6);
PORT_InitStructure.PORT_OE = PORT_OE_OUT;
PORT_InitStructure.PORT_FUNC = PORT_FUNC_ALTER;
PORT_InitStructure.PORT_MODE = PORT_MODE_DIGITAL;
PORT_InitStructure.PORT_SPEED = PORT_SPEED_MAXFAST;
PORT_InitStructure.PORT_PD = PORT_PD_DRIVER;
PORT_Init(MDR_PORTA, &PORT_InitStructure);

/* Reset all TIMER1 settings */
TIMER_DeInit(MDR_TIMER4);

/* TIM1 Configuration ---------------------------------------------------
Generates 5 PWM signals with 4 different duty cycles:
TIM1CLK = 8 MHz, Prescaler = 0, TIM1 counter clock = 8 MHz
TIM1 frequency = TIM1CLK/(TIM1_Period + 1) = 1.95 KHz
- TIM1 Channel1 & Channel1N duty cycle = TIM1->CCR1 / (TIM1_Period + 1) = 50%
- TIM1 Channel2 & Channel2N duty cycle = TIM1->CCR2 / (TIM1_Period + 1) = 25%
- TIM1 Channel3 duty cycle = TIM1->CCR3 / (TIM1_Period + 1) = 12.5%
----------------------------------------------------------------------- */

/* Initializes the TIMERx Counter ------------------------------------*/
sTIM_CntInit.TIMER_Prescaler = 0x0;
sTIM_CntInit.TIMER_Period = 999;
sTIM_CntInit.TIMER_CounterMode = TIMER_CntMode_ClkFixedDir;
sTIM_CntInit.TIMER_CounterDirection = TIMER_CntDir_Up;
sTIM_CntInit.TIMER_EventSource = TIMER_EvSrc_None;
sTIM_CntInit.TIMER_FilterSampling = TIMER_FDTS_TIMER_CLK_div_1;
sTIM_CntInit.TIMER_ARR_UpdateMode = TIMER_ARR_Update_Immediately;
sTIM_CntInit.TIMER_ETR_FilterConf = TIMER_Filter_1FF_at_TIMER_CLK;
sTIM_CntInit.TIMER_ETR_Prescaler = TIMER_ETR_Prescaler_None;
sTIM_CntInit.TIMER_ETR_Polarity = TIMER_ETRPolarity_NonInverted;
sTIM_CntInit.TIMER_BRK_Polarity = TIMER_BRKPolarity_NonInverted;
TIMER_CntInit (MDR_TIMER4,&sTIM_CntInit);

/* Initializes the TIMER1 Channel 1,1N,2,2N,3 ------------------------------*/
TIMER_ChnStructInit(&sTIM_ChnInit);

sTIM_ChnInit.TIMER_CH_Mode = TIMER_CH_MODE_PWM;
sTIM_ChnInit.TIMER_CH_REF_Format = TIMER_CH_REF_Format6;
sTIM_ChnInit.TIMER_CH_Number = TIMER_CHANNEL1;
TIMER_ChnInit(MDR_TIMER4, &sTIM_ChnInit);

TIMER_SetChnCompare(MDR_TIMER4, TIMER_CHANNEL1, CCR1_Val);

/* Initializes the TIMER1 Channel 1,1N,2,2N,3 Output -----------------------*/

TIMER_ChnOutStructInit(&sTIM_ChnOutInit);

sTIM_ChnOutInit.TIMER_CH_DirOut_Polarity = TIMER_CHOPolarity_NonInverted;
sTIM_ChnOutInit.TIMER_CH_DirOut_Source = TIMER_CH_OutSrc_REF;
sTIM_ChnOutInit.TIMER_CH_DirOut_Mode = TIMER_CH_OutMode_Output;
TIMER_ChnOutInit(MDR_TIMER4, &sTIM_ChnOutInit);

/* Enable TIMER1 clock */
TIMER_BRGInit(MDR_TIMER4,TIMER_HCLKdiv1);

/* Enable TIMER1 */
TIMER_Cmd(MDR_TIMER4,ENABLE);

while(1);
}
Закрыть
При частоте 7,8 МГц скорость передачи через UART при IRBD = 4 и FRBD = 22 должна быть 112200, что ниже требуемых 115200. А она выше почти на треть.

Сейчас попробую с внешним кварцем.

Автор:  Dmitry_S [ 2018-окт-04 15:54 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Добавил в main строки(в выложенном проекте их нет)

RST_CLK_DeInit();
RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSIdiv1,0);

и UART заработал так, как должен.

Автор:  vasili [ 2018-окт-05 15:20 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

Dmitry_S писал(а):
Добавил в main строки(в выложенном проекте их нет)

RST_CLK_DeInit();
RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSIdiv1,0);

и UART заработал так, как должен.
В Вашей ситуации непонятно почему частота на выходе SPI была правильной.

Автор:  Dmitry_S [ 2018-окт-09 12:00 ]
Заголовок сообщения:  Re: 1986ВЕ1Т, коэффициент деления для UART

vasili писал(а):
Dmitry_S писал(а):
Добавил в main строки(в выложенном проекте их нет)

RST_CLK_DeInit();
RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSIdiv1,0);

и UART заработал так, как должен.
В Вашей ситуации непонятно почему частота на выходе SPI была правильной.
В программе с SPI эти функции были.

Страница 1 из 1 Часовой пояс: UTC+03:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/