Skocz do zawartości

Nadpisywanie danych w buforze DMA w trybie cyklicznym.


Pomocna odpowiedź

Napisano

Witam piszę sterownik silnika krokowego z użyciem DMA. Skonfigurowałem również przerwanie od DMA, które występuję w połowie wysyłania danych i na końcu paczki. Paczka zawiera 3 elementy

Period, Repetition COunter Pulse. Chciałbym zadać pytanko czy ja nadpisuje wartości w przerwaniu i tam mają być zawarte obliczenia ? czy jak wykonywane są obliczenia w jakiejś tam funkcji X i zapisywane dane do bufora, to co przerwanie dane same się nadpisują ?

Zamieszczam kod bez uSARTA żeby nie było za dużo.

float vMax = 10.0;

int accelerationTime = 10;
int decelerationTime = 10;

int totalSteps = 120;
int currentStep = 0;
//============Szukane==========
float accelerationPerSec = 0;
float decelerationPerSec = 0;

float accelerationPerStep = 0;
float decelerationPerStep = 0;

int stepsAcceleration = 0;
int stepsDeceleration = 0;

//============================
float currentSpeed = 0.0;
float accelSpeedSum = 0.0;
float initialPeriod = 0;
float diffrencePeriod = 0;
float maxPeriod = 0;
float period = 0;

float tab[120];
u16 bufor1[120 * 3];

int main(void) {
   GPIO_Config();
   TIM_Config();
   DMA_Config();
   PWM_Config();
   obliczSzukane();
   obliczPredkosc();
   obliczOkres();
   while (1) {
   }
}
/*
*
* FUNKCJE
*
*/

void obliczSzukane(void) {
   accelerationPerSec = (vMax - vMin) / (accelerationTime);
   decelerationPerSec = (vMax - vMin) / (decelerationTime);

   stepsAcceleration = ceil(((vMin * accelerationTime) +
       (accelerationPerSec * (accelerationTime * accelerationTime)) / 2));
   stepsDeceleration = ceil(((vMin * decelerationTime) +
       (decelerationPerSec * (decelerationTime * decelerationTime)) / 2));

   if (totalSteps <= stepsAcceleration + stepsDeceleration)
       totalSteps = stepsAcceleration + stepsDeceleration + 1;

   accelerationPerStep = ((float)accelerationTime / ((float)stepsAcceleration) * accelerationPerSec);
   decelerationPerStep = ((float)decelerationTime / (float)stepsDeceleration) * decelerationPerSec;
}
void obliczPredkosc(void) {
   for (currentStep = 0; currentStep < totalSteps; currentStep++) {
       if (currentStep == 0) {
           currentSpeed = vMin;
           accelSpeedSum += currentSpeed;
       }
       else if (currentStep < stepsAcceleration) {
           currentSpeed += accelerationPerStep;
           accelSpeedSum += currentSpeed;
       }
       else if (currentStep < totalSteps - stepsDeceleration)
           currentSpeed = vMax;
       else
           currentSpeed -= decelerationPerStep;
       tab[currentStep] = currentSpeed;
   }
}

void obliczOkres(void) {
   initialPeriod = tab[stepsAcceleration - 1] * accelerationTime * 1000 / accelSpeedSum;
   diffrencePeriod = initialPeriod - tab[stepsAcceleration - 2] * accelerationTime * 1000 / accelSpeedSum;
   maxPeriod = initialPeriod - diffrencePeriod * stepsAcceleration;

   for(currentStep = 0; currentStep < totalSteps; currentStep++) {
       if(currentStep == 0)
           period = initialPeriod;
       else if (currentStep < stepsAcceleration)
           period -= diffrencePeriod;
       else if (currentStep < totalSteps - stepsDeceleration)
           period = maxPeriod;
       else
           period += diffrencePeriod;
       bufor1[currentStep * 3] = round(period);
       bufor1[currentStep * 3 + 1] = 0;
       bufor1[currentStep * 3 + 2] = round(period / 2);
   }
   TIM1 -> EGR = TIM_EGR_UG;

}
 void DMA1_Channel1_IRQHandler(void)
{
 if (DMA_GetITStatus(DMA1_IT_TC1) != RESET) // DMA1_IT_TC1 - Channel1 transfer complete interrupt
 {
   DMA_ClearITPendingBit(DMA1_IT_TC1);
 }
 if (DMA_GetITStatus(DMA1_IT_HT1) != RESET) // DMA1_IT_HT1 - DMA1 Channel1 half transfer interrupt
 {
   DMA_ClearITPendingBit(DMA1_IT_HT1);
 }
}

"Chciałbym zadać pytanko czy ja nadpisuje wartości w przerwaniu.."

Wygląda, że w przerwaniu niczego nie nadpisujesz. Na pewno napisałeś ten kod? Bo chyba niemożliwe żebyś nie widział gdzie jest funkcja ISR i co robi.

"czy jak wykonywane są obliczenia w jakiejś tam funkcji X i zapisywane dane do bufora, to co przerwanie dane same się nadpisują"

Co ma się nadpisywać na czym? Mają być zamazywane jakieś buufory? Czym? Tu nic takiego się nie dzieje. Jednokrotnie wywołujesz każdą funkcję w main() więc każda wykona się tylko raz. Nawiasem mówiąc najpierw inicjalizujesz DMA i timery, to wszystko rusza(?) a dopiero późnej obliczasz potrzebne parametry, których te mechanizmy mają używać. Trochę głupie, nie sądzisz?

Wydaje mi się, ze jakoś generalnie nie rozumiesz działania DMA a my, nie widząc wyciętych funkcji XXX_config() nie wiemy co system naprawdę robi lub miał robić. Czy mógłbyś opisać własnymi słowami jak to miało działać? Co obliczasz i wpisujesz do buforów, na podstawie jakich algorytmów i jak to później miało być wykorzystane gdy już while(1) się zacznie? W prostych, żołnierskich słowach. W jakim trybie pracuje timer, co nim ma sterować i po co?

No i te "pytanka" jakieś odklejone. Pytasz bo nie rozumiesz działania własnego kodu czy nie wiesz jak ma wyglądać? To może opisz to co chcesz zrobić a nie to co zrobiłeś? Jest tu wielu doświadczonych ludzi od STM32, doradzą Ci jak to powinno być zrobione.

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