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

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.