Sari la conținut
ELFORUM - Forumul electronistilor

litrometru pic 16f 676


Postări Recomandate

  • Răspunsuri 23
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Imagini postate

In acel folder, de fapt este un proiect mikroPascal for PIC complet, cu fisier sursa.

 

Fisierul sursa este urmatorul:

program bakometr;

const
   stNormal : byte = 1;
   stCalibr : byte = 2;
   AdrHi : byte = 2;
   litr : array [0..AdrHi] of byte = (0, 127, 255);

var
    C1 : sbit at porta.2;
    C2 : sbit at porta.5;
    C3 : sbit at porta.1;
    
    SW : sbit at porta.3;
    i, j, cc: byte;
    V : word; absolute 0x40;
    Vhi : byte; absolute 0x41;
    VLo : byte; absolute 0x40;
    V100 : word;
    
    L100, L10, L1 : byte;
    dat : array [0..AdrHi] of byte;
    mode : byte;
    calibrN : byte;
    sign : byte;

procedure Razr(V : integer);
begin
  sign := V < 0;
  sign := 0;
  L100 := V div 100;
  V100 := V mod 100;
  L10:= V100 div 10;
  L1 := V100 mod 10;
end;
    
procedure Led(i: short);
begin
  if I=0 then begin
    portc:=$04;
    porta.4:=0;
  end;
  if I=1 then begin
    portc:=$2D;
    porta.4:=1;
  end;
  if I=2 then begin
    portc:=$22;
    porta.4:=0;
  end;
  if I=3 then begin
    portc:=$28;
    porta.4:=0;
  end;
  if I=4 then begin
    portc:=$09;
    porta.4:=1;
  end;
  if I=5 then begin
    portc:=$18;
    porta.4:=0;
  end;
  if I=6 then begin
    portc:=$10;
    porta.4:=0;
  end;
  if I=7 then begin
    portc:=$0D;
    porta.4:=0;
  end;
  if I=8 then begin
    portc:=$00;
    porta.4:=0;
  end;
  if I=9 then begin
    portc:=$08;
    porta.4:=0;
  end;
end;

procedure delay10;
begin
  delay_ms(10);
end;

procedure ReadData;
begin
  for i := 0 to AdrHi do dat[i]:=EEPROM_Read(i);
end;

begin
  porta := %00000000;
  trisa := %11001001;
  portc := %11111111;
  trisc := %00000000;
  wpua  := %00000001;
  cmcon := %00000111;
  ansel := %00000001;
  adcon0:= %00000000;
  adcon1:= %00110000;
  
  mode:=stNormal;
  ReadData;
  ADC_Init;
  i := 0;
  while true do
  begin
    inc(I);
    if mode = stNormal then
    begin
      {if (i.7) and (V<22) then
      begin
        C1:=0;
        C2:=0;
        C3:=0;
      end; }
      if i=0 then
      begin
        V:=ADC_Read(0);
        V:=V shr 2;
        if V<=dat[AdrHi] 
          then V:=litr[adrHi]
          else begin
            if V>=dat[0] 
              then V:=litr[0]
              else begin
                for j:=0 to AdrHi-1 do
                  if (V<=dat[j]) and (V>dat[j+1]) then cc:=j;
                if cc=AdrHi
                  then V:=Litr[AdrHi]
                  else begin
                    V:= (dat[cc]-V);
                    j:=(Litr[cc+1]-Litr[cc]);
                    V:= V * j;
                    j:=(dat[cc]-dat[cc+1]);
                    V:= V / j;
                    V:= V + litr[cc];
                  end;
              end;
          end;
        
        Razr(V);
(*
        sign := V < 0;
        L100 := V div 100;
        V100 := V mod 100;
        L10:= V100 div 10;
        L1 := V100 mod 10;
*)
        //L10 := V div 10;
        //L1  := V mod 10;

        if (SW = 0) then
         begin
         delay_ms(3000);
          begin
           C1 := 1;
           C2 := 1;
           C3 := 1;
           portc := $3B;
           porta.4 := 1;
          
           calibrN := 0;
           mode := stCalibr;
           delay10;
           repeat until SW = 1;
          end;
          delay10;
        end;
      end;
    end;
    
    if mode = stCalibr then
    begin
      Razr(litr[calibrN]);
(*
      //sign := litr[calibrN] < 0;
      L100 := litr[calibrN] div 100;
      V100 := litr[calibrN] mod 100;
      L10  := V100 div 10;
      L1   := V100 mod 10;
*)
      if i > 127 then
      begin
        C1 := 0;
        C2 := 0;
        C3 := 0;
      end;
      if SW = 0 then
      begin
        delay10;
        repeat until SW = 1;
        delay10;
        V:=adc_read(0);
        V:=V shr 2;
        EEPROM_Write(calibrN,VLo);
        inc(calibrN);
        if calibrN>AdrHi then
        begin
           mode:= stNormal;
           CalibrN:=0;
           delay10;
           delay10;
           delay10;
           delay10;
           ReadData;
        end;
      end;
    end;
    
    delay10();
    cc := i mod 3;
    if cc = 2 then begin
      C1 := 0;
      C2 := 0;
      {if sign then begin
        portc := $3B;
        porta.4 := 1;
      end else }
        Led(L100);
      C3 := 1;
    end else if cc = 1 then begin
      C1 := 0;
      C3 := 0;
      Led(L10);
      C2 := 1;
    end else
    begin
      C2 := 0;
      C3 := 0;
      Led(L1);
      C1 := 1;
    end;

  end;


end.
Editat de mars01
Link spre comentariu

Din cate se pare, da.

16F684 are mai multa memorie (flash si SRAM) cat si mai multe module.

 

Dar va trebui sa deschizi proiectul mikroPascal, sa modifici in proprietati registrii CONFIG (s-ar putea sa fie la fel dar nu este sigur) cat si sa schimbi numele uC-ului vechi cu cel nou. In programul efectiv trebuie dezactivat comparatorul suplimentar care se gaseste in 16F684.

Apoi recompilezi si folosesti fisierul .HEX generat.

Editat de mars01
Link spre comentariu

Programul modificat pentru 16F684.

A trebuit umblat la comparatoare, registrul CMCON a devenit CMCON0 si CMCON1 pentru ca 16F684 are 2 comparatoare spre deosebire de 16F676 care are doar unul singur.

Acestea sunt singurele modificari (in afara de modificarea registrilor CONFIG din meniul mikroPascal de configurare a proiectului).

program bakometr;

const
   stNormal : byte = 1;
   stCalibr : byte = 2;
   AdrHi : byte = 2;
   litr : array [0..AdrHi] of byte = (0, 127, 255);

var
    C1 : sbit at porta.2;
    C2 : sbit at porta.5;
    C3 : sbit at porta.1;
    
    SW : sbit at porta.3;
    i, j, cc: byte;
    V : word; absolute 0x40;
    Vhi : byte; absolute 0x41;
    VLo : byte; absolute 0x40;
    V100 : word;
    
    L100, L10, L1 : byte;
    dat : array [0..AdrHi] of byte;
    mode : byte;
    calibrN : byte;
    sign : byte;

procedure Razr(V : integer);
begin
  sign := V < 0;
  sign := 0;
  L100 := V div 100;
  V100 := V mod 100;
  L10:= V100 div 10;
  L1 := V100 mod 10;
end;
    
procedure Led(i: short);
begin
  if I=0 then begin
    portc:=$04;
    porta.4:=0;
  end;
  if I=1 then begin
    portc:=$2D;
    porta.4:=1;
  end;
  if I=2 then begin
    portc:=$22;
    porta.4:=0;
  end;
  if I=3 then begin
    portc:=$28;
    porta.4:=0;
  end;
  if I=4 then begin
    portc:=$09;
    porta.4:=1;
  end;
  if I=5 then begin
    portc:=$18;
    porta.4:=0;
  end;
  if I=6 then begin
    portc:=$10;
    porta.4:=0;
  end;
  if I=7 then begin
    portc:=$0D;
    porta.4:=0;
  end;
  if I=8 then begin
    portc:=$00;
    porta.4:=0;
  end;
  if I=9 then begin
    portc:=$08;
    porta.4:=0;
  end;
end;

procedure delay10;
begin
  delay_ms(10);
end;

procedure ReadData;
begin
  for i := 0 to AdrHi do dat[i]:=EEPROM_Read(i);
end;

begin
  porta := %00000000;
  trisa := %11001001;
  portc := %11111111;
  trisc := %00000000;
  wpua  := %00000001;
  cmcon0 := %00000111;
  cmcon1 := %00000111;
  ansel := %00000001;
  adcon0:= %00000000;
  adcon1:= %00110000;
  
  mode:=stNormal;
  ReadData;
  ADC_Init;
  i := 0;
  while true do
  begin
    inc(I);
    if mode = stNormal then
    begin
      {if (i.7) and (V<22) then
      begin
        C1:=0;
        C2:=0;
        C3:=0;
      end; }
      if i=0 then
      begin
        V:=ADC_Read(0);
        V:=V shr 2;
        if V<=dat[AdrHi] 
          then V:=litr[adrHi]
          else begin
            if V>=dat[0] 
              then V:=litr[0]
              else begin
                for j:=0 to AdrHi-1 do
                  if (V<=dat[j]) and (V>dat[j+1]) then cc:=j;
                if cc=AdrHi
                  then V:=Litr[AdrHi]
                  else begin
                    V:= (dat[cc]-V);
                    j:=(Litr[cc+1]-Litr[cc]);
                    V:= V * j;
                    j:=(dat[cc]-dat[cc+1]);
                    V:= V / j;
                    V:= V + litr[cc];
                  end;
              end;
          end;
        
        Razr(V);
(*
        sign := V < 0;
        L100 := V div 100;
        V100 := V mod 100;
        L10:= V100 div 10;
        L1 := V100 mod 10;
*)
        //L10 := V div 10;
        //L1  := V mod 10;

        if (SW = 0) then
         begin
         delay_ms(3000);
          begin
           C1 := 1;
           C2 := 1;
           C3 := 1;
           portc := $3B;
           porta.4 := 1;
          
           calibrN := 0;
           mode := stCalibr;
           delay10;
           repeat until SW = 1;
          end;
          delay10;
        end;
      end;
    end;
    
    if mode = stCalibr then
    begin
      Razr(litr[calibrN]);
(*
      //sign := litr[calibrN] < 0;
      L100 := litr[calibrN] div 100;
      V100 := litr[calibrN] mod 100;
      L10  := V100 div 10;
      L1   := V100 mod 10;
*)
      if i > 127 then
      begin
        C1 := 0;
        C2 := 0;
        C3 := 0;
      end;
      if SW = 0 then
      begin
        delay10;
        repeat until SW = 1;
        delay10;
        V:=adc_read(0);
        V:=V shr 2;
        EEPROM_Write(calibrN,VLo);
        inc(calibrN);
        if calibrN>AdrHi then
        begin
           mode:= stNormal;
           CalibrN:=0;
           delay10;
           delay10;
           delay10;
           delay10;
           ReadData;
        end;
      end;
    end;
    
    delay10();
    cc := i mod 3;
    if cc = 2 then begin
      C1 := 0;
      C2 := 0;
      {if sign then begin
        portc := $3B;
        porta.4 := 1;
      end else }
        Led(L100);
      C3 := 1;
    end else if cc = 1 then begin
      C1 := 0;
      C3 := 0;
      Led(L10);
      C2 := 1;
    end else
    begin
      C2 := 0;
      C3 := 0;
      Led(L1);
      C1 := 1;
    end;

  end;

end.

Proiectul incluzand is fisierul .HEX este aici.

Editat de mars01
Link spre comentariu

cel cu leduri sigur functioneaza si fizic osa il incerc si pe o placa test , iar cea cu digiti, asta nu functioneaza nici in proteus


la prima pornire in proteus se aprind segmentele G de la ambi digiti si dupaia ramane aprins doar digiti 1 si afiseaza litera U si asa ramane sa vad daca am timp sa il arunc si pe o placa test dar banuiesc ca se comporta la fel

Link spre comentariu

Afisajul este cu anod comun, in simularea ta este cu catod comun.

Sunt mai multe scheme in folderul atasat de tine, in una butonul de calibrare este pus pe pinul 4, in alta pe 13 si probabil ca trebuie gasit hexul corespunzator schemei.

Proiectul testat de mine,care afiseaza corect, este cel slavat cu denumirea ok 2, cu hexul de pe calea "Litrometru\New folder\bakometr 2\bak2.hex" din arhiva atasata la postarea #1 si cu afisaj cu anod comun.

Calibrarea se face din buton, zero insemnand cea mai mare tensiune de pe intrarea analogica si 40l corespunde celei mai mici tensiuni.

Pe intrarea analogica am pus un potentiometru de 10k conectat la 5V.

Link spre comentariu

DA este ok acuma functioneaza ,nu am fost eu atent la tipul de lcd, cu anod comun referitor la hexul pentru pic 16f684 acesta tot nu functioneaza am incercat si cu lcd cu anod comul si cu catod comun si face la fel doar ca pe celalalt digit , ce nu integ eu prea bine este partea cu calibrarea ,potentiometrul lai pus pe pinul 12 ,ce rol are mai exact?

Link spre comentariu

Nu stiu daca pentru mine era intrebarea, insa o sa-ti spun ca potentiometrul din simulare reprezinta sonda de nivel din rezervorul de benzina.

Pentru o indicatie cat mai aproape de realitate, trebuie facuta calibrarea.

In functie de versiunea de hex, ea se face pentru fiecare doi sau patru litri de combustibil adaugati in rezervor.

Calibrarea se face la montarea dispozitivului pe masina sau in cazul in care se inlocuieste sonda de nivel.

Cand rezervorul este gol, se apasa butonul de calibrare, apoi se aduga doi litri de combustibil si se apasa din nou butonul, pe afisaj la fiecare apasare este afisata cantitatea de combustibil pentru care se face calibrarea la acel moment.

Valorile citite de pe intrarea analogica pentru fiecare apasare de buton sunt retinute in eprom, iar asta inseamna ca daca calibrarea este corect realizata, la urmatoarea alimentare a montajului (folosire) nu mai este nevoie de calibrare.

Calibrarea este incheiata cand se ajunge la 40 de litri.

Se pare ca exista prin arhiva si hexuri pentru rezervoare mai mari.

post-179738-0-14559000-1510343727_thumb.jpg

Editat de Elison
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări