Skocz do zawartości

Stm32 problem z enkoderem [Rozwiązany]


_LM_

Pomocna odpowiedź

Piszę sobie takiego małego libsa do obsługi enkodera, do testów używam najzwyklejszego impulsowego oraz płytki nucleo L476. Problem polega na tym że po pewnym czasie kręcenia, funkcja enkodera zacina się. Ponieważ nie mam pomysłu jak to dalej debugować przedstawiam kod testowy. Użyłem timera4 w trybie encodera i pracuje on w pełnej swojej pojemności zliczania. Podejrzewam że problem tkwi w maszynie stanów, być może ktoś zauważy miejsce błędu.
 

#include "main.h"
#include "tim.h"
#include "stm32l4xx_hal.h"
#include  "enco.h"


typedef enum {idle, count, runf,end}encoState_t;

static uint8_t encodir = 0;
static uint16_t encoInterval = 50;
static void(*enc_event_callback)(void);


void enco_init(const uint16_t interval)
{
	encoInterval = interval;
}

void register_enc_event_callback(void(*callback)(void)){

	if(callback)enc_event_callback = callback;
}

void ENCODER_EVENT() {
	static uint16_t encoval = 0;
	static uint32_t tickStart = 0;
	static encoState_t enc = idle;

	static uint16_t roznicaPlus, roznicaMinus;

	if (encoval != __HAL_TIM_GET_COUNTER(&htim4) && enc == idle) { // zaczeto krecic
		enc = count; // liczenie
		encoval = __HAL_TIM_GET_COUNTER(&htim4); //

		roznicaPlus = __HAL_TIM_GET_COUNTER(&htim4) + (ENCO_STEP - 1);
		roznicaMinus = __HAL_TIM_GET_COUNTER(&htim4) - (ENCO_STEP - 1);
		tickStart = HAL_GetTick() + encoInterval; // timeout
		return;
	}

	if (enc == count) {
		if (roznicaPlus == __HAL_TIM_GET_COUNTER(&htim4)) {

			encodir = encoRight;
			encoval = __HAL_TIM_GET_COUNTER(&htim4);
			enc = idle;
			if (enc_event_callback)enc_event_callback();
			}else if (roznicaMinus == __HAL_TIM_GET_COUNTER(&htim4)) {
			encodir = encoLeft;
			encoval = __HAL_TIM_GET_COUNTER(&htim4);
			enc = idle;
			if (enc_event_callback)enc_event_callback(); // wykonanie przypisanej f
		}

	} else if (enc == count && HAL_GetTick() > tickStart) { // timeout
		encoval = __HAL_TIM_GET_COUNTER(&htim4); // przypisanie aby nie zmenial statusu bez potrzeby
		enc = idle;
	}

}

encoDir getEncoDir(void){
	return encodir;			// zwraca kierunek obracania
}

.h

#ifndef INC_ENCO_H_
#define INC_ENCO_H_

#define ENCO_STEP 4 //4 or 2



typedef enum{encoLeft = 16,encoRight = 32}encoDir;

encoDir getEncoDir(void);
void enco_init(const uint16_t interval);
void ENCODER_EVENT();
void register_enc_event_callback(void(*callback)(void));

#endif /* INC_ENCO_H_ */

main.c

  /* USER CODE BEGIN 2 */
  enco_init(500);
  register_enc_event_callback(encoclb);

  HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_1);
  HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_2);
  /* USER CODE END 2 */

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

	 ENCODER_EVENT();

	  /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

Oraz zarejestrowana funkcja obsługi callbacka:

void encoclb(){
	HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
}

 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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