Sari la conținut
ELFORUM - Forumul electronistilor

Solutie pentru DS18B20


mitescu

Postări Recomandate

Utilizarea lui DS18B20 este facila si binecunocuta. In schimb are o deficienta, si anume timpul mare de acces. Acesta face ca in multiple situatii sa nu se poata utiliza intreruperi la o viteza mare. De exemplu : Daca avem o intrerupere data de T0_Overflow la cca 100us, aceasta va fi serios perturbata de citirea lui DS18B20, la care accesul in modul 9BITS este de cca.100ms. Mai mult pentru modul 12BITS, citirea valorilor va fi facuta in peste 800ms, (aproape o secunda). Este evident faptul ca , daca in rutina de deservire a intreruperii vom avea un ceas de timp real, acesta va fi complet perturbat de citirea datelor de la DS18B20.

Intampinind aceasta problema am cautat o solutie si m-am gandit ca poate si altii s-au lovit de aceasta problema. Am gasit o solutie (nu prea ortodoxa) care merge foarte bine si la care timpul de citire a temperaturilor este convenabil pentru una din situatiile de mai sus.

Pe scurt: am cuplat DS18B20 la un MC( de tip tiny) . MC-ul citeste temperaturile si le poate transmite la cerere tot pe 1WIRE catre un MC master.

In attach este o schema cu AT90S2343. Se poate inlocuii cu orice model cu conditia ca frecventa de lucru sa fie de 1MHz.

Programul din MC este:

/***************************************************Chip type           : AT90LS2343Clock frequency     : 1.000000 MHzMemory model        : Tiny*****************************************************/#include <90s2343.h>// 1 Wire Bus functions#asm   .equ __w1_port=0x18 ;PORTB   .equ __w1_bit=4   .def   tmp1=r16   .def   tmp2=r17   .def   tmp3=r18   .equ   portb=0x18   .equ   ddrb=0x17   .equ   pinb=0x16#endasm#include <1wire.h>// DS1820 Temperature Sensor functions#include <ds18b20.h>#define true 1#define false 0char devices;signed int temp;char flag;#pragma regalloc-signed int temperature;#pragma regalloc+unsigned char rom_codes[2][9];// External Interrupt 0 service routineinterrupt [EXT_INT0] void ext_int0_isr(void){#asm          push      tmp3          push      tmp1          push      tmp2                    in        tmp3,sreg          lds       tmp1,_temperature                      ldi       tmp1,8   int1:          sbis      pinb,1          rjmp      int1                   sbi       portb,1          sbi       ddrb,1          ror       tmp1          brcs      int10          cbi       portb,1   int10:          nop          nop          nop          nop          cbi       ddrb,1   int2:          sbic      pinb,1          rjmp      int2          dec       tmp2                brne      int1          lds       tmp1,_temperature+1          ldi       tmp2,8    int3:          sbis      pinb,1          rjmp      int1                   sbi       portb,1          sbi       ddrb,1          ror       tmp1          brcs      int30          cbi       portb,1    int30:          nop          nop          nop          nop          cbi       ddrb,1   int4:          sbic      pinb,1          rjmp      int4          dec       tmp2                brne      int3          pop       tmp1          pop       tmp2          out       sreg,tmp3                 pop        tmp3#endasm          flag=false;}void main(void){PORTB=0x1F;DDRB=0x00;TCCR0=0x00;TCNT0=0x00;// External Interrupt(s) initialization// INT0: On// INT0 Mode: Falling EdgeGIMSK=0x40;MCUCR=0x02;GIFR=0x40;TIMSK=0x00;// 1 Wire Bus initialization          temperature=0xff;w1_init();          devices=w1_search(0xf0,rom_codes);          if(devices)         {         devices=0;           if(ds18b20_init(&rom_codes[0][0],25,35,DS18B20_9BIT_RES))          {          devices=1;          temperature=0xaa;          }         }#asm("sei")while (1)      {            if(devices)        {         flag=true;         temp= ds18b20_temperature(&rom_codes[0][0]);         if(flag==true){temperature=temp;}        }      };}
Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • mitescu

    3

  • XAN77

    2

  • danzup

    1

Top autori în acest subiect

Utilizarea lui DS18B20 este facila si binecunocuta. In schimb are o deficienta, si anume timpul mare de acces. Acesta face ca in multiple situatii sa nu se poata utiliza intreruperi la o viteza mare. De exemplu : Daca avem o intrerupere data de T0_Overflow la cca 100us, aceasta va fi serios perturbata de citirea lui DS18B20, la care accesul in modul 9BITS este de cca.100ms. Mai mult pentru modul 12BITS, citirea valorilor va fi facuta in peste 800ms, (aproape o secunda). Este evident faptul ca , daca in rutina de deservire a intreruperii vom avea un ceas de timp real, acesta va fi complet perturbat de citirea datelor de la DS18B20.Intampinind aceasta problema am cautat o solutie si m-am gandit ca poate si altii s-au lovit de aceasta problema. Am gasit o solutie (nu prea ortodoxa) care merge foarte bine si la care timpul de citire a temperaturilor este convenabil pentru una din situatiile de mai sus.Pe scurt: am cuplat DS18B20 la un MC( de tip tiny) . MC-ul citeste temperaturile si le poate transmite la cerere tot pe 1WIRE catre un MC master.In attach este o schema cu AT90S2343. Se poate inlocuii cu orice model cu conditia ca frecventa de lucru sa fie de 1MHz.

Si eu am patit acelasi lucru si am folosit doua attiny2313 unul care afiseaza multiplexat pe LED si celalat care citeste (am un ciclu de citire de la device-ul respectiv de 950ms !!!!!) interconectate ca si la tine pe 1WIRE .
Link spre comentariu

din cate stiu conversia temperaturii este functie de rezolutie si mare intradevar, la 12 biti conform datasheet este de 750 mS. DAR citirea propriu-zisa a valorii temperaturii din senzor se face in mult mai putin timp; cred eu ca in cateva mS, pana in 5 . Sau am eu o parere eronata..

Link spre comentariu

din cate stiu conversia temperaturii este functie de rezolutie si mare intradevar, la 12 biti conform datasheet este de 750 mS. DAR citirea propriu-zisa a valorii temperaturii din senzor se face in mult mai putin timp; cred eu ca in cateva mS, pana in 5 . Sau am eu o parere eronata..

Intradevar un ciclu de citire dureaza cam 5ms, dar daca (asa cum spuneam) intreruperea este la fiecare 100us, este clar ca ea va fi perturbata in mod serios, pe scurt se pierd cca 50 de intreruperi. In afara de asta dupa un ciclu de citire mai trebuie si cate un ciclu de RESET si o comanda de START conversie. Am incercat in intrerupere sa "FELIEZ" rutina ptr DS18B20 pe intrerupere . Am obtinut rezultate bune, dar codul este imens ca dimensiune, si pe la soroace se mai pierde cate o intrerupere. Nici asta nu ar fi grav , dar daca mai exista si o alta intrerupere (ex. INT0) totul s-a terminat. Cu montajul de mai sus, chiar daca apar decalaje de timp pe comunicatie, nu exista nicio problema, pe langa faptul ca se transfera numai doi octeti, valoarea citita.
Link spre comentariu

Citeste list-ul pus, si ai sa vezi ca nu este chiar 1Wire, chiar poate fi intrerupt un timp f. mare si tot se "conformeaza". deci rutina de citire se poate scrie in afara intreruperilor fara a se da "cli" si "sei", prin urmare intreruperile nu vor fi perturbate.

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