Skocz do zawartości

STM32F0 - UART i przerwanie od timerów - wykrzaczenia się programu


amilo_pa

Pomocna odpowiedź

Witam Panowie,

Próbuję odpalić komunikację UART wraz z Timerem i program się zacina na funkcji wysyłającej dane po UART.

Sytuacja wygląda następująco:

1. Mam ustawiony Timer na 10ms i w nim zapalam diodę:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM14){
	static uint16_t cnt =0;
	uint Data[50];
	uint16_t size;

	if(++cnt>99){		//gdy mineła sekunda
		s1_flag = TRUE;	//ustaw flagę tyknięca sekundy
		sekundy ++;		//zwiększ licznik sekund
		size = sprintf(Data, "Liczba sekund: %d.\r\n",sekundy);
		HAL_UART_Transmit_DMA(&huart1, Data, size);
		HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin);
		if(sekundy>59) sekundy =0;	//jeżeli czba sekund >59 - wyzeruj
		cnt =0;	//wyzeruj licznik ms
	}

}
}

W programie RealTerm ładnie wyświetlają liczba kolejnych sekund - czyli komunikacja działa

Wpisuje w programie RealTerm np 0. i program zawiesza się. Kod przerwania UART:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
static uint8_t Data[40]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size =0;
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
size = sprintf(Data, "Odebrana wiadomosc: %d.\r\n",40);
HAL_UART_Transmit_DMA(&huart, Data ,size);// Rozpoczecie nadawania danych z wykorzystaniem przerwan
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
HAL_UART_Receive_DMA(&huart1, Received, size_Received); // Ponowne włączenie nasłuchiwania
}

Program zacina się w linijce

 HAL_UART_Transmit_DMA(&huart, Data ,size);// Rozpoczecie nadawania danych z wykorzystaniem przerwa   

Po zacięciu przechodzi do biblioteki: stm32f0xx_it.c do linijki 69

/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
 /* USER CODE BEGIN HardFault_IRQn 0 */

 /* USER CODE END HardFault_IRQn 0 */
 while (1)
 {
 }
 /* USER CODE BEGIN HardFault_IRQn 1 */

 /* USER CODE END HardFault_IRQn 1 */
}

Poniżej cały kod programu main.c

/**
 ******************************************************************************
 * File Name          : main.c
 * Description        : Main program body
 ******************************************************************************
 *
 * COPYRIGHT(c) 2017 STMicroelectronics
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */
#define TRUE 1
#define FALSE 0
#define size_Received 1

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim14;
TIM_HandleTypeDef htim16;

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

uint8_t Received[size_Received];
uint8_t czujnik_cnt;		//liczba czujnikó na magistralii
volatile uint8_t s1_flag;	//flaga tyknięcia timera co 1 sekundę
volatile uint8_t sekundy;	//licznik sekund 0-59

uint8_t subzero, cal, cel_fract_bits;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM14_Init(void);
static void MX_TIM16_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);	//Funkcja obsługująca przerwania od timerów
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);		//Funkcja obsługująca przerwania do UARTa



/* USER CODE END PFP */

/* USER CODE BEGIN 0 */


/* USER CODE END 0 */

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();

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

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_USART1_UART_Init();
 MX_TIM14_Init();
 MX_TIM16_Init();

 /* USER CODE BEGIN 2 */
 HAL_TIM_BaseBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
   Error_Handler();
 }

}

/** 
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA1_Channel2_3_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

/** Configure pins as 
       * Analog 
       * Input 
       * Output
       * EVENT_OUT
       * EXTI
*/
static void MX_GPIO_Init(void)
{

 GPIO_InitTypeDef GPIO_InitStruct;

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

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, LED_BLUE_Pin|LED_GREEN_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pins : LED_BLUE_Pin LED_GREEN_Pin */
 GPIO_InitStruct.Pin = LED_BLUE_Pin|LED_GREEN_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM14){
	static uint16_t cnt =0;
	uint Data[50];
	uint16_t size;

	if(++cnt>99){		//gdy mineła sekunda
		s1_flag = TRUE;	//ustaw flagę tyknięca sekundy
		sekundy ++;		//zwiększ licznik sekund
		size = sprintf(Data, "Liczba sekund: %d.\r\n",sekundy);
		HAL_UART_Transmit_DMA(&huart1, Data, size);
		HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin);
		if(sekundy>59) sekundy =0;	//jeżeli czba sekund >59 - wyzeruj
		cnt =0;	//wyzeruj licznik ms
	}

}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
static uint8_t Data[40]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size =0;
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
size = sprintf(Data, "Odebrana wiadomosc: %d.\r\n",40);
HAL_UART_Transmit_DMA(&huart, Data ,size);// Rozpoczecie nadawania danych z wykorzystaniem przerwan
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
HAL_UART_Receive_DMA(&huart1, Received, size_Received); // Ponowne włączenie nasłuchiwania
}


/* USER CODE END 4 */

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

#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,
   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */

}

#endif

/**
 * @}
 */ 

/**
 * @}
*/ 

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

Może być winny priorytet przerwań?

Jeżeli tak, to jak ustawić aby UART miał największy ?

Link do komentarza
Share on other sites

Na początek wypadałoby napisać jaki model mikrokontrolera programujesz. Pewnie można się domyślić, że to stm32, ale byłoby elegancko napisać co to za typ - po pierwsze łatwiej doradzać, po drugie osoby, które tylko czytają też mogą być zainteresowane.

Czy przypadkiem kompilator nie wyświetla Ci ostrzeżeń podczas kompilacji?

Dla mnie podejrzanie wygląda kod:

HAL_UART_Transmit_DMA(&huart, Data ,size);

Wcześniej używałeś podobnego, ale huart było zmienną globalną. Teraz dostajesz ją jako wskaźnik:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

Czyli przekazujesz wskaźnik do wskaźnika... Na pewno o to chodziło?

Link do komentarza
Share on other sites

Hej,

Dziękuję za reakcję 🙂 Już poprawiłem informację w polu temat.

Co do Twoich uwag to:

1. Miałeś rację. w linijce HAL_UART_Transmit_DMA(&huart, Data ,size); powinien być huart1

2. Wszystkie informacje dotyczące programowania STMów posiadam tylko z tego kursu: https://forbot.pl/blog/artykuly/programowanie/kurs-stm32-f4-7-komunikacja-przez-uart-id13472

Jeżeli chodzi o kompilacje to są zgłaszane dwa worningi tyczące się funkcji sprintf:

E:/STM32_ARM/ECLIPS_V2/Workspace_kepler/UART_v1/UART_v1/Src/main.c: In function 'HAL_TIM_PeriodElapsedCallback':
E:/STM32_ARM/ECLIPS_V2/Workspace_kepler/UART_v1/UART_v1/Src/main.c:291:19: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
   size = sprintf(Data, "Liczba sekund: %d.\r\n",sekundy);

oraz

E:/STM32_ARM/ECLIPS_V2/Workspace_kepler/UART_v1/UART_v1/Src/main.c: In function 'HAL_UART_RxCpltCallback':
E:/STM32_ARM/ECLIPS_V2/Workspace_kepler/UART_v1/UART_v1/Src/main.c:305:17: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
 size = sprintf(Data, "Odebrana wiadomosc: %c.\r\n",40);

A teraz to co się dzieje w podczas debugowania projektu:

1. Uruchamiam program w trybie Debug.

2. Program wchodzi w przerwanie od timera TIM14 (struktura htim14 jest ładnie przekazywana do przerwania:

3. Generuję zmienną Data (zmienna ładnie się tworzy, ale struktura htim zwraca błąd o treści:

htim	TIM_HandleTypeDef *	Error: Multiple errors reported.\ Failed to execute MI command: -var-update 1 var1 Error message from debugger back end: value has been optimized out\ Failed to execute MI command: -var-update 1 var1 Error message from debugger back end: value has been optimized out	

4. Wysyłam dane na UARTa (struktura htim dalej ma błąd, w terminalu wyświetla się wiadomość Liczba sekund 1.)

5. Ponownie włączam nasłuchiwanie na UART.

6. Puszczam program dalej i czekam na kolejne przerwanie i breakpoint

7. Jestem w przerwaniu od timera14 (struktura htim wygląda tak jak w pkt 2, ale zgłasza błąd:

Failed to execute MI command:
-var-update 1 var1
Error message from debugger back end:
value has been optimized out

8. wykonuje funkcję sprintf (zmienna data wykonała się poprawnie.

9. Wysyłam dane na UART (na terminalu nic się nie wyświetla, struktura htim zwraca błą:

htim	TIM_HandleTypeDef *	Error: Multiple errors reported.\ Failed to execute MI command: -var-update 1 var1 Error message from debugger back end: value has been optimized out\ Failed to execute MI command: -var-update 1 var1 Error message from debugger back end: value has been optimized out	

Poniżej cały main.c

/**
 ******************************************************************************
 * File Name          : main.c
 * Description        : Main program body
 ******************************************************************************
 *
 * COPYRIGHT(c) 2017 STMicroelectronics
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */
#define TRUE 1
#define FALSE 0
#define size_Received 1

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim14;
TIM_HandleTypeDef htim16;

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

uint8_t Received;
uint8_t czujnik_cnt;		//liczba czujnikó na magistralii
volatile uint8_t s1_flag;	//flaga tyknięcia timera co 1 sekundę
volatile uint8_t sekundy;	//licznik sekund 0-59

uint8_t subzero, cal, cel_fract_bits;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM14_Init(void);
static void MX_TIM16_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);	//Funkcja obsługująca przerwania od timerów
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);		//Funkcja obsługująca przerwania do UARTa



/* USER CODE END PFP */

/* USER CODE BEGIN 0 */


/* USER CODE END 0 */

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();

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

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_TIM14_Init();
 MX_TIM16_Init();
 MX_USART1_UART_Init();

 /* USER CODE BEGIN 2 */
 HAL_TIM_BaseBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
   Error_Handler();
 }

}

/** 
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA1_Channel2_3_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

/** Configure pins as 
       * Analog 
       * Input 
       * Output
       * EVENT_OUT
       * EXTI
*/
static void MX_GPIO_Init(void)
{

 GPIO_InitTypeDef GPIO_InitStruct;

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

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, LED_BLUE_Pin|LED_GREEN_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pins : LED_BLUE_Pin LED_GREEN_Pin */
 GPIO_InitStruct.Pin = LED_BLUE_Pin|LED_GREEN_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM14){
	static uint16_t cnt =0;
	uint8_t Data[50];
	uint16_t size;

	if(++cnt>99){		//gdy mineła sekunda
		s1_flag = TRUE;	//ustaw flagę tyknięca sekundy
		sekundy ++;		//zwiększ licznik sekund
		size = sprintf(Data, "Liczba sekund: %d.\r\n",sekundy);
		HAL_UART_Transmit_DMA(&huart1, Data, size);
		HAL_UART_Receive_DMA(&huart1, &Received, size_Received); // Ponowne włączenie nasłuchiwania
		HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin);
		if(sekundy>59) sekundy =0;	//jeżeli czba sekund >59 - wyzeruj
		cnt =0;	//wyzeruj licznik ms
	}

}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
uint8_t Data[40]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size =0;
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
size = sprintf(Data, "Odebrana wiadomosc: %c.\r\n",40);
HAL_UART_Transmit_DMA(&huart1, Data ,size);// Rozpoczecie nadawania danych z wykorzystaniem przerwan
HAL_UART_Receive_DMA(&huart1, &Received, size_Received); // Ponowne włączenie nasłuchiwania
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
HAL_UART_Receive_DMA(&huart1, &Received, size_Received); // Ponowne włączenie nasłuchiwania
}


/* USER CODE END 4 */

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

#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,
   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */

}

#endif

/**
 * @}
 */ 

/**
 * @}
*/ 

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

I tak w kółko... Już mi sił brakuję...

Link do komentarza
Share on other sites

Dziwne, kompilator powinien ostrzegać o niepoprawnym typie wskaźnika. Oczywiście musisz poprawić wszystkie wskaźniki do wskaźników, masz to samo przy innych użyciach huart.

Komunikat o którym piszesz nie wynika z błędu w programie - to błąd debuggera. Właściwie to nie błąd tylko informacja, że nie może wyświetlić wartości zmiennej, bo została przez optymalizator usunięta. Gdy piszesz program w języku wysokopoziomowym, bezpośrednie przetłumaczenie kodu na język maszynowy jest bardzo nieefektywne - program jest duży, działa powoli i zużywa mnóstwo pamięci, czyli taki windows. Zadaniem optymalizatora jest pogrzebać w takim kodzie i wymyślić co zrobić, żeby całość działała trochę lepiej. Współczesne optymalizatory są bardzo sprytne, potrafią czynić prawdziwe cuda. Niestety debugowanie takiego programu jest nieco skomplikowane - Ty napisałeś program, a optymalizator go przerobił. Przy debugowaniu używasz tej przerobionej wersji do wykonywania, ale podgląd zmiennych masz z oryginału - to czasem do siebie nie pasuje i stąd komunikat od debuggera. Po prostu optymalizator uznał, że ta zmienna jest niepotrzebna i ją wyrzucił 🙂

W ustawieniach projektu możesz poszukać parametrów optymalizacji. Pewnie masz ustawioną opcję -O2 lub coś podobnego. Możesz spróbować optymalizację wyłączyć (-O0). Wtedy kod będzie dłuższy, ale łatwiejszy w debugowaniu.

I jeszcze jedna rada - nie wysyłaj danych z przerwań. Przerwania powinny być obsługiwane szybko i natychmiast zwracać sterowanie do programu głównego. Używanie sprintf, czy wysyłanie może zajmować dużo czasu - a to ma wpływ na inne przerwania i cały system. Zmiana priorytetów to nie metoda na poprawienie programu.

  • Lubię! 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

Hej,

Dziękuję za wyjaśnienie 🙂

To teraz dopytam, powiedzmy, że znam podstawy programowania w C, ale nie mam dużej praktyki w tym temacie więc nie wszytko jest dla mnie oczywiste 🙂 jak się pomylę to sprostuj mnie 🙂

W funkcjach:

HAL_UART_Receive_DMA(&huart1,Received,10);
HAL_UART_Transmit_DMA(&huart1,Data,40);

Przed zmienną huart1 mam dać znaczek &? a co ze zmienną Received, tutaj też dać &?

Co do przerwań to proponujesz np zrobić zmienną lokalną załóżmy Value_UART, do niej ładować to co wyślę po UARCIE a w pętli głównej dać switcha i w zależności od wartości zmiennej Value_UART wykonywać odpowiednie operacje ?

[ Dodano: 29-06-2017, 23:22 ]

Ogarnąłem worningi zgłaszane od funkcji HAL_UART_Receive_DMA oraz HAL_UART_Transmit_DMA. Został tylko ten od funkcji sprintf.

Ale żeby nie było za łatwo to znalazłem coś jeszcze, mianowicie funkcja HAL_UART_Transmit_DMA nigdy nie widzi końca transmisji.

1. Włączam UARTA

2. Włączam nasłuch na linii

3. Odbieram po raz pierwszy jakiś znak

4. Po wysłaniu wiadomości dalej gState jest ustawione na HAL_UART_STATE_BUSY_TX ( mogę czekać nawet i 15 minut i tak dalej będzie ten sam status)

5. Ponownie włączam nasłuch

6. Odbieram po raz drugi jakiś znak

7 Program się wyburacz (Działa odbieranie danych, a bufor wyjściowy nie reaguje)

Gdzie szukać przyczyny?

Poniżej cały kod programu:

/**
 ******************************************************************************
 * File Name          : main.c
 * Description        : Main program body
 ******************************************************************************
 *
 * COPYRIGHT(c) 2017 STMicroelectronics
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */
#define TRUE 1
#define FALSE 0
#define size_UART1_received 1

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim14;
TIM_HandleTypeDef htim16;

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

uint8_t UART1_received;
volatile uint8_t UART_flag;
volatile uint8_t Data[50]; // Tablica przechowujaca wysylana wiadomosc.
volatile uint16_t Data_size = 0;// Rozmiar tablicy przechowujacej wysylana wiadomosc.


uint8_t czujnik_cnt;		//liczba czujnikó na magistralii
volatile uint8_t s1_flag;	//flaga tyknięcia timera co 1 sekundę
volatile uint8_t sekundy;	//licznik sekund 0-59

uint8_t subzero, cal, cel_fract_bits;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM14_Init(void);
static void MX_TIM16_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);	//Funkcja obsługująca przerwania od timerów
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);		//Funkcja obsługująca przerwania do UARTa



/* USER CODE END PFP */

/* USER CODE BEGIN 0 */


/* USER CODE END 0 */

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();

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

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_TIM14_Init();
 MX_TIM16_Init();
 MX_USART1_UART_Init();

 /* USER CODE BEGIN 2 */
 HAL_TIM_BaseBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
   Error_Handler();
 }

}

/** 
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA1_Channel2_3_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

/** Configure pins as 
       * Analog 
       * Input 
       * Output
       * EVENT_OUT
       * EXTI
*/
static void MX_GPIO_Init(void)
{

 GPIO_InitTypeDef GPIO_InitStruct;

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

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, LED_BLUE_Pin|LED_GREEN_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pins : LED_BLUE_Pin LED_GREEN_Pin */
 GPIO_InitStruct.Pin = LED_BLUE_Pin|LED_GREEN_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM14){
	static uint16_t cnt =0;
//		uint8_t Data[50];
//		uint16_t size;

	if(++cnt>99){		//gdy mineła sekunda
		s1_flag = TRUE;	//ustaw flagę tyknięca sekundy
		sekundy ++;		//zwiększ licznik sekund
//			size = sprintf(Data, "Liczba sekund: %d.\r\n",sekundy);
//			HAL_UART_Transmit_DMA(&huart1, Data, size);
//			HAL_UART_Receive_DMA(&huart1, &UART1_received, size_UART1_received); // Ponowne włączenie nasłuchiwania
		HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin);
		if(sekundy>59) sekundy =0;	//jeżeli czba sekund >59 - wyzeruj
		cnt =0;	//wyzeruj licznik ms
	}

}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
UART_flag = TRUE; //Ustawienie flagi UARTA
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
HAL_UART_Receive_DMA(&huart1, (uint8_t *)&UART1_received, size_UART1_received); // Ponowne włączenie nasłuchiwania
}


/* USER CODE END 4 */

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

#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,
   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */

}

#endif

/**
 * @}
 */ 

/**
 * @}
*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Link do komentarza
Share on other sites

Dla potomnych 🙂

Udało mi się rozwiązać problem z niezerującym się statusem HAL_UART_STATE_BUSY_TX. Polecam zaglądnąć tutaj: https://community.st.com/thread/9316#comment-137236

a w celu zapobiegnięcia pobrania nowych danych przed końcem wysłania poprzednich można dołożyć taki fragment kodu:

//Przerwanie UART DMA
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
   UART_flag = TRUE; //Ustawienie flagi UARTA
}

// Po odebraniu danej wykonaj program 

  if(UART_flag == TRUE){
	  UART_flag = FALSE;
      Data_size = sprintf(&Data, "Odebrano znak: %c.\r\n", UART1_received);

      HAL_UART_Transmit_DMA(&huart1, (uint8_t*)Data ,Data_size);// Rozpoczecie nadawania danych z wykorzystaniem przerwan
      flag_UART_gState = TRUE;
  }
  if((huart1.gState == HAL_UART_STATE_READY) & flag_UART_gState){
	  HAL_UART_Receive_DMA(&huart1, (uint8_t *)&UART1_received, size_UART1_received); // Ponowne włączenie nasłuchiwania
	  flag_UART_gState = FALSE;
  }

Ponadto funkcja sprintf w:

Data_size = sprintf(&Data, "Odebrano znak: %d.\r\n",&UART1_received);

dodawała jeden znak ASCII. Z każdą nową zmienną Data ten znak ASCII był inny (kolejny z tabeli kodów ASCII). Rozwiązaniem tego problemu okazało się obłożenie zmiennej UART1_received funkcją atoi()

Data_size = sprintf(&Data, "Odebrano znak: %d.\r\n", atoi(&UART1_received));
Link do komentarza
Share on other sites

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.