Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F103C8+USART+LL
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
manul78
День добрый всем !

Для быстрого старта использую CubeMX. При генерации кода использую исключительно библиотеку Low Layer (LL)
Работал с STM32 F0, а конкретно с простейшим STM32F030F4 - всё работало как часы. Никаких проблем.
Для МК STM32F103 библиотеки LL не было, поэтому обходился шаблонами SPL и не парился.
Но вот в январе этого года вышло обновление для CubeMX, куда добавили генерацию кода LL и для STM32F103
Решил попробовать и никак. Какие-то видимо проблемы с установкой регистров GPIO при настройке USART1
Смотрю дебаггером - в установках порта не меняются биты регистра CRH порта GPIOA.
В битах MODE9 и CNF9 0x00 и 0x01 соответственно, то есть 9-я нога порта GPIOA (USART TX) сконфигурирована на ВХОД с Открытым стоком.
Процедура инициализации в LL:

Код
static void MX_USART1_UART_Init(void)
{

  LL_USART_InitTypeDef USART_InitStruct;

  LL_GPIO_InitTypeDef GPIO_InitStruct;

  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
  
  /**USART1 GPIO Configuration  
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  LL_USART_Init(USART1, &USART_InitStruct);

  LL_USART_ConfigAsyncMode(USART1);

  LL_USART_Enable(USART1);

}


После инициализации USART - регистры USART настраиваются как надо. A вот пин 9 (TX) порта GPIOA остаётся в том-же состоянии. На ВХОД с
открытым стоком. Хотя должно быть в битах MODE9 и CNF9 0x01 и 0x02 то есть Порт А на ВЫХОД 10 Мгц и АЛЬТЕРНАТИВНЫЙ ВЫХОД Push-Pull

Что такое - не понимаю. Ради интереса открыл старый проект на STM32 F030F4 и посмотрел процедуру инициализации - она немного другая. И всё работает. Полез посмотреть драйвер для stm32f1xx_ll_gpio.c разумеется он отличается. Сильно упрощен.
Для примера привожу код процедуры инициализации USART для библиотеки LL и STM32 F0, он 100% рабочий.

Код
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{

  LL_USART_InitTypeDef USART_InitStruct;

  LL_GPIO_InitTypeDef GPIO_InitStruct;

  /* Peripheral clock enable */
  LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1);
  
  /**USART1 GPIO Configuration  
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USART1 interrupt Init */
  NVIC_SetPriority(USART1_IRQn, 0);
  NVIC_EnableIRQ(USART1_IRQn);

  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART1, &USART_InitStruct);

  LL_USART_DisableIT_CTS(USART1);

  LL_USART_EnableOverrunDetect(USART1);

  LL_USART_EnableDMADeactOnRxErr(USART1);

  LL_USART_ConfigAsyncMode(USART1);

  LL_USART_Enable(USART1);

}


Но он более насыщенный чем для F103.

Где грабли ? Всю башку сломал....
Заранее благодарен за ответы.


UPD. Меняю в дебаггере биты настройки порта вручную - всё заработало... sad.gif






Видимо какие-то глюки в программных настройках порта. Кривая библиотека что-ли ? wacko.gif
manul78
Цитата(manul78 @ Jan 26 2018, 10:49) *
Видимо какие-то глюки в программных настройках порта. Кривая библиотека что-ли ? wacko.gif



UPD:

Разобрался, но не совсем... sad.gif

При помощи "говна и палок" запустил таки. Пришлось использовать для инициализации портов столь ненавистный мне HAL... Его драйвер рабочий.

Код
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA11 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}


Ну а потом закомментировать в инициализации USART1 настройки порта при помощи LL драйвера.

Код
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{

  LL_USART_InitTypeDef USART_InitStruct;

  //LL_GPIO_InitTypeDef GPIO_InitStruct;

  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
  
  /**USART1 GPIO Configuration  
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  
    //GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  //GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  //GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  //GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  //LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  //GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  //GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
  //LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  LL_USART_Init(USART1, &USART_InitStruct);

  LL_USART_ConfigAsyncMode(USART1);

  LL_USART_Enable(USART1);

}


Вот ТАКОЙ гибрид получился. Унылый. Но работает.
Виноват кривой LL драйвер портов GPIO. Где конкретно грабли в stm32f1xx_ll_gpio.c или в stm32f1xx_ll_gpio.h пока не знаю.
Знаю только что библиотека кривая. Пол года уже.
author MCD Application Team
version V1.1.1
date 12-May-2017
GPIO LL module driver.

Привет компании STM и MCD Application Team... sm.gif

Тему не закрываю. Постараюсь найти где именно ошибка. Если кто-то уже налетал на эти грабли - пишите, чтобы другие не наступали.

P.S. Кто-то разумеется спросит: "Зачем мне это нужно ? ". Отвечаю. Почти год писал для STM32F030F4 исключительно используя библиотеку LL, привык, код компактный, всё понятно.
Никаких нареканий не было. Честно, говоря она мне даже нравится. sm.gif
adnega
Цитата(manul78 @ Jan 26 2018, 14:30) *
P.S. Кто-то разумеется спросит: "Зачем мне это нужно ? ". Отвечаю. Почти год писал для STM32F030F4 исключительно используя библиотеку LL, привык, код компактный, всё понятно.
Никаких нареканий не было. Честно, говоря она мне даже нравится. sm.gif

Потерять на запуск USART день и говорить, что "мне даже нравится". Чего-то я не пойму плюсов от таких библиотек.
Код
//-----------------------------------------------------------------------------
//    void init_USART1(void)
//-----------------------------------------------------------------------------
void init_USART1(void)
{
    if(rcc_state == RCC_STATE_PLL)
        USART1->BRR = FPLL / CONSOLE_BAUD;
    else
        USART1->BRR = FHSI / CONSOLE_BAUD;
    USART1->CR1 =
          (1 << USART_CR1_UE)
        | (1 << USART_CR1_TE)
        | (1 << USART_CR1_RE)
        | (1 << USART_CR1_RXNEIE);
    USART1->CR2 = 0;
    USART1->CR3 = 0;
}
jcxz
Цитата(adnega @ Jan 26 2018, 14:52) *
Потерять на запуск USART день и говорить, что "мне даже нравится". Чего-то я не пойму плюсов от таких библиотек.

Ага! Всего лишь открыв UM и прочитав описание 7 регистров всё запускается за полчаса с нуля.
А тут - мегатонна "библиотек", куча костылей и кое-как закостылили такую простую вещь как UART. А при следующем чихе опять всё упадёт.... biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.