Skocz do zawartości

Stm32 F103RB Nucleo - Przekłamana wartość w przerwaniu Timera


Pomocna odpowiedź

Napisano

Witam problem jest taki że do zmiennej volatile currentXSpeed przypisuję wartość zmiennej vXMIN. W przerwaniu gdy za pomocą USARTA zwracam tą wartość to zamiast wynosić 1, zwraca mi 0. Jazda z prędkością maksymalną i zjazdem do minimalnej odbywa się poprawnie. Czy mógłby mi ktoś podpowiedzieć co zrobić aby wartość zmiennej currentXSpeed wynosiła tyle ile jej dałe przed przerwaniem ?

Kod:

volatile int times_X_ms = 0;
volatile int stepsX = 10;
float vXMin = 1.0;
float vXMax = 3.0;

int accelXTime = 2;
int decelXTime = 2;

double accelerationX = 0;
double decelerationX = 0;

double accelerationCurrentStep;
double decelerationCurrentStep;

int stepsXAccel = 0;
int stepsXDecel = 0;
int middleXSteps = 0;

volatile float currentXSpeed = 0;
volatile int stepAxisX = 0;
volatile int axisXEnabled = OFF;

void axisXmove(int stepsX, float vXMin, float vXMax,int accelXTime, int decelXTime,  int direction) {
if (axisXEnabled == OFF) {
	accelerationX = (vXMax - vXMin) / (accelXTime * 1000);
	decelerationX = (vXMax - vXMin) / (decelXTime * 1000);

	stepsXAccel = ceil(((vXMin * accelXTime) + ((accelerationX*1000) * (accelXTime * accelXTime)) / 2));
	stepsXDecel = ceil(((vXMin * decelXTime) + ((decelerationX*1000) * (decelXTime * decelXTime)) / 2));
	middleXSteps = stepsX - stepsXAccel - stepsXDecel;

	accelerationCurrentStep = (accelXTime / stepsXAccel) * accelerationX;
	decelerationCurrentStep = (decelXTime / stepsXDecel) * decelerationX;

	if (stepsX >= stepsXAccel + stepsXDecel) {
		if (direction == LEFT){
			sendString("Engine X running. - left\r\n");
			GPIO_SetBits(axisXpin, axisXdir);
		}
		else{
			sendString("Engine X running. - right\r\n");
			GPIO_ResetBits(axisXpin, axisXdir);
		}

		axisXEnabled = ON;
		currentXSpeed = vXMin;

		stepAxisX = 1;
		times_X_ms = 0;
		TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	} else
		sendString(conkat("ERROR: Minimum ",toString(stepsXAccel + stepsXDecel)," steps.\r\n"));
} else
	sendString("ERROR: Engine X is currently enabled.\r\n");
}

void TIM2_IRQHandler() {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {

	if (stepAxisX <= stepsX) {
		times_X_ms++;
		if(times_X_ms == 1)
				sendString(conkat("Speed: ",floatToString(currentXSpeed),".\r\n"));
		if (times_X_ms >= 0 && times_X_ms <= 50) {
			GPIO_SetBits(axisXpin, axisXstep);
		} else {
			GPIO_ResetBits(axisXpin, axisXstep);
		}

			if (stepAxisX < stepsXAccel)
				currentXSpeed += accelerationX;
			else if (stepAxisX <= (stepsXAccel + middleXSteps))
				currentXSpeed = vXMax;
			else {
				if (currentXSpeed <= 1)
					currentXSpeed = vXMin;
				else
					currentXSpeed -= decelerationX;
			}

		if (times_X_ms >= (1000 / currentXSpeed)) {
			times_X_ms = 0;
			stepAxisX++;
		}

	} else {
		axisXEnabled = OFF;
		TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
int main(void) {


while (1) {
	axisXmove(stepsX, vXMin,vXMax,accelXTime,decelXTime, RIGHT);
}
}

Pominąłem inicjalizację wszystkich pinów. W razie potrzeby mogę dorzucić. Z istotnych informacji powiem, ze przerwanie od timera występuje co 1ms. Zatem co mogę zrobić aby wartość zmiennej currentXSpeed zwracała 1 USARTEM, a nie 0. Dziękuję za podpowiedzi.

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