Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Operazioni tra numeri di tipo diverso

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Operazioni tra numeri di tipo diverso

Messaggioda Foto Utenteemacar » 10 mag 2017, 10:20

Buongiorno a tutti,
sto lavorando con un MCU a 32 bit dell'Infineon, l' XMC4500.
Nel mio firmware c'è un interrupt in cui ho scritto il seguente codice. Anche se credo sia un dettaglio inutile, questo codice crea un dente di sega all'uscita di un DAC e così per come è scritto funziona.
Codice: Seleziona tutto
/*Start*********************************************VCO driver********************************************************/
void UserIRQHandler(void)
{
   static int32_t DACValLin = -279;
   static int32_t DACVal = -279;

        DAC_SingleValue_SetValue_s16(&Coarse_Fine_VCO,DACValLin);
   DACValLin += 4;

   if (DACValLin > 1303)
      {
      DACValLin = -279;
      }
}
/*End***********************************************VCO driver********************************************************/

Ho bisogno però di modificarlo un po' e per farlo ho bisogno di aggiungere delle variabili e fare dei conti. Ho aggiunto le seguenti righe di codice:
Codice: Seleziona tutto
   float32_t BintoV = 0;
   BintoV = 0.0005*DACValLin+1.4003;

Qui anche se la variabile BintoV non viene ancora utilizzata da nessuna parte, succede un casino! Lo script che ho postato prima continua a funzionare ma non mi funziona altro nel firmare (ad esempio non funziona più l' ADC). Credo di aver capito che il problema sia che faccio operazioni tra variabili di tipo diverso ed infatti ho corretto il codice nel seguente modo, risolvendo il problema:
Codice: Seleziona tutto
   float32_t BintoV = 0;
        BintoV = (float32_t)(0.0005*DACValLin) + (float32_t)1.4003;

Credevo di aver imparato una cosa nuova e di poter continuare così ma poi avrei bisogno di scrivere il seguente codice:
Codice: Seleziona tutto
   float32_t BintoV = 0;
   float32_t VtoV = 0;

   BintoV = (float32_t)(0.0005*DACValLin) + (float32_t)1.4003;
   
        VtoV = 0.2627*BintoV*BintoV + 0.11*BintoV + 0.7107;
   DACVal = 1862.3*VtoV - 2607.7;

Che invece non riesco proprio a far funzionare. Credo che il problema possa essere banale e sia dovuto alla mia ignoranza sulle operazioni che posso fare tra i vari tipi del MCU ma non riesco proprio a sbrogliare la matassa! ?%
Un'altra cosa che mi confonde è che lo script sembra funzionare ma i problemi li ho in altre parti del firmware (es. l'ADC che non c'entra nulla con questo script).
Grazie a chiunque avrà la pazienza e la bontà di leggere quanto ho scritto,
Emanuele
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

0
voti

[2] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto Utentemed90 » 10 mag 2017, 10:42

Io proverei una cosa del genere



Codice: Seleziona tutto
float32_t appo=0;
appo=1862.3*VtoV - 2607.7;
DACVal=(int32_t) appo;
Avatar utente
Foto Utentemed90
45 2
 
Messaggi: 26
Iscritto il: 18 apr 2017, 15:58

0
voti

[3] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto UtenteEcoTan » 10 mag 2017, 11:06

Veramente non dovrei rispondere perché di micro capisco pochissimo. Dico solo che molte stranezze sono cessate da quando ho preso l'abitudine di dichiarare le variabili prima del programma cioè nell'area common (dove però c'è meno spazio).
Altro utile accorgimento testare i valori prima di fare operazioni che potrebbero andare in overflow. E poi non fare certe operazioni in C direttamente sui registri.
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5420
Iscritto il: 29 gen 2014, 8:54

0
voti

[4] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto Utenteemacar » 10 mag 2017, 12:08

Foto Utentemed90 Grazie per la risposta, ho provato il tuo codice ma niente :cry:
Ho dovuto però sostituire VtoV con BintoV perché anche la riga con VtoV (l'ho riportata sotto) mi da problemi per cui per provare il tuo codice l'ho rimossa.
Codice: Seleziona tutto
VtoV = 0.2627*BintoV*BintoV + 0.11*BintoV + 0.7107;

Foto UtenteEcoTan Grazie mille anche a te per le dritte. Non le ho dichiarate nell'area common sia perché ho già una marea di variabili dichiarate li e sia perché queste variabili servono solo a questa funzione. Facendo il debug i valori sono corretti ovvero i valori che assumono le variabili coincidono con quelli che calcolo io con carta e penna mentre non ho capito (probabilmente per ignoranza mia) cosa intendi per non fare certe operazioni in C direttamente sui registri...

Tutto sembra funzionare benissimo, i valori sono corretti ma intanto l'interrupt relativo al ADC (che ripeto non dovrebbe c'entrare assolutamente niente) non funziona più ?%
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

0
voti

[5] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto Utenteemacar » 10 mag 2017, 12:30

Ok lo so io me la canto e io me la suono..ho risolto!!!
Ho fatto così:
Codice: Seleziona tutto
/*Start*********************************************VCO driver********************************************************/
void UserIRQHandler(void)
{
   static int32_t DACValLin = -279;
   float32_t BintoV = 0;
   float32_t VtoV = 0;
   static int32_t DACVal = -279;

   BintoV = 5*DACValLin+14003; //x10000
   BintoV=BintoV/10000;
   //BintoV = (float32_t)(0.0005*DACValLin) + (float32_t)1.4003;
   VtoV = 2627*BintoV*BintoV + 1100*BintoV + 7107;//x10000
   VtoV = VtoV/10000;
   DACVal = 18623*VtoV - 26077; //x10
   DACVal = DACVal/10;
   //VtoV = (float32_t)((float32_t)0.2627*BintoV);
   //DACVal = (int32_t)(1862.3*VtoV - 2607.7);
   DAC_SingleValue_SetValue_s16(&Coarse_Fine_VCO,DACVal);
   DACValLin += 4;

   if (DACValLin > 1303)
      {
      DACValLin = -279;
      }
}
/*End***********************************************VCO driver********************************************************/

Provo a dare un interpretazione: scrissi che questo codice funzionava mentre era il resto del FW che non funzionava ma mi sbagliavo. Non mi ero accorto che si era modificata la temporizzazione di questo interrupt.
Provo a supporre che le operazioni algebriche che avevo scritto inizialmente fossero molto onerose per il micro e che impiegando troppo tempo faceva saltare tutto il resto del FW. Scrivendole come sopra (eseguendo moltiplicazioni e addizioni solo con interi) funziona.
In tutto ciò per quanto abbia fatto queste supposizioni, non sono proprio sicuro che i miei ragionamenti siano esatti, se qualcuno mi sapesse spiegare per bene cosa ho combinato gliene sarei grato :D
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

1
voti

[6] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto UtenteEcoTan » 10 mag 2017, 13:09

emacar ha scritto:cosa intendi per non fare certe operazioni in C direttamente sui registri

Le operazioni aritmetiche e logiche le faccio in variabili da me dichiarate così conosco con certezza se siano considerate int oppure unsigned int.
Anche se non c'entra (quasi) niente, riporto una frase dall'help di un compilatore Basic:
R12 – R15 are not saved. When you use floating point math in the ISR(not recommended) you must save and restore R12-R15 yourself in the ISR.
Tu che compilatore adoperi?
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5420
Iscritto il: 29 gen 2014, 8:54

2
voti

[7] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto Utentexyz » 10 mag 2017, 20:06

Quel micro controllore è un ARM Cortex-M4 ?
Quel ARM ha il float point in hardware ?
Esegui dei calcoli in float point in un interrupr con FPU hardware abilitata ?

Se le risposte sono tutte e 3 si allora il tuo problema è che non hai letto bene il datasheet del ARM, i registi della FPU non vengono salvati in automatico, deve essere il programmatore a farlo nel codice e dipende dal compilatore utilizzato:

http://infocenter.arm.com/help/index.js ... index.html
https://sites.google.com/site/sippeyfun ... -cortex-m4

Consiglio se possibile di non fare i calcoli in float point negli interrupt ma nel ciclo principale e di utilizzare solo numeri interi del codice degli interrupt.
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[8] Re: Operazioni tra numeri di tipo diverso

Messaggioda Foto Utenteemacar » 12 giu 2017, 9:06

Scusatemi ma per impegni di lavoro non mi sono più collegato su Electroyou e poi non ho più controllato la presenza di ulteriori risposte. Grazie a tutti per gli ultimi consigli che naturalmente approfondirò!
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti