Skocz do zawartości

Wysyłanie temperatury z stm32F411 na komputer PC Windows


Imilek

Pomocna odpowiedź

Cześć.

Chciałbym się Was poprosić o pomoc. Bardzo chcę przesłać na komputer za pomocą UART'a informacje o mierzonej przez mikrokontroler temperaturze. Udaje mi się przesłać temperaturę jako liczbę naturalną, lecz mi zależy na tym, aby owa temperatura była wysyłana jako liczba z dwiema cyframi po przecinku.

Kod wygląda następująco:

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

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

TIM_HandleTypeDef htim10;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint16_t size = 0;
uint8_t data[100];
uint16_t PomiarADC;
uint32_t Counter = 0;
float Suma = 0;
int Wyjscie;
float Temperature;
float Vsense;

const float V25 = 0.76;
const float Avg_slope = 0.0025;
const float SupplyVoltage = 3.0;
const float ADCResolution = 4096.0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM10_Init(void);
static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
if (hadc->Instance==ADC1){
PomiarADC = HAL_ADC_GetValue(&hadc1);
Vsense = (SupplyVoltage*PomiarADC)/(ADCResolution-1);
Temperature = ((Vsense-V25)/Avg_slope)+25;
Suma = Suma + Temperature;
++Counter;
}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM10){
	HAL_GPIO_TogglePin(LED_Blue_GPIO_Port, LED_Blue_Pin);
	Wyjscie = (Suma/Counter);

	size = sprintf(data, "Zmierzona temperatura wynosi: %d\r\n", Wyjscie);
	HAL_UART_Transmit_IT(&huart1, data, size);

	Suma = 0;
	Counter = 0;
}
}
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 *
 * @retval None
 */
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_ADC1_Init();
 MX_TIM10_Init();
 MX_USART1_UART_Init();
 /* USER CODE BEGIN 2 */
 HAL_ADC_Start_IT(&hadc1);
 HAL_TIM_Base_Start_IT(&htim10);
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

 }
 /* USER CODE END 3 */

}

Powyższy kod powoduje pojawienie się czegoś takiego:

Teraz jeżeli zmienię ten kod, że zamiast:

int Wyjscie;

zrobię:

float Wyjscie;

oraz zmienię:

size = sprintf(data, "Zmierzona temperatura wynosi: %d\r\n", Wyjscie);

na to:

size = sprintf(data, "Zmierzona temperatura wynosi: %.2f\r\n", Wyjscie);

To byłem przekonany, że zadziała, jednakże moim oczom ukazały się dwa poprawne wyniki z dwoma znakami po przecinku, a następnie cały czas było wypisywane:

"Zmierzona temperatura wynosi: nan".

Dodam tylko, że przed wysłaniem tych danych przez UART, w programie STMStudio, zmienna "Wyjscie" miała wiele cyfr po przecinku., dlatego też nie mam pojęcia gdzie tkwi problem.

Czy umielibyście mi pomóc?

Z góry serdecznie dziękuję za wszelką pomoc.

Pozdrawiam.

Link do komentarza
Share on other sites

Gość es2

Imilek jakiego kompilatora i środowiska używasz? Kompilator pewnie GCC a w nim trzeba włączyć obsługę wyświetlania liczb zmiennoprzecinkowych. W KEIL nie trzeba tego robić.

Link do komentarza
Share on other sites

Imilek, gdy obliczasz wynik, zakładasz że jakiś pomiar został wykonany:

Wyjscie = (Suma/Counter);

Może jednak lepiej byłoby się upewnić że Counter != 0?

Jeśli to nie pomoże, to spróbuj wypisywać wartość zmiennych Suma i Counter - może ich wartości są inne niż oczekiwane, np. następuje przepełnienie.

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

Gość es2

W programach unikam liczb zmiennoprzecinkowych. Jeśli potrzebujesz większej precyzji użyj liczb stałoprzecinkowych.

Float, z dwoma miejscami po przecinku, możesz wyświetlić np tak:

float Wyjscie;
int wys;

wys = Wyjscie * 100;
sprintf(data, "Zmierzona temperatura wynosi: %d.%d\r\n", wys/100, wys%100);

Z liczbami ujemnymi więcej zabawy:

sprintf(data, "Zmierzona temperatura wynosi: %d.%d\r\n", wys/100, abs(wys%100) );

Z formatowanie tego jeszcze więcej, pewnie tak:

sprintf(data, "Zmierzona temperatura wynosi: %d.%02d\r\n", wys/100, abs(wys%100) );

Najlepiej oczywiście nie konwertować float na int czy long, tylko cały czas operować na np int pamiętając, że 1=100.

Link do komentarza
Share on other sites

Skoro program wypisuje pierwsze dwie wartości poprawnie, a później wyświetla "nan" to obsługa float-ów działa poprawnie. W programie i tak są używane, więc po co dawać rady typu - programuj jak ja lubię bo tak jest lepiej.

Link do komentarza
Share on other sites

Gość es2
Skoro program wypisuje pierwsze dwie wartości poprawnie, a później wyświetla "nan"

Tego nie doczytałem.

W takim razie należałoby uruchomić pod debugerem i zobaczyć co tak naprawdę znajduje się w zmiennej przy kolejnych obiegach pętli. Do debugowania, polecałbym zmienną zadeklarować jako static volatile.

Link do komentarza
Share on other sites

Cześć.

Dziękuję za odpowiedzi. Korzystam z System Workbench for STM32, i z CubeMX.

Zrobiłem tak jak mówił: , ale niestety nie dało to pożądanego rezultatu. Poniżej wklejam kod, który zwraca dwa dobre wyniki (różne), a potem, każda kolejna wartość jest taka sama jak poprzednia.

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

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

TIM_HandleTypeDef htim10;
TIM_HandleTypeDef htim11;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/*Obsługa działania przycisków*/
int8_t settemp = 20;
uint8_t PinState;
uint32_t timer1ms = 0;
/* Wysyłanie danych przez UART*/
uint8_t data[100];
uint16_t size = 0;
float Wyjscie;
/*Pomiar temperatury przez mikrokontroler*/
uint16_t PomiarADC;
uint32_t Counter = 0;
float Suma = 0;
float Temperature;
float Vsense;
const float V25 = 0.76;
const float Avg_slope = 0.0025;
const float SupplyVoltage = 3.0;
const float ADCResolution = 4096.0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM10_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM11_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
if (hadc->Instance == ADC1){
PomiarADC = HAL_ADC_GetValue(&hadc1);
Vsense = (SupplyVoltage*PomiarADC)/(ADCResolution-1);
Temperature = ((Vsense-V25)/Avg_slope)+25;
Suma = Suma + Temperature;
++Counter;
}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM10){
	HAL_GPIO_TogglePin(LED_Blue_GPIO_Port, LED_Blue_Pin);
		if (Counter != 0){
			Wyjscie = (Suma/Counter);
		}
	size = sprintf(data, "%.2f\r\n", Wyjscie);
	HAL_UART_Transmit_IT(&huart1, data, size);
	Suma = 0;
	Counter = 0;

}

if (htim->Instance == TIM11){
	if ((PinState == 1) || (PinState == 2)){
	++timer1ms;
	}
	if (((PinState == 1) || (PinState == 2))&&(timer1ms >=20)&&((HAL_GPIO_ReadPin(Button_Up_GPIO_Port, Button_Up_Pin) == 1)&&(HAL_GPIO_ReadPin(Button_Down_GPIO_Port, Button_Down_Pin) == 1))){
		timer1ms = 0;
		PinState = 0;
	}
}
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	if (GPIO_Pin == Button_Up_Pin){
		PinState = 1;
	}else if (GPIO_Pin == Button_Down_Pin){
		PinState = 2;
	}
}

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 *
 * @retval None
 */
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_ADC1_Init();
 MX_TIM10_Init();
 MX_USART1_UART_Init();
 MX_TIM11_Init();
 /* USER CODE BEGIN 2 */
 HAL_ADCBITS_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;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
   _Error_Handler(__FILE__, __LINE__);
 }

}

/** 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_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(LED_Blue_GPIO_Port, LED_Blue_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pins : Button_Up_Pin Button_Down_Pin */
 GPIO_InitStruct.Pin = Button_Up_Pin|Button_Down_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : LED_Blue_Pin */
 GPIO_InitStruct.Pin = LED_Blue_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(LED_Blue_GPIO_Port, &GPIO_InitStruct);

 /* EXTI interrupt init*/
 HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI3_IRQn);

 HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI4_IRQn);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @param  file: The file name as string.
 * @param  line: The line in file as a number.
 * @retval None
 */
void _Error_Handler(char *file, int line)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 while(1)
 {
 }
 /* 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****/

Sprawdziłem również co się dzieje w programie za pomocą programu STMStudio i zauważyłem, że jak kod wygląda jak powyżej, to wówczas zmienne Suma oraz Counter rosną w nieskończoność (przez trochę ponad 1 sekundę), aż w końcu przyjmują one wartość 0.0, po czym otrzymywane wyniki przestają się zmieniać.

Natomiast gdy kod wygląda tak:

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

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

TIM_HandleTypeDef htim10;
TIM_HandleTypeDef htim11;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/*Obsługa działania przycisków*/
int8_t settemp = 20;
uint8_t PinState;
uint32_t timer1ms = 0;
/* Wysyłanie danych przez UART*/
uint8_t data[100];
uint16_t size = 0;
int Wyjscie;
/*Pomiar temperatury przez mikrokontroler*/
uint16_t PomiarADC;
uint32_t Counter = 0;
float Suma = 0;
float Temperature;
float Vsense;
const float V25 = 0.76;
const float Avg_slope = 0.0025;
const float SupplyVoltage = 3.0;
const float ADCResolution = 4096.0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM10_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM11_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
if (hadc->Instance == ADC1){
PomiarADC = HAL_ADC_GetValue(&hadc1);
Vsense = (SupplyVoltage*PomiarADC)/(ADCResolution-1);
Temperature = ((Vsense-V25)/Avg_slope)+25;
Suma = Suma + Temperature;
++Counter;
}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM10){
	HAL_GPIO_TogglePin(LED_Blue_GPIO_Port, LED_Blue_Pin);
		if (Counter != 0){
			Wyjscie = (Suma/Counter);
		}
	size = sprintf(data, "%d.\r\n", Wyjscie);
	HAL_UART_Transmit_IT(&huart1, data, size);
	Suma = 0;
	Counter = 0;

}

if (htim->Instance == TIM11){
	if ((PinState == 1) || (PinState == 2)){
	++timer1ms;
	}
	if (((PinState == 1) || (PinState == 2))&&(timer1ms >=20)&&((HAL_GPIO_ReadPin(Button_Up_GPIO_Port, Button_Up_Pin) == 1)&&(HAL_GPIO_ReadPin(Button_Down_GPIO_Port, Button_Down_Pin) == 1))){
		timer1ms = 0;
		PinState = 0;
	}
}
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	if (GPIO_Pin == Button_Up_Pin){
		PinState = 1;
	}else if (GPIO_Pin == Button_Down_Pin){
		PinState = 2;
	}
}

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 *
 * @retval None
 */
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_ADC1_Init();
 MX_TIM10_Init();
 MX_USART1_UART_Init();
 MX_TIM11_Init();
 /* USER CODE BEGIN 2 */
 HAL_ADCBITS_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;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
   _Error_Handler(__FILE__, __LINE__);
 }

}

/** 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_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(LED_Blue_GPIO_Port, LED_Blue_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pins : Button_Up_Pin Button_Down_Pin */
 GPIO_InitStruct.Pin = Button_Up_Pin|Button_Down_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : LED_Blue_Pin */
 GPIO_InitStruct.Pin = LED_Blue_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(LED_Blue_GPIO_Port, &GPIO_InitStruct);

 /* EXTI interrupt init*/
 HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI3_IRQn);

 HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI4_IRQn);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @param  file: The file name as string.
 * @param  line: The line in file as a number.
 * @retval None
 */
void _Error_Handler(char *file, int line)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 while(1)
 {
 }
 /* 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****/

To Counter oraz Suma co jakiś czas się zerują i nie następuje zatrzymanie zmian odczytywanej wartości temperatury. Wiecie co może być przyczyną?

Pozdrawiam serdecznie.

Link do komentarza
Share on other sites

Ok, to wbrew pozorom sporo wyjaśnia.

Więc może zacznijmy od początku - pierwszy program o ile rozumiem wykonuje konwersję A/C w trybie ciągłym i po każdym pomiarze pojawia się przerwanie obsługiwane przez funkcję HAL_ADC_ConvCpltCallback.

Tych przerwań z wynikami pojawia się X, a następnie kolejne przerwanie od TIM10, które "obrabia" wyniki w HAL_TIM_PeriodElapsedCallback.

Więc pytanie jest następujące - ile razy zostanie wywołana funkcja HAL_ADC_ConvCpltCallback, zanim wywołane będze HAL_TIM_PeriodElapsedCallback?

Mogę się mylić, ale możliwe że problem wynika ze specyfiki liczb zmiennopozycyjnych - dodawanie małej wartości do dużej może dawać w wyniku większą wartość zamiast sumy. Ale najpierw trzeba oszacować ile danych dostajemy i jaka jest maksymalna wartość zmiennej Suma.

Link do komentarza
Share on other sites

Konwersja temperatury wykonuje się około 4065 razy na sekundę. Jeden cykl trwa 0,000246s. Po to właśnie wprowadziłem zmienną Counter, aby mieć pewność, że dzielę przez poprawną ilość konwersji. Postaram się jeszcze podpatrzeć coś przez debugger, ale średnio ogarniam co się w nim dzieje, dlatego potrzebuję nieco więcej czasu.

Pozdrawiam.

Link do komentarza
Share on other sites

Ok, wycofuję moje pomysły odnośnie sumowania float-ów. Ale na przyszłość może napisz czym się różnią oba programy, to dużo ułatwia - nie wiem dlaczego ale coś mi się przewidziało że jest inna częstotliwość obliczania wyników, a programy są prawie identyczne:

Skoro taka zmiana powoduje różnicę w wynikach, proponuję dodać volatile do zmiennych modyfikowanych w przerwaniach - czyli Suma, Couner i Wyjscie. Może to coś da...

Link do komentarza
Share on other sites

Na przyszłość zapamiętam Twoją radę. Dziękuję.

Volatile niestety nic nie pomogło. Jednak podziałałem trochę z debuggerem. Dodałem breakpointy przy:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

oraz

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

I zauważyłem, że praca programu tylko raz zatrzymuje się na pomiarze temperatury, a potem bez przerwy jest na tej drugiej podanej przeze mnie linii i cały czas ją wykonuje. Przerwania od Timera10 są dużo rzadsze (1Hz) od tych przeznaczonych do pomiaru temperatury (około 4065Hz).

Jednak dziwi mnie to bo przy oglądaniu pracy pod STMStudio, widziałem, że wartość Countera była zdecydowanie większa niż 1 i się szybko zmieniała, a tutaj tego niestety nie widzę.

EDIT.

A czy może być to związane, z tym, że pomiar temperatury dokonuje się z większą częstotliwością niż jest ustawiony zegar (Timer11 jest ustawiony na 1000Hz)?

Link do komentarza
Share on other sites

Już wysyłam. Nie sądziłem, że ktoś będzie chciał mi poświęcać tyle czasu, żeby tam jeszcze zaglądać. Na następny raz będę wiedział 🙂

EDIT.

Ponowię z poprzedniego postu.

A czy może być to związane, z tym, że pomiar temperatury dokonuje się z większą częstotliwością niż jest ustawiony zegar (Timer11 jest ustawiony na 1000Hz)?

10_Projekt_zajecia.rar

Link do komentarza
Share on other sites

Chyba problem polega na odczytach z ADC. U mnie nie dziala UART, ale testuje taki kod:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM10){
	HAL_GPIO_TogglePin(LED_Blue_GPIO_Port, LED_Blue_Pin);
		if (Counter != 0){
			Wyjscie = (Suma/Counter);
			Suma = 0;
			Counter = 0;
			size = sprintf(data, "%d\r\n", Wyjscie);
			HAL_UART_Transmit_IT(&huart1, data, size);
		}
}

Teraz counter jest > 0 tylko na poczatku, poźniej jest ciągle zerem. Jeśli możesz to sprawdź taki kod - ciekawe czy jest tak jak myślę.

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.