Sida 3 av 4

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

Postat: 16 december 2015, 18:49:57
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.

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

Postat: 17 december 2015, 09:32:23
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.

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

Postat: 17 december 2015, 10:22:08
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

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

Postat: 17 december 2015, 11:09:24
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.

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

Postat: 17 december 2015, 11:12:43
av tecno
(1024 / 3.3)

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

Postat: 17 december 2015, 12:23:43
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();
   }
}

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

Postat: 17 december 2015, 12:39:06
av Jan Almqvist
Du behöver inga interrupt om du bygger upp ditt program annorlunda och tar bort alla delay_ms().

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

Postat: 17 december 2015, 12:45:15
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.

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

Postat: 17 december 2015, 13:05:00
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.

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

Postat: 17 december 2015, 14:20:56
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.

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

Postat: 17 december 2015, 15:41:51
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

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

Postat: 17 december 2015, 15:45:48
av Icecap
Varför definierar du State som en unsigned short?
Det du hämtar och skriver i EEPROM är en unsigned char.

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

Postat: 17 december 2015, 15:49:36
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.

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

Postat: 17 december 2015, 19:54:14
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.

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

Postat: 18 december 2015, 00:21:39
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...