Lite klarhet i varför ROM slukas i PIC

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

bearing skrev:Ett sätt att göra koden "snygg" är att definiera en "enhet" i form av en konstant.
Eftersom att programmet har variabler med namnet shunt gissar jag att det handlar om ström-mätning.
Då kan man göra typ såhär:

Kod: Markera allt

#define MAX_CURRENT 3300
#define MAX_ADC 1024
#define mA (1UL * MAX_ADC / MAX_CURRENT)
#define CURRENT_LIMIT_LOW  (1000 * mA)
#define CURRENT_LIMIT_HIGH (2000 * mA)

...

CurrentLimit = CURRENT_LIMIT_LOW;
Nu har jag skrivit med heltal, men på många kompilatorer kan man ha decimaltal i dom här konstanterna, ty förkompilatorn räknar i flyttal och sedan trunkerar till heltal ifall konstanten skrivs till en integer. Dock inte alla kompilatorer / förkompilatorer, har jag märkt.
Men ifall din förkompilator hanterar flyttal och trunkerar, kan du skriva konstanterna i t.ex. ampere med decimaler, om du önskar.
Låter vettigt.

Precis är det strömmätning det handlar om.
Shimonu
Inlägg: 327
Blev medlem: 21 oktober 2015, 22:44:33

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Shimonu »

sodjan skrev:> Vill någon förklara vad som möjligen händer i kompilatorn. Är det att stöd saknas för
> flyttalsberäkningar och det får helt enkelt göras i mjukvara istället?

Förstår inte riktigt vad du frågar om... Det är ju ganska självklart
att om processorn inte har någon flyttalsenhet i hårdvaran så
får det göras med programvara istället. Så är det ju alltid !?

Man jag kanske missförstod frågan...
Jag var möjligen lite otydlig. Visst kändes det självklart men jag föreställde mig att göra beräkningen i assembler och förstod inte hur en flyttalsberäkning i mjukvara skulle ta så mycket plats. När någon nämnde att det är ett helt lib som laddas in blir det dock självklart.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Icecap »

Själva beräkningen kunde nog ha gjorts på ett sätt som gjorde det enklare.
ShuntValue=(ShuntValue*3.3)/1024; // Det är ju flyttal i den merkerade delen.

ShuntValue=(ShuntValue / 310); // Hade givit samma resultat utan flyttal
ShuntValue=(ShuntValue/((uint_16)(1024 / 3.3)); // Hade klarats utan flyttal vid att kompilern hade fixat uträkningen från början
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

ShuntValue=(ShuntValue / 310); // Hade givit samma resultat utan flyttal

är intte med hur du kommer fram till 310? hur jag än räknar hamnar jag lite off från din siffra.
Senast redigerad av newbadboy 17 december 2015, 11:14:35, redigerad totalt 2 gånger.
Användarvisningsbild
tecno
Inlägg: 27252
Blev medlem: 6 september 2004, 17:34:45
Skype: tecnobs
Ort: Sparreholm, Södermanland N 59° 4.134', E 16° 49.743'
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av tecno »

(1024 / 3.3)
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

Jag får inte det till att lira. Den verkar inte läsa ngt adc värde. Har en extern spänningskälla där jag ställt tillräckligt högt värde men den reagerar inte.

adc ingång 3 används.

Däremot varje gång jag spännningsätter kortet går den genom while loopen i main en gång, går in i CurrentMeas() och där tycker den då att den läser ett högtt ADC värde då den går in i den lilla while loopen och väntar på knapptryckning. Efter jag tryckt på knappen snurrar koden igen bortsett från att den inte reagerar på adc värden.

Beteendet ovan får jag även om jag jordar adc ingången :(...

Till sist måste jag också göra om CurrentMeas() till ngn form av mjukvaru interrupt så att säga. Jag vill att den ska reagera snabbt på strömförändringar och ligger jag inne i ngn delay som tänder LED så blir det en onödig fördröjning.

Här kommer hela koden så ni slipper gissa. Jag har kastat om s mycket grejer nu så ag har tappat tråden lite.

Kod: Markera allt

#define LoadCTRL GPIO.F2
#define Reset GPIO.F1
#define LedOut GPIO.F5

unsigned short State;
int a, ShuntValue, Currentlimit;


void InitMain(){
   TRISIO=0b00001010;
   ANSEL=0b00001000;
   CMCON=0b00000111;
   
   LoadCTRL=1;                            //utgång av innan eeprom värde är inläst
   State=EEPROM_Read(0x80);
   LoadCTRL=0;                              //sätt igång +5V utgång

   
   if((State!=1)&&(State!=2)&&(State!=3)){           //allra första gången vid start kan det finnas ngt konstigt i minnet. Finns det ngt annat än siffran 1,2 eller 3 skirver man en etta för  att
       State=1;                                                //undvika konstiga beteende
       EEPROM_Write(0x80,0x1);
       }

   for(a=0; a<7; a++){
       LedOut=1;
       delay_ms(50);
       LedOut=0;
       delay_ms(50);
       }
    delay_ms(500);
    }
    
void CurrentSet(){
     if(State==1)
       Currentlimit=936;                         //520mA          för att fåcdet till int    0.936x1000=936
     else if(State==2)
            Currentlimit=1656;                   //920mA
     else if(State==3)
            Currentlimit=2736;                  //1520mA
     }

void ModeINCR(){
    State++;
    if(State>3){
       State=1;
       }
    EEPROM_Write(0x80,State);
    CurrentSet();
    while(Reset==0){                            //utan denna räknas State kontinuerligt så länge man håller in knappen. Denna ska bara räkna ett steg för varje knapptryck
         LedOut=1;
         }
    }
    
void LEDmode(){
    if((State==1)&&(Reset=1)){
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(1000);
    }
    if((State==2)&&(Reset=1)){
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(150);
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(1000);
    }
    if((State==3)&&(Reset=1)){
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(150);
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(150);
    LedOut=1;
    delay_ms(100);
    LedOut=0;
    delay_ms(1000);
    }
   }
    
void CurrentMeas(){
     ShuntValue=ADC_Read(3);
     ShuntValue=(ShuntValue/310);                   //1024/3.3=310
     if(ShuntValue>CurrentLimit){
       delay_ms(3);
       ShuntValue=ADC_Read(3);
       ShuntValue=(ShuntValue/310);
       if(ShuntValue>CurrentLimit){
          while(Reset==1){
                LoadCTRL=1;
                LedOut=1;
                }
         }
       LoadCTRL=0;
       }
     }

void main() {
   InitMain();
   
   while(1){
   
         if(Button(&GPIO, 1, 200, 0)){
            ModeINCR();
            }
         LEDmode();
         CurrentMeas();
   }
}
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Jan Almqvist »

Du behöver inga interrupt om du bygger upp ditt program annorlunda och tar bort alla delay_ms().
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Icecap »

Det första steget är väl att verifiera att input tas emot på rätt sätt och att omräkningen sker korrekt.

När det är klart kan man öka på men jag håller med om att delay_ms() är en oskick.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

Jan Almqvist skrev:Du behöver inga interrupt om du bygger upp ditt program annorlunda och tar bort alla delay_ms().
Det är sant, jag har tänkt på det också. Kan ju göra lite räknare istället tex som vid visst värde tänder Leden.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Icecap »

if((State!=1)&&(State!=2)&&(State!=3))

kan skrivas
if((State < 1) || (State > 3))

jag tycker att det är enklare att läsa.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

Skrev så först men så var jag inte säker om det på ngt sätt kanske skulle finnas ngt odefinierat i minnet. Jag vill med andra ord verkilgen sätta gärnser som vad som får finnas där så man inte får ngt skumt beteende.

Nu har jag gjort om LedOut funktionen helt utan delays utan bara med räknare.

Kvar har jag fortfarande ADCn att lösa/hitta felet
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av Icecap »

Varför definierar du State som en unsigned short?
Det du hämtar och skriver i EEPROM är en unsigned char.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av newbadboy »

Jag kollade help filen i mikroc och där stod att man skulle def det som unsignef short för 16f medans för 18f skulle det vara ngn annan variant.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av bearing »

Det är något uppenbart feltänk här.

Kod: Markera allt

Currentlimit=2736;
...
     ShuntValue=ADC_Read(3);
     ShuntValue=(ShuntValue/310);
     if(ShuntValue>CurrentLimit)
Högsta värdet från ADC_Read är 1023?
Dividerat med 310, blir ShuntValue <= 3. ShuntValue kan alltså omöjligt nå 2736.

Tidigare lät det som att du skulle köra med Sodjans förslag att använda råa ADC-värdet, d.v.s ShuntValue=ADC_Read(3)
I så fall är det något som är felräknat med CurrentLimit, för de värdena bör ju vara under 1024.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Lite klarhet i varför ROM slukas i PIC

Inlägg av sodjan »

Ja, precis...

> I verkligheten är det ca 900mv 1560mv och 2700 mv.

Vid 3.3 V Vref ger det ca 280, 484 och 837 som utvärde från ADC.

Så t.ex:

Kod: Markera allt

Currentlimit=837;
...
     ShuntValue=ADC_Read(3);
     if(ShuntValue>CurrentLimit)
borde fungera. Som sagt, det är lika bra att jämföra direkt
mot de aktuella nivåerna från ADCn...
Skriv svar