Skocz do zawartości

Wywołanie instrukcji LCD podczas pracy programu


Pomocna odpowiedź

Napisano

Dzień dobry,

chciałbym wywołać dane na wyświetlaczu LCD w trakcie działania programu bez wykorzystania funkcji HAL_Delay(); Program jest to "wstępny" zarys procesu regulacji temperatury (PID). Bez funkcji HAL_Delay() wyświetlacz odświeża się zbyt szybko. Jak implementuje się LCD w programie sterującym aby nie były "przerwy" w pracy mcu?

Wyświetlacz LCD 16x2 HD44780.

if (HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK)
  {
	  PomiarADC = HAL_ADC_GetValue(&hadc);
	  LcdADC = (PomiarADC*0.097);
	  HAL_ADC_Start(&hadc);
  }

  error = setPoint - LcdADC;
  Itemp += kI*error*dt;

  	  if(Itemp > 100)
  	  {
  		  Itemp = 100;
  	  }
  	  else if(Itemp < 0 )
	  	  {
  		  Itemp = 0;
	  	  }

  float Dtemp = (LcdADC-lastLcdADC)*(1000/dt);
  lastLcdADC = LcdADC;

  int Pwm = kP*error+Itemp-kD*Dtemp;

  if (Pwm > 100)
	  {
		  Pwm = 100;
	  }
		  else if(Pwm < 0)
	  {
		  Pwm = 0;
	  }

  Duty = Pwm;

  TIM3->CCR4 = Duty;
  LCD = LcdADC;

  LCD1602_clear();
  LCD1602_print("Temperatura:");
  LCD1602_2ndLine();
  LCD1602_PrintInt(LCD);

W przypadku zastosowania HAL_Delay(); występują obserwowalne przerwy w działaniu wyświetlacza.

LCD1602_clear();
  LCD1602_print("Temperatura:");
  LCD1602_2ndLine();
  LCD1602_PrintInt(LCD);
HAL_Delay();

Drugi pomysł to odliczanie czasu za pomocą funkcji HAL_GetTick(); Ale i w tym przypadku program nie działa poprawnie. Widać, że sygnał PWM tjest inny niż bez tej funkcji.

if(HAL_GetTick()% 1000 == 0)
  {
	  LCD1602_clear();
	  LCD1602_print("Temperatura:");
	  LCD1602_2ndLine();
	  LCD1602_PrintInt(LCD);
  }

Trzeci pomysł to wykorzystanie przerwań cyklicznych co 2Hz z wykorzystaniem TIM6. Ale w tym przypadku wyświetlacz nic nie pokazuje.

 /* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);

/* USER CODE END 2 */

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM6)
{ 
LCD1602_clear();
	  LCD1602_print("Temperatura:");
	  LCD1602_2ndLine();
	  LCD1602_PrintInt(LCD); 
}
}
/* USER CODE END PFP */

Jak się implementuje peryferia tj. LCD aby nie wpływały na proces regulacji temperatury w algorytmie PID?

Jest kilka możliwości rozwiązania Twojego problemu.

1. Możesz zastosować RTOS, wtedy obsługę LCD umieszczasz w oddzielnym tasku. Do delayów służą wtedy odpowiednie funkcje RTOS, które oddają sterowanie innemu wątkowi w tym czasie. Zaletą tego rozwiązania jest bardzo mała ingerencja w istniejący kod. Wadą potrzeba poznania RTOSa i zmiana architektury całego programu pod niego.

2. Możesz przepisać bibliotekę wykorzystując przerwania i maszyny stanu. Jest to dosyć skomplikowane i wymaga najprawdopodobniej przepisanie całego drivera LCD. Możesz na przykład wykorzystać przerwanie od timera uruchamiane co określony przedział czasu. W jednym obiegu przerwania wykonujesz operacje, które możesz zrobić od razu, a jak musisz na coś czekać, zapisujesz stan i wychodzisz. W następnym wejściu do przerwania ze stanu odczytujesz w którym miejscu kontynuować. Taki driver wykonuje bardzo niskopoziomowe operacje - zwykle będzie to wysyłanie komend, które poznasz czytając dokumentację. Będziesz też potrzebował mechanizm wyższego poziomu, który kolejkuje zadania wyższego poziomu np. teksty składające się z wielu znaków. To rozwiązanie jest chyba jeszcze bardziej skomplikowane niż poprzednie.

To tyle jeśli chodzi o opcje implementacji nieblokującej LCD. Jak widać, stwarzają one spore trudności i jeśli jesteś początkujący, możesz mieć problemy. Możesz jednak podejść do problemu trochę inaczej. Sprawdzi się to, jeżeli nie będziesz chciał rozbudowywać już aplikacji o kolejne taski.

Otóż możesz zostawić wyświetlanie LCD w pętli głównej, a odczyt ADC i obsługę PID dać do przerwań. ADC może na przykład pomiar zapisywać w zmiennej, a przerwanie timera o niskim priorytecie będzie obsługiwać obliczanie PID korzystając z wartości ADC. Dzięki temu możesz dalej korzystać z gotowej biblioteki, a program pozostanie prosty i nie dojdą nowe zależności.

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...