Sari la conținut
ELFORUM - Forumul electronistilor

timer digital ciclic cu pic


quinn

Postări Recomandate

acum programul eset in regula ca functionalitate. A mai ramas doar problema cu prima alimentare. ori de cate ori ii iau alimentarea si revin cu ea dupa ce setez ceasul si ii dau start se blocheaza isi revine doar dupa cateva operatii de setare pornire, reset apoi dupa ce isi revine functioneaza fara probleme de cate ori programez. nu-mi dau seama unde ar fi problema.. o sa fac un filmulet sa vedeti despre ce este vorba. daca nu reusesc il folosesc asa, o sa il las alimentat non-stop.

 

Pe alimentarea PIC-ului aveti condensator de 100nF chiar langa soclu ? Asa am patit si eu cu un alt proiect, nu am pus acel cond. si cand cupla releul PIC-ul o lua razna cand se reseta cand se bloca, etc... am stat aproape o zii modificand softul crezand ce e de la soft pana cand am zis ca nu are cum sa fie de la soft, asa am pus acel cond. chiar langa soclu si a pronit. Probabil in momentul cuplarii releul genereaza un impuls care deranjeaza PIC-ul.

 

Daca nu posibil sa fie inca o eroare, de soft pe partea de initilalizare in main() pe care in proteus nu am reusit sa-l reproduc.  

Editat de bandi12
Link spre comentariu

am condensator de 100 nF intre (+) si (-) chiar pe soclu, am si dioda inversa montata pe bobina releului, am incercat si functionarea fara releu si la fel face de fiecare data la prima alimentare. am pus un video https://youtu.be/jOVP2hPHs0g

 

Am inteles. Se pare ca modulul Timer1 (intreruperea la fiecare 100ms) nu isi da drumul. De obieci eu lucrez cu Timer0, dar cum noi avem nevoie de temporizare 1s, Timer1 poate da intrerupere la fiecare 100ms , Timer0 de obieci se foloseste pentru valori mai mici de 10ms. Daca este putem incerca sa trecem la Timer0 si incerc sa obtin un timp cat mai aproape de 1s ( daca tin bine minte intreruperea cu Timer0 era in jur de 9.89ms pierzand ceva din precizie avand in vedera ca ar trebuii 10ms).

 

@quinn Face la fell si varianta cu ciclu repetitiv/montajul realizat sau doar la Myhayxx se intampla ? Ms.

Link spre comentariu

Am trecut inapoi de la Timer1 la Timer0 sa vadem daca face la fell. Timer0 o sa piarda cam 4s/ora la precizie fata de Timer1 ,dar nu cred ca este o mare problema. 

 

Nu stiu de ce ingheata Timer1 la pornire, daca are altcineva o ideie poate ne ajuta. 

 

 

 

 

sbit LCD_RS at RA0_bit;sbit LCD_EN at RA1_bit;sbit LCD_D7 at RB7_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D4 at RB4_bit;// Pin directionsbit LCD_RS_Direction at TRISA0_bit;sbit LCD_EN_Direction at TRISA1_bit;sbit LCD_D7_Direction at TRISB7_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB4_bit;#define relay PORTB.F3volatile int msTime;//char relay=1;int onTime = 6 ; // in secundeint TimeLeft = 6;    // in secundechar *timeToLCD="00m00s";void Init_LCD() {   Lcd_Init();   Lcd_Cmd(_LCD_CURSOR_OFF);   Lcd_Cmd(_LCD_CLEAR);   Lcd_Out(1,6, "Hello!");   delay_ms(1000);   Lcd_Cmd(_LCD_CLEAR);}void InitTimer0(){//Timer0 Registers Prescaler= 256 - TMR0 Preset = 61 - Freq = 100.16 Hz - Period = 0.009984 secondsOPTION_REG.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pinOPTION_REG.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/lowOPTION_REG.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0OPTION_REG.PS2 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bitsOPTION_REG.PS1 = 1;TMR0		 = 61;INTCON	 = 0xA0;}void Interrupt(){  if (TMR0IF_bit){    TMR0IF_bit	 = 0;    TMR0 = 61;    msTime++;  }}void DisplayData() {  int TlSecounds,TlMinutes;  TlMinutes = TimeLeft/60;  TlSecounds = TimeLeft-TlMinutes*60;  Lcd_Out(1,1, "Relay is: ");    if(relay)   Lcd_Out(1,11, "ON ");  else   Lcd_Out(1,11, "OFF ");     Lcd_Out(2,1,"TimeLeft:");  timeToLCD[4] = TlSecounds%10+48;  timeToLCD[3] = TlSecounds/10%10+48;  timeToLCD[1] = TlMinutes%10+48;  timeToLCD[0] = TlMinutes/10%10+48;  Lcd_Out(2,10,timeToLCD);}void DisplaySetupData() { int TlSecounds,TlMinutes;  TlMinutes = onTime/60;  TlSecounds = onTime-TlMinutes*60;  Lcd_Out(2,1,"On Time:");  timeToLCD[4] = TlSecounds%10+48;  timeToLCD[3] = TlSecounds/10%10+48;  timeToLCD[1] = TlMinutes%10+48;  timeToLCD[0] = TlMinutes/10%10+48;  Lcd_Out(2,10,timeToLCD);}void CheckTime() {  if(msTime >= 100 && timeLeft > 0)  {      TimeLeft--;      msTime=0;           /* if(TimeLeft == 0)             // ciclu repetitiv      {        if(relay)          TimeLeft = 15-OnTime;        else          TimeLeft = onTime;                    relay=!relay;            }   */      if(TimeLeft == 0 && relay == 1)   // un singur ciclu      {        //T1CON.F0 = 0;        relay = 0;      }           DisplayData();  }}void SetTime() {    onTime = 0;    Lcd_Cmd(_LCD_CLEAR);    Lcd_Out(1,5,"Set Time");    delay_ms(500);    while(Button(&PORTB,0,10,0) == 0) {        DisplaySetupData();                if(Button(&PORTB,1,10,0))        {          onTime+=60;          delay_ms(250);        }        if(Button(&PORTB,2,10,0))        {          onTime+=1;          delay_ms(250);        }                }    Lcd_Cmd(_LCD_CLEAR);    Lcd_Out(1,2,"Time Setup Done!");    delay_ms(1000);    TimeLeft = onTime;    if(TimeLeft == 0)    {      relay = 0;      //T1CON.F0 = 0;    }    else    {    relay  = 1;    //T1CON.F0 = 1;    }    Lcd_Cmd(_LCD_CLEAR);}void main() {   CMCON  |= 7;   TRISB = 0x7;   relay = 0;   OPTION_REG.F7 = 0;   Init_LCD();   InitTimer0(); //100ms   //T1CON.F0 = 0;   setTime();    while(1)    {      if(Button(&PORTB,0,5,0))         SetTime();          checkTime();    }} 

 

 

Editat de bandi12
Link spre comentariu

Acele 4 secunde sunt calculate teoretic in conditii perfecte cu componente perfect in realitate poate fi mai mult sau mai putin. Daca se doreste precizie cat mai buna atunci se seteaza un interval mai mare (50-40min) si la pornire se noteaza ora actuala, la terminarea timpului se noteaza din nou ora actuala si se verifica cu cat a fost mai mult/ mai putin si de acolo se pot face mici ajustari. 

De exemplu eu am facut un ceas cu afisaj matrice, nu stiu cum am reusit dar am prajit RTC-ul, am fost nevoit sa comand unul nou si pana cand a sosit am utilizat tot asa intrerupere pe timer si am observat ca alimentat de la baterie ceasul intarzia in momentul in care l-am alimentat dintr-un transformator a inceput sa se grabeasca in loc sa intarzie.

 

 

Varianta cu Timer0 pentru ciclu repetitiv :

 

 

 

sbit LCD_RS at RA0_bit;sbit LCD_EN at RA1_bit;sbit LCD_D7 at RB7_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D4 at RB4_bit;// Pin directionsbit LCD_RS_Direction at TRISA0_bit;sbit LCD_EN_Direction at TRISA1_bit;sbit LCD_D7_Direction at TRISB7_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB4_bit;#define relay PORTB.F3volatile int msTime;//char relay=1;int onTime = 6 ; // in secundeint TimeLeft = 6;    // in secundechar *timeToLCD="00m00s";void Init_LCD() {   Lcd_Init();   Lcd_Cmd(_LCD_CURSOR_OFF);   Lcd_Cmd(_LCD_CLEAR);   Lcd_Out(1,6, "Hello!");   delay_ms(1000);   Lcd_Cmd(_LCD_CLEAR);}void InitTimer0(){//Timer0 Registers Prescaler= 256 - TMR0 Preset = 61 - Freq = 100.16 Hz - Period = 0.009984 secondsOPTION_REG.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pinOPTION_REG.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/lowOPTION_REG.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0OPTION_REG.PS2 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bitsOPTION_REG.PS1 = 1;TMR0                 = 61;INTCON         = 0xA0;}void Interrupt(){  if (TMR0IF_bit){    TMR0IF_bit         = 0;    TMR0 = 61;    msTime++;  }}void DisplayData() {  int TlSecounds,TlMinutes;  TlMinutes = TimeLeft/60;  TlSecounds = TimeLeft-TlMinutes*60;  Lcd_Out(1,1, "Relay is: ");    if(relay)   Lcd_Out(1,11, "ON ");  else   Lcd_Out(1,11, "OFF ");     Lcd_Out(2,1,"TimeLeft:");  timeToLCD[4] = TlSecounds%10+48;  timeToLCD[3] = TlSecounds/10%10+48;  timeToLCD[1] = TlMinutes%10+48;  timeToLCD[0] = TlMinutes/10%10+48;  Lcd_Out(2,10,timeToLCD);}void DisplaySetupData() { int TlSecounds,TlMinutes;  TlMinutes = onTime/60;  TlSecounds = onTime-TlMinutes*60;  Lcd_Out(2,1,"On Time:");  timeToLCD[4] = TlSecounds%10+48;  timeToLCD[3] = TlSecounds/10%10+48;  timeToLCD[1] = TlMinutes%10+48;  timeToLCD[0] = TlMinutes/10%10+48;  Lcd_Out(2,10,timeToLCD);}void CheckTime() {  if(msTime >= 100 && timeLeft > 0)  {      TimeLeft--;      msTime=0;            if(TimeLeft == 0)             // ciclu repetitiv      {        if(relay)          TimeLeft = 15-OnTime;        else          TimeLeft = onTime;                    relay=!relay;            }     /* if(TimeLeft == 0 && relay == 1)   // un singur ciclu      {        //T1CON.F0 = 0;        relay = 0;      }         */           DisplayData();  }}void SetTime() {    onTime = 0;    Lcd_Cmd(_LCD_CLEAR);    Lcd_Out(1,5,"Set Time");    delay_ms(500);    while(Button(&PORTB,0,10,0) == 0) {        DisplaySetupData();                if(Button(&PORTB,1,10,0))        {          onTime+=60;          delay_ms(250);        }        if(Button(&PORTB,2,10,0))        {          onTime+=1;          delay_ms(250);        }                }    Lcd_Cmd(_LCD_CLEAR);    Lcd_Out(1,2,"Time Setup Done!");    delay_ms(1000);    TimeLeft = onTime;    if(TimeLeft == 0)    {      relay = 0;      //T1CON.F0 = 0;    }    else    {    relay  = 1;    //T1CON.F0 = 1;    }    Lcd_Cmd(_LCD_CLEAR);}void main() {   CMCON  |= 7;   TRISB = 0x7;   relay = 0;   OPTION_REG.F7 = 0;   Init_LCD();   InitTimer0(); //100ms   //T1CON.F0 = 0;   setTime();    while(1)    {      if(Button(&PORTB,0,10,0))         SetTime();          checkTime();      delay_ms(5);    }} 

 

 

Link spre comentariu

Am incercat sa modific programul astfel incat sa adaug si ore,dar nu merge, ma puteti ajuta? Am mai adaugat un buton pentru a modifica orele la PortA4.  Multumesc frumos!

 

sbit LCD_RS at RA0_bit;sbit LCD_EN at RA1_bit;sbit LCD_D7 at RB7_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D4 at RB4_bit;

// Pin directionsbit LCD_RS_Direction at TRISA0_bit;sbit LCD_EN_Direction at TRISA1_bit;sbit LCD_D7_Direction at TRISB7_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB4_bit;

#define relay PORTB.F3

int msTime;//char relay=1;int onTime = 6 ; // in secundeint TimeLeft = 6;   // in secundechar *timeToLCD="00:00:00";

void Init_LCD() { Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,6, "Hello!"); delay_ms(1000); Lcd_Cmd(_LCD_CLEAR);}

void InitTimer1(){  T1CON = 0x31;  TMR1IF_bit = 0;  TMR1H = 0x0B;  TMR1L = 0xDC;  TMR1IE_bit = 1;  INTCON = 0xC0;}

void Interrupt(){  if (TMR1IF_bit){   TMR1IF_bit = 0;   TMR1H = 0x0B;   TMR1L = 0xDC;   msTime++;  }}

void DisplayData() {  int TlSecounds,TlMinutes,TlHours; TlHours  =  TimeLeft/24; TlMinutes = TimeLeft-TlHours*60;  TlSecounds = TimeLeft-TlMinutes*60;

  Lcd_Out(1,1, "Relay is: ");

  if(relay) Lcd_Out(1,11, "ON ");  else Lcd_Out(1,11, "OFF ");

  Lcd_Out(2,1,"TimeLeft:");  timeToLCD[7] = TlSecounds%10+48;  timeToLCD[6] = TlSecounds/10%10+48;  timeToLCD[4] = TlMinutes%10+48;  timeToLCD[3] = TlMinutes/10%10+48;  timeToLCD[1] = TlHours%10+48;  timeToLCD[0] = TlHours/10%10+48;;

  Lcd_Out(2,10,timeToLCD);}

void DisplaySetupData() { int TlSecounds,TlMinutes,TlHours;  TlHours  =  onTime/24;  TlMinutes = onTime-TlHours*60;  TlSecounds = onTime-TlMinutes*60;

  Lcd_Out(2,1,"OnT:");  timeToLCD[7] = TlSecounds%10+48;  timeToLCD[6] = TlSecounds/10%10+48;  timeToLCD[4] = TlMinutes%10+48;  timeToLCD[3] = TlMinutes/10%10+48;  timeToLCD[1] = TlHours%10+48;  timeToLCD[0] = TlHours/10%10+48;;  Lcd_Out(2,6,timeToLCD);}

void CheckTime() {  if(msTime >= 10)  {   TimeLeft--;   msTime=0;

  if(TimeLeft == 0)   {   if(relay)

  TimeLeft = 3600-OnTime;   else   TimeLeft = onTime;

  relay=!relay;

  }  }

}

void SetTime() {   onTime = 0;   Lcd_Cmd(_LCD_CLEAR);   Lcd_Out(1,5,"Set Time");   delay_ms(500);

  while(Button(&PORTB,0,10,0) == 0) {   DisplaySetupData();

  if(Button(&PORTB,1,10,0))   {   onTime+=60;   delay_ms(250);   }   if(Button(&PORTB,2,10,0))   {   onTime+=1;   delay_ms(250);   }

if(Button(&PORTA,4,10,0))   {   onTime+=10;   delay_ms(250);   }   } }

  Lcd_Cmd(_LCD_CLEAR);   Lcd_Out(1,2,"Time Setup Done!");   delay_ms(1000);   TimeLeft = onTime;   relay  = 1;   Lcd_Cmd(_LCD_CLEAR);}

void main() {

CMCON  |= 7; TRISB = 0x7; TRISA = 0x7; TRISA.RA4 =1; OPTION_REG.F7 = 0; Init_LCD(); InitTimer1(); //100ms setTime();   while(1)   {   if(Button(&PORTB,0,10,0)) SetTime();

  checkTime();   DisplayData();}  }

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