Skocz do zawartości

STM32 - problem z Serial'em


wn2001

Pomocna odpowiedź

Witam,

ostatnio bawię się płytką Kamami KA-NUCLEO-F411CE (i książka pana Kurczyka "Mikrokontrolery STM32 dla początkujących), pojawił się problem. Napisałem kilka programów, typu, migająca dioda, reagowanie na przycisk, w międzyczasie zaklinowało się złącze micro-usb, które musiałem wymienić - tu zaznaczam, wymieniłem je, programy wgrywają się i działają bez problemu. Przesyłam zrzut ekranu z programu STM32CubeMX i program main.c z Atollic True Studio. Program jest banalny, ma na Serialu przesyłać komunikat "Hello". Problem polega na tym, że próbowałem z PuTTy, wewnętrznym terminalu Atollic i monitorze portu Arduino IDE, dwie prędkości (9600 i 115200), dodawałem nawet błyśnięcie diodą na początku, aby upewnić się, że program wgrałem poprawnie (działało), ale na Serialu pusto, próbowałem z zamkniętym Atollic'iem, otwartym, po wgraniu odłączenie, ponowne podłączenie, niezależnie co próbowałem robić - na Serial'u pustka 😪😪😪

Czy komuś przychodzi coś do głowy? Jeszcze raz powtarzam - złącze jest wymienione, ale programy się wgrywają, oczywiście sprawdzałem port w Menedżer'ze Urządzeń, zawsze wykrywa poprawnie (poza pojedynczym przypadkiem "Nie wykryto urządzenia..." ) COM12 (oczywiście inny port USB też próbowałem). Liczę, że jest to błąd gdzieś w programie albo konfiguracji, chociaż kieruję się książką i sprawdzałem kilka razy konfiguracje Serial'a w CubeMX.

Pozdrawiam, z góry dziękuję za pomoc!

image.thumb.png.b6373cd08a2059acd4a2a0d1cb03dd15.png

PS Właściwy kod zaczyna się od linijki "/* USER CODE BEGIN 0 */"

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void uart_write(UART_HandleTypeDef * handler, char * text) {
	HAL_UART_Transmit(handler, text, strlen(text), 1000);
}

void uart_write_line(UART_HandleTypeDef * handler, char * text) {
	HAL_UART_Transmit(handler, text, strlen(text), 1000);
	HAL_UART_Transmit(handler, "\r\n", 2, 1000);
}

void uart_read_line(UART_HandleTypeDef * handler, char * buffer, uint16_t buffer_size) {
	HAL_StatusTypeDef status;
	char current_char;
	uint16_t char_counter = 0;

	while (char_counter < buffer_size -1) {
		status = HAL_UART_Receive(handler, &current_char, 1, 1);
		if (status == HAL_OK) {
			if (current_char == '\r' || current_char == '\n') {
				if (char_counter == 0) continue;
				else break;
			}
			*(buffer + char_counter++) = current_char;


		}
	}
	*(buffer + char_counter) = '\0';
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	  HAL_Delay(500);
	  uart_write_line(&huart2, "Hello");
    /* USER CODE BEGIN 3 */
	  HAL_Delay(500);
	  uart_write_line(&huart2, "Hello");
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 100;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, RGB_BLUE_Pin|RGB_RED_Pin|RGB_GREEN_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : USER_BNT_Pin */
  GPIO_InitStruct.Pin = USER_BNT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USER_BNT_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : RGB_BLUE_Pin RGB_RED_Pin RGB_GREEN_Pin */
  GPIO_InitStruct.Pin = RGB_BLUE_Pin|RGB_RED_Pin|RGB_GREEN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

Edytowano przez wn2001
Link do komentarza
Share on other sites

Dnia 29.03.2019 o 00:06, wn2001 napisał:

Witam,

Program jest banalny, ma na Serialu przesyłać komunikat "Hello". Problem polega na tym, że próbowałem z PuTTy, wewnętrznym terminalu Atollic i monitorze portu Arduino IDE, dwie prędkości (9600 i 115200), dodawałem nawet błyśnięcie diodą na początku, aby upewnić się, że program wgrałem poprawnie (działało), ale na Serialu pusto, próbowałem z zamkniętym Atollic'iem, otwartym, po wgraniu odłączenie, ponowne podłączenie, niezależnie co próbowałem robić - na Serial'u pustka 😪😪😪

Czy komuś przychodzi coś do głowy? Jeszcze raz powtarzam - złącze jest wymienione, ale programy się wgrywają, oczywiście sprawdzałem port w Menedżer'ze Urządzeń, zawsze wykrywa poprawnie (poza pojedynczym przypadkiem "Nie wykryto urządzenia..." ) COM12 (oczywiście inny port USB też próbowałem). Liczę, że jest to błąd gdzieś w programie albo konfiguracji, chociaż kieruję się książką i sprawdzałem kilka razy konfiguracje Serial'a w CubeMX.

Pozdrawiam, z góry dziękuję za pomoc!

Cześć,

nie ma w podanym kodzie inicjalizacji zegara dla USART2 (przynajmniej ja nie znalazłem). Można to zrobić tak np. :

__HAL_RCC_USART2_CLK_ENABLE();

lub

__USART2_CLK_ENABLE();

po drugie to co przychodzi mi na myśl to maksymalny czas opóźnienia dla funkcji: HAL_UART_Transmit

Kod:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void uart_write(UART_HandleTypeDef * handler, char * text) {
	HAL_UART_Transmit(handler, text, strlen(text), 1000);
}

void uart_write_line(UART_HandleTypeDef * handler, char * text) {
	HAL_UART_Transmit(handler, text, strlen(text), 1000);
	HAL_UART_Transmit(handler, "\r\n", 2, 1000);
}

wartości 1000 zamieniłbym na HAL_MAX_DELAY ,może po prostu masz timeout'y?

Tutaj funkcja inicjalizacji dla USART2:

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

Czyli np. w Putty ustawiasz dla portu COMx :

1) Prędkość 9600

2) Dlugość słowa 8 bitów

3) Bity stopu 1

4) bity parzystości brak

5) Kontrola sprzętowa transmisji - brak

Wypróbuj może kod z tego tutoriala i zobacz, czy będzie Ci działał:

https://visualgdb.com/tutorials/arm/stm32/uart/hal/

Pozdrawiam

Edytowano przez FlyingDutch
  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

@FlyingDutch Dziękuję za odpowiedź, sprawdzałem ten sam kod na płytce NucleoF103 i działał, oczywiście sprawdzę, tak jak napisałeś, tą z Kamami.

BTW Jaki program polecacie (darmowy) do programowania STM'ów? Atollic TrueStudio jest dobry czy coś innego? 🙂

Link do komentarza
Share on other sites

18 godzin temu, wn2001 napisał:

BTW Jaki program polecacie (darmowy) do programowania STM'ów? Atollic TrueStudio jest dobry czy coś innego? 🙂

Cześć,

ja poza pracą używam prywatnie "System Workbench for STM32" i jestem zadowolony (razem z darmowym STM32CubeMX). W pracy jestem zobligowany do używania jednego z komercyjnych IDE i kompilatora do programowania ARM, ale często do prototypowania kodu wolę użyć darmowego "System Workbench for STM32".

Jego dużą zaletą jest, że dobrze radzi sobie sobie z mieszanym kodem C/C++. Poza tym wiele lat programowałem w Eclipse (Java, C++) stąd Workbench oparty na Eclipse bardzo mi pasuje.

Pozdrawiam

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.