Sari la conținut
ELFORUM - Forumul electronistilor

Invatat programare de la zero


riciu

Postări Recomandate

Va referiti la registrii timerului, nu?

Eu am zic ca posibil sa fie de acolo, nu ca ar fi din acest motiv....in al doilea rand sunteti singurul care ma ajuta pe aici...nu am mai vazut pe nimeni...momentan am plecat de la serviciu (acolo imi bat capul cu C in timpul cand nu lucrez in electronica)...cei de acolo nu prea ma ajuta, le e frica sa nu le iau painea probabil, in ghilimele...acum sunt inscris la master, sper sa imi arate ceva pe acolo, oricum din Electrotehnica nu am priceput nimic...totul din practica...si electronica o stiam fara facultate....

 

Maine mai lucrez la el, si mai vedem...

Link spre comentariu

Nu, nu cred ca timer-ul are ceva atata timp cat fara partea acea cu LED-ul, se misca bine.

Pur si simplu, daca nu exista o problema de read-write-modify atunci nu vad ce ar putea sa fie intr-un program atat de simplu si care sa influenteze LCD-ul.

Asa cum este setat LCD-ul in programul postat anteiror, pinul RS nu este parte a portului B.

Link spre comentariu

:91 Programul actual este acesta:

#define pompa_dir TRISC.F1      //pompa pe iesirea RC1
#define pompa PORTC.F1
#define hidro_dir TRISC.F0      //hidrofor pe iesirea RC0
#define hidro PORTC.F0
#define LED_dir TRISC.F2        //indicator pompa pe iesirea RC2
#define LED PORTC.F2

#define buton_dir TRISC.F4      //butonul pe intrarea RC4
#define buton PORTC.F4

#define INPUT        1;
#define OUTPUT       0;

// enumeratie anonime pentru a salva diferite stari
enum
{
   OFF = 0,
   ON  = 1
};

//enumeratie pentru salvarea starilor din FSM
typedef enum States
{
   IDLE ,
   RUN,
   HIDRO_OFF
} state_t;

state_t state;                            // variable of type state_t
volatile unsigned long timer_cnt = 0;     // variable to store time in multiples of 0.1sec
unsigned long initial_time;               // var to store the initial time
unsigned volatile long cnt=0;
//LCD setare porturi iesire
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D4 at RB5_bit;
//Sfarsit LCD conect

// pini catre porturi
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D4_Direction at TRISB5_bit;
//terminare setare pentru lcd

// clear the watchdog timer
void clrwdt()
{
   asm CLRWDT;
}

void hw_init(void)
{
   clrwdt();
   // make sure that the oscillator is running at 8MHz cred ca doar cu oscilator intern
   //IRCF2_bit = 1;
   //IRCF1_bit = 1;
   //IRCF0_bit = 1;

   ADON_bit = 0x00;           // disable ADC
   ADCON1 = 0xFF;             // set all ADC pins as digital

   Lcd_Init();                // Initialize LCD
   Lcd_Cmd(_LCD_CLEAR);       // Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);  // Cursor off

   pompa_dir = OUTPUT;        //pompa ca iesire
   hidro_dir = OUTPUT;        //hidro ca iesire
   buton_dir = INPUT;         //buton ca intrare
   LED_dir = OUTPUT;

   pompa = OFF;               //pompa stare initiala off
   hidro = ON;                //hidrofor stare initiala on

   //initializare timer
   T1CKPS1_bit = 1;          //Pre-scaler 1:1
   T1CKPS0_bit = 0;
   TMR1ON_bit = 1;           // start Timer1
   TMR1IF_bit = 0;           // clear Timer1 interrupt flag
   TMR1H         = 0x3C;     // Clear High byte
   TMR1L         = 0xB0;     // Clear Low byte
   TMR1IE_bit  = 1;          // Disables Enables the TMR1 overflow interrupt
   PEIE_bit = 1;             // Enable Peripheral Interrupt
   GIE_bit = 1;              // start interrupts

  // SWDTEN_bit = 1;         // enable watchdog; the watchdog postscaler was set at 1:256 that means an reset interval of 4ms x 256 = 1024ms = 1.024sec

}

void Interrupt()
{
   // Timer1 one Interrupt rate is 100ms = 0.1s
   if (TMR1IF_bit && TMR1ON_bit)
   {
      TMR1IF_bit = 0;           // clear Timer1 interrupt flag
      TMR1H         = 0x3C;     // Clear High byte
      TMR1L         = 0xB0;     // Clear Low byte
      timer_cnt++;

        if (pompa == ON)
      {
         cnt++;
         if (cnt == 5)
         {
             cnt = 0;
             LED = !LED;
         }
         else
         {
             cnt++;
         }
      }
      else
      {
         LED = OFF;
      }
   }
}

// VERIFICARE STARI BUTON
unsigned char check_button (void)
 {
   static unsigned char anterior_buton = 1; // starea initiala a butonului este OFF
   clrwdt();
   if (buton == 1)
   {
   anterior_buton = 1;
   }
   if (buton == 0 && anterior_buton == 1)
   {
      delay_ms(200);
      if (buton == 0)
       {
         anterior_buton = 0;
         return 1;
      }
   }
   else return 0;
}

// initialize the timer_cnt variable
void init_timer()
{
   timer_cnt = 0;
}

// return the timer_cnt variable value
unsigned long timer_func ()
{
   volatile unsigned long temp;           // declared as volatile so it will not be optimized
   clrwdt();                              //clear watchdog
   GIE_bit = 0;                           // disable interrupts
   temp = timer_cnt;                      // copy the value of timer variable into the shadow variable named temp
   GIE_bit = 1;                           // enable interrupts

   return temp;                      // return the timer variable
}

void idle_func ()
 {
   hidro = ON;
   pompa = OFF;
   clrwdt();
   if (check_button() == ON)
   {
      state = RUN;
      init_timer();
      initial_time = timer_func();
   }
}

void run_func()
{
   pompa = ON;
   clrwdt();
   // if time is less than 15'
   if ((timer_func() - initial_time) < 4000)
   {
      if (check_button() == ON)
      {
         state = IDLE;
      }
   }
   else {
      state = HIDRO_OFF;
   }
}

void hidro_off_func()
{
   hidro = OFF;
   clrwdt();
    // if the time is less than 30'
   if ((timer_func() - initial_time) < 9000)
    {
      if (check_button() == ON)
      {
         pompa = !pompa;
      }
   }
   else pompa = OFF;
    // if the time is more than 45'
   if ((timer_func() - initial_time) >= 13500)
    {
      state = IDLE;
    }
}
void display()
{
  if(hidro==ON && pompa == OFF)
  {
   Lcd_Out(1,3, "POMPA  OPRITA");
   Lcd_Out(2,2, "HIDROFOR  ACTIV");
   }
   else if(hidro==ON && pompa == ON)
   {
   Lcd_Out(1,3, "POMPA PORNITA");
   Lcd_Out(2,2, "HIDROFOR  ACTIV");
   }
   else if(hidro==OFF && pompa == ON)
   {
   Lcd_Out(1,3, "POMPA PORNITA");
   Lcd_Out(2,2, "HIDROFOR  ST-BY");
   }
   else if(hidro == OFF && pompa == OFF)
   {
   Lcd_Out(1,3, "POMPA  OPRITA");
   Lcd_Out(2,2, "HIDROFOR  OPRIT");
   }
}

void main()
 {
   hw_init();
   state = IDLE;
   clrwdt();
   while (1)
    {
      clrwdt();
      display();
      switch (state)
       {
         case IDLE:
            idle_func();
            break;
         case RUN:
            run_func();
            break;
         case HIDRO_OFF:
            hidro_off_func();
            break;
      }
   }
}

Cred ca am rezolvat prin mutarea functiei display inainte de functia hw...se pare ca este ok

 

Merge 10 secunde si apoi se perturba iarasi....

Editat de catalin004
Link spre comentariu

Colegu' problema persista....faza tare ca se perturba displayul si atunci cand nu dau START la pompa...adica pornesc montajul si atat...dupa10-15 sec incepe si se perturba

Link spre comentariu

Vezi ca ai greseli.

 

1. Functia de initializare hardware trebuie sa fie prima intotdeuana. Ca sunt mai multe sau una, sunt primele in program (main() ).

2. Nu pui punct si virgula in liniile cu #define

3. In intrerupere, ai un cnt++ in plus:

 if (pompa == ON)
      {
         cnt++;
         if (cnt == 5)
         {
             cnt = 0;
             LED = !LED;
         }
         else
         {
             cnt++;
         }
      }
      else
      {
         LED = OFF;
      }

ar trebui sa fie asa:

 if (pompa == ON)
 {
         if (cnt >= 5)
         {
             cnt = 0;
             LED = !LED;
         }
         else
         {
             cnt++;
         }
 }
 else
 {
         LED = OFF;
 }


LE: Vezi ca am schimbat in conditie din == in >=

 

Incearca sa numai rulezi functia display() decat daca s-a schimbat ceva.

Editat de mars01
Link spre comentariu

O masina de stari finite asa cum este implementat programul are avantajul ca este posibil (asa cum este cazul aici) sa nu ramai blocat intr-o stare ci doar testezi daca s-a schimbat ceva si atunci executi. Cu alte cuvinte se trece prin stari (case-uri) foarte repede ceea ce face ca bucla pricipala (while(1) ) sa fie foarte rapida.

 

Dar tu introduci in bucla pricipala o functie "grea" care mananca niste timp de procesare semnificativ, functia display() pe care o executi la fiecare trecere prin bucla.

Eu iti sugeram sa tii minte in unele variabile starea curenta a hydro si pompa si sa afisezi pe LCD doar cand se schimba starea acestora.

 

Ceva de genul: daca data trecuta pompa a fost OFF si acum este ON sau daca data trecuta a fost ON si acum este OFF atunci executa display, daca nu treci mai departe; la fel pentru hidro. Aceasta o faci in bucla while(1) iar inainte de intrarea in bucla, testezi odata si afisezi starea curenta. Aceata ca sa ai ceva pe LCD pana se schimba ceva in bucla while(1).

Editat de mars01
Link spre comentariu

Interesanta abordare...a mai incercat si un coleg sa modifice programul..o sa va postez luni ceea ce a facut el...pana atunci nu mai sunt la serviciu...dar tot se perturba...pana atunci ma dau batut si ma voi gandi la treaba asta cu display-ul...

Link spre comentariu

Am pus un delay de 10ms inainte de if pompa si vad ca nu mai sunt probleme....cauza nu o stiu...o sa postez si programul facut de colegul meu, insa ma baga in ceata rau de tot

 

 

 

void Interrupt()
{
// Timer1 one Interrupt rate is 100ms = 0.1s
if (TMR1IF_bit && TMR1ON_bit)
{
TMR1IF_bit = 0; // clear Timer1 interrupt flag
TMR1H = 0x3C; // Clear High byte
TMR1L = 0xB0; // Clear Low byte
timer_cnt++;
delay_ms(10);
if (pompa == ON)
{
cnt++;
if (cnt == 5)
{
cnt = 0;
LED = !LED;
}
else
{
cnt++;
}
}
else
{
LED = OFF;
}
}
}

Link spre comentariu

Nu se folosesc delay-uri in functia speciala apelata de intrerupere ... In cazul tau poate ca cele 10ms suplimentare cat se sta in intrerupere nu este o problema (pentru ca intreruperea are loc la fiecare 100ms) dar daca intreruperea era la 1ms ... Stateai numai in delay-uri fara ca sa mai executi ceva in bucla principala while(1).

In final, este reteta pentru probleme in programele tale pe viitor.

Link spre comentariu

Colegul a facut cum ati zis dvs...cu schimbarea starii doar atunci cand este nevoie...atasez programul...Ar mai fi o problema...as dori ca dupa ce se opreste pompa in mod automat, sa o pot porni imediat...nu sa astept in acelasi timp cu hidroforul pana se umple fantana....



#define pompa_dir TRISC.F1      //pompa pe iesirea RC1
#define cmdPompa PORTC.F1
#define hidro_dir TRISC.F0      //hidrofor pe iesirea RC0
#define cmdHidro PORTC.F0
#define LED_dir TRISC.F2        //indicator pompa pe iesirea RC2
#define LED PORTC.F2

#define buton_dir TRISC.F4      //butonul pe intrarea RC4
#define buton PORTC.F4

#define INPUT        1;
#define OUTPUT       0;

// enumeratie anonime pentru a salva diferite stari
enum
{
   OFF = 0,
   ON  = 1
};

#define stCMD_ON        1U
#define stCMD_OFF       0U

#define STD_ON        1U
#define STD_OFF       0U

//enumeratie pentru salvarea starilor din FSM
typedef enum States
{
   IDLE ,
   RUN,
   HIDRO_OFF
} state_t;

state_t state;                            // variable of type state_t
volatile unsigned long timer_cnt = 0;     // variable to store time in multiples of 0.1sec
unsigned long initial_time;               // var to store the initial time
unsigned volatile long cnt=0;
//LCD setare porturi iesire
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D4 at RB5_bit;
//Sfarsit LCD conect

// pini catre porturi
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D4_Direction at TRISB5_bit;
//terminare setare pentru lcd

/* variabile stare */
unsigned char stLed = STD_OFF;
unsigned char stPompa = STD_OFF;
unsigned char stHidro = STD_OFF;
unsigned char stPompaOld = STD_OFF;
unsigned char stHidroOld  = STD_OFF;

// clear the watchdog timer
void clrwdt()
{
   asm CLRWDT;
}

void display()
{
  if((STD_ON == stHidro) && (STD_OFF == stPompa ))
  {
   Lcd_Out(1,1, " POMPA  OPRITA  ");
   Lcd_Out(2,1, " HIDROFOR ACTIV ");
   }
   else if((STD_ON == stHidro) && (STD_ON == stPompa ))
   {
   Lcd_Out(1,1, "  POMPA PORNITA ");
   Lcd_Out(2,1, " HIDROFOR ACTIV ");
   }
   else if((STD_OFF == stHidro) && (STD_ON== stPompa ))
   {
   Lcd_Out(1,1, "  POMPA PORNITA ");
   Lcd_Out(2,1, " HIDROFOR ST-BY ");
   }
   else if((STD_OFF == stHidro) && (STD_OFF == stPompa ))
   {
   Lcd_Out(1,1, " POMPA  OPRITA  ");
   Lcd_Out(2,1, " HIDROFOR OPRIT ");
   }
}

void hw_init(void)
{
   clrwdt();
   // make sure that the oscillator is running at 8MHz cred ca doar cu oscilator intern
   //IRCF2_bit = 1;
   //IRCF1_bit = 1;
   //IRCF0_bit = 1;

   ADON_bit = 0x00;           // disable ADC
   ADCON1 = 0xFF;             // set all ADC pins as digital

   Lcd_Init();                // Initialize LCD
   Lcd_Cmd(_LCD_CLEAR);       // Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);  // Cursor off

   pompa_dir = OUTPUT;        //pompa ca iesire
   hidro_dir = OUTPUT;        //hidro ca iesire
   buton_dir = INPUT;         //buton ca intrare
   LED_dir = OUTPUT;          //led ca iesire

        stPompa = STD_OFF;                        //pompa stare initiala off
        cmdPompa = stCMD_OFF;

        stHidro = STD_ON;                //hidrofor stare initiala on
        cmdHidro = stCMD_ON;

   //initializare timer
   T1CKPS1_bit = 1;          //Pre-scaler 1:1
   T1CKPS0_bit = 0;
   TMR1ON_bit = 1;           // start Timer1
   TMR1IF_bit = 0;           // clear Timer1 interrupt flag
   TMR1H         = 0x3C;     // Clear High byte
   TMR1L         = 0xB0;     // Clear Low byte
   TMR1IE_bit  = 1;          // Disables Enables the TMR1 overflow interrupt
   PEIE_bit = 1;             // Enable Peripheral Interrupt
   GIE_bit = 1;              // start interrupts

  // SWDTEN_bit = 1;         // enable watchdog; the watchdog postscaler was set at 1:256 that means an reset interval of 4ms x 256 = 1024ms = 1.024sec

}

void Interrupt()
{
   // Timer1 one Interrupt rate is 100ms = 0.1s
   if (TMR1IF_bit && TMR1ON_bit)
   {
      TMR1IF_bit = 0;           // clear Timer1 interrupt flag
      TMR1H         = 0x3C;     // Clear High byte
      TMR1L         = 0xB0;     // Clear Low byte
      timer_cnt++;
   }
   else
   {
           /* do nothing */
   }

   if (STD_ON == stPompa)        //daca pompa este pornita
   {
         cnt++;
         if (cnt > 4 )
         {
             cnt = 0;
                         if(STD_ON == stLed)
                     {
                                 stLed = STD_OFF;
                 LED = stCMD_OFF;         //toogle led
                         }
                         else
                     {
                                 stLed = STD_ON;
                 LED = stCMD_ON;         //toogle led
                         }
         }
         else
         {
                        /* do nothing */
                 }
   }
   else
   {
                stLed = STD_ON;
        LED = stCMD_ON;         //toogle led
   }
}

// VERIFICARE STARI BUTON
unsigned char check_button (void)
 {
   static unsigned char anterior_buton = 1; // starea initiala a butonului este OFF
   clrwdt();
   if (buton == 1)
   {
   anterior_buton = 1;
   }
   if (buton == 0 && anterior_buton == 1)
   {
      delay_ms(200);
      if (buton == 0)
       {
         anterior_buton = 0;
         return 1;
      }
   }
   else return 0;
}

// initialize the timer_cnt variable
void init_timer()
{
   timer_cnt = 0;
}

// return the timer_cnt variable value
unsigned long timer_func ()
{
   volatile unsigned long temp;           // declared as volatile so it will not be optimized
   clrwdt();                              //clear watchdog
   GIE_bit = 0;                           // disable interrupts
   temp = timer_cnt;                      // copy the value of timer variable into the shadow variable named temp
   GIE_bit = 1;                           // enable interrupts

   return temp;                           // return the timer variable
}

void idle_func ()
 {

        cmdHidro = stCMD_ON;
        stHidro = STD_ON;

        stPompa = STD_OFF;
        cmdPompa = stCMD_OFF;

        clrwdt();
        if (check_button() == ON)
        {
                state = RUN;
                init_timer();
                initial_time = timer_func();
        }

}// idle_func

void run_func()
{
        unsigned long ulTmp;

        stPompa = STD_ON;
        cmdPompa = stCMD_ON;

   clrwdt();
   // if time is less than 15'
   ulTmp = timer_func();

   if(ulTmp>initial_time)
   {
           ulTmp -= initial_time;
   }
   else
   {
           ulTmp = 0U;
   }

   if (ulTmp < 4000)
   {
      if (check_button() == ON)
      {
         state = IDLE;
      }
   }
   else
   {
      state = HIDRO_OFF;
   }
}

void hidro_off_func()
{
        unsigned long ulTmp;

        cmdHidro = stCMD_OFF;
        stHidro = STD_OFF;

    ulTmp = timer_func();

   if(ulTmp>initial_time)
   {
           ulTmp -= initial_time;
   }
   else
   {
           ulTmp = 0U;
   }

   clrwdt();
    // if the time is less than 30'
        if (ulTmp < 9000)
    {
                if (check_button() == ON)
                {
                        if(STD_OFF == stPompa)
                        {
                                stPompa = STD_ON;
                                cmdPompa = stCMD_ON;
                        }
                        else
                        {
                                stPompa = STD_OFF;
                                cmdPompa = stCMD_OFF;
                        }
                }
                else
                {
                        /* do nothing*/
                }
   }
   else
   {
           stPompa = STD_OFF;
           cmdPompa = stCMD_OFF;
   }

    // if the time is more than 45'
   if (ulTmp >= 13500)
    {
      state = IDLE;
    }
}

void main()
 {

   hw_init();
   state = IDLE;
   clrwdt();
   
   stPompaOld = ~stPompa;
   stHidroOld =  ~stHidro;

   while (1)
    {
      clrwdt();
      if((stPompaOld != stPompa)|| (stHidroOld !=  stHidro))
      {
         stPompaOld = stPompa;
         stHidroOld =  stHidro;
         display();
      }
      
      switch (state)
       {
         case IDLE:
            idle_func();
            break;
         case RUN:
            run_func();
            break;
         case HIDRO_OFF:
            hidro_off_func();
            break;
      }
   }
}
Editat de catalin004
Link spre comentariu

Salut!

 

1. Subliniez, numai adauga punct si virgula la finalul liniilor cu #define.

 

Tu le pui asa:

#define INPUT        1;
#define OUTPUT       0;

dar liniile, asa cum ti le-am scris de fiecare data, trebuie sa fie asa:

#define INPUT        1
#define OUTPUT       0

E o practica proasta sa adaugi punct si virgula in liniile cu #define care poate duce la bug-uri in program care nu pot fi semnalate de compilator.

 

2. Compara si tu listing-urile postate de mine cu cele postate de tine. Care este mai usor de citit? Corecteaza formatarea codului: da stiu, trebuie sa stai sa stergi sau sa adaugi spatii ...

 

3. Ai spus ca vrei sa inveti. De ce nu faci tu modificarile necesare? Pentru aceasta evident trebuie sa intelegi structura programului.

Link spre comentariu

Ultimul program nu este facut de mine....cum am zis un coleg l-a editat....in al meu nu mai am , nu l-am mai postat ca sa nu incarc forumul;....revenind la program al dvs este mult mai usor de inteles...si simplu....

Editat de catalin004
Link spre comentariu

Uite la ce ma refeream eu:

/* 
   Project: Hydrophore - garden pump usage
   Microcontroller:  Microchip 16F73 running at 4MHz on external oscillator
   Programmer: mars01 on elforum.ro
   Date: 10 - Oct- 2017
*/

#define POMPA_DIR    TRISC1_bit     //pompa pe iesirea RC1
#define POMPA        RC1_bit

#define HIDRO_DIR    TRISC3_bit     //HIDROfor pe iesirea RC3
#define HIDRO        RC3_bit

#define LED_DIR      TRISC6_bit     //HIDROfor pe iesirea RC6
#define LED          RC6_bit

#define BUTON_DIR    TRISB0_bit     //BUTONul pe intrarea RB00
#define BUTON        RB0_bit

#define INPUT        1
#define OUTPUT       0

// enumeratie anonima pentru a salva diferite stari
enum{
   OFF = 0,
   ON  = 1
};

//enumeratie pentru salvarea starilor din FSM
typedef enum States{
   IDLE ,
   RUN,
   HIDRO_OFF
} state_t;

state_t state;                                // variable of type state_t
volatile unsigned long timer_cnt = 0;         // variable to store time in multiples of 0.1sec
unsigned long initial_time;                   // var to store the initial time
volatile unsigned char sec_timer_cnt = 0;     // variable to store time in multiples of 0.1sec for LED blink

// variables to store the current and old states of the pump and hidro
unsigned char hidro_state, old_hidro_state, pump_state, old_pump_state;

//LCD setare porturi iesire
sbit LCD_RS at RC4_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D7 at RB6_bit;
sbit LCD_D6 at RB5_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D4 at RB3_bit;
//Sfarsit LCD conect

// pini catre porturi
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB6_bit;
sbit LCD_D6_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D4_Direction at TRISB3_bit;
//terminare setare pentru lcd

// clear the watchdog timer
void clrwdt() {
   asm CLRWDT;
}

void hw_init(void)
{
   clrwdt();
   PSA_bit = 1;               // prescaler assigned to WDT
   
   // prescaler set at 1:64 which means that the watchdog will expire at 18ms x 64 = 1152ms ~ 1.1sec
   PS2_bit = 1;
   PS1_bit = 1;
   PS0_bit = 0;

   ADON_bit = 0x00;           // disable ADC
   ADCON1 = 0xFF;             // set all ADC pins as digital

   Lcd_Init();                // Initialize LCD
   Lcd_Cmd(_LCD_CLEAR);       // Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);  // Cursor off

   POMPA_DIR = OUTPUT;        //POMPA ca iesire
   HIDRO_DIR = OUTPUT;        //HIDRO ca iesire
   BUTON_DIR = INPUT;         //BUTON ca intrare

   LED_DIR = OUTPUT;

   pump_state = OFF;
   old_hidro_state = OFF;
   POMPA = OFF;                //POMPA stare initiala off
   hidro_state = OFF;
   old_hidro_state = OFF;
   HIDRO = OFF;                //HIDROfor stare initiala off

   // TIMER1: Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 100 ms
   T1CKPS1_bit = 0;          //Pre-scaler 1:1
   T1CKPS0_bit = 1;
   TMR1ON_bit = 1;           // start Timer1
   TMR1IF_bit = 0;           // clear Timer1 interrupt flag
   TMR1H         = 0x3C;     // Clear High byte
   TMR1L         = 0xB0;     // Clear Low byte
   TMR1IE_bit  = 1;          // Disables Enables the TMR1 overflow interrupt
   PEIE_bit = 1;             // Enable Peripheral Interrupt
   GIE_bit = 1;              // start interrupts

   Lcd_Out(1,3, "POMPA  OPRITA   ");
   Lcd_Out(2,2, "HIDROFOR  OPRIT ");
}

void Interrupt(){
   clrwdt();
   
   // Timer1 one Interrupt rate is 100ms = 0.1s
   if (TMR1IF_bit && TMR1ON_bit){
      TMR1IF_bit = 0;           // clear Timer1 interrupt flag
      TMR1H         = 0x3C;     // Clear High byte
      TMR1L         = 0xB0;     // Clear Low byte

      timer_cnt++;

      if (pump_state == ON){
        if (sec_timer_cnt >= 5){
           sec_timer_cnt = 0;
           LED = !LED;
        }
        else{
           sec_timer_cnt++;
        }
      }
      else{
         LED = OFF;
      }
   }
}

// VERIFICARE STARI BUTON
unsigned char check_button (void){
   static unsigned char anterior_BUTON = 1; // starea initiala a BUTONului este OFF
   clrwdt();
   if (BUTON == 1){
      anterior_BUTON = 1;
   }
   if (BUTON == 0 && anterior_BUTON == 1){
      delay_ms(200);
      if (BUTON == 0){
         anterior_BUTON = 0;
         return 1;
      }
   }
   else return 0;
}

// initialize the timer_cnt variable
void init_timer(){
   timer_cnt = 0;
}


// return the timer_cnt variable value
unsigned long timer_func (){
   volatile unsigned long temp;           // declared as volatile so it will not be optimized
   clrwdt();                              // clear watchdog
   GIE_bit = 0;                           // disable interrupts
   temp = timer_cnt;                      // copy the value of timer variable into the shadow variable named temp
   GIE_bit = 1;                           // enable interrupts

   return timer_cnt;                      // return the timer variable
}

void display(){
   clrwdt();

   if (pump_state == ON && old_pump_state == OFF){
      Lcd_Out(1,3, "POMPA PORNITA   ");
   }
   if (pump_state == OFF && old_pump_state == ON){
      Lcd_Out(1,3, "POMPA  OPRITA   ");
   }

   if (hidro_state == ON && old_hidro_state == OFF){
      Lcd_Out(2,2, "HIDROFOR  ACTIV ");
   }
   if (hidro_state == OFF && old_hidro_state == ON){
      if (pump_state == ON){
         Lcd_Out(2,2, "HIDROFOR  ST-BY ");
      }
      else{
         Lcd_Out(2,2, "HIDROFOR  OPRIT ");
      }
   }
}

void idle_func (){
   hidro_state = ON;
   HIDRO = hidro_state;
   
   // because we assign states we test and if different than the old state we update the LCD
   if (old_hidro_state != hidro_state){
      display();
      old_hidro_state = hidro_state;
   }

   pump_state = OFF;
   POMPA = pump_state;
   
   // because we assign states we test and if different than the old state we update the LCD
   if (old_pump_state != pump_state){
      display();
      old_pump_state = pump_state;
   }
   
   clrwdt();
   if (check_button() == ON){
      state = RUN;
      init_timer();
      initial_time = timer_func();
   }
}

void run_func(){
   pump_state = ON;
   POMPA = pump_state;
   
   // because we assign states we test and if different than the old state we update the LCD
   if (old_pump_state != pump_state){
      display();
      old_pump_state = pump_state;
   }
   
   clrwdt();
   // if time is less than 15'
   if ((timer_func() - initial_time) < 4000){
      if (check_button() == ON){
         state = IDLE;
      }
   }
   else{
      state = HIDRO_OFF;
   }
}

void HIDRO_off_func(){
   hidro_state = OFF;
   HIDRO = hidro_state;
   
   // because we assign states we test and if different than the old state we update the LCD
   if (old_hidro_state != hidro_state){
      display();
      old_hidro_state = hidro_state;
   }
   
   clrwdt();
    // if the time is less than 30'
   if ((timer_func() - initial_time) < 9000){
      if (check_button() == ON){
         pump_state = !pump_state;
         POMPA = pump_state;

         // because we assign states we test and if different than the old state we update the LCD
         if (old_pump_state != pump_state){
            display();
            old_pump_state = pump_state;
         }
      }
   }
   else{
      pump_state = OFF;
      POMPA = pump_state;
      
      // because we assign states we test and if different than the old state we update the LCD
      if (old_pump_state != pump_state){
         display();
         old_pump_state = pump_state;
      }
   }
    // if the time is more than 45'
   if ((timer_func() - initial_time) >= 13500){
      state = IDLE;
    }
}

void main(){
   hw_init();
   
   state = IDLE;
   clrwdt();

   while (1){
      clrwdt();
      display();

      switch (state){
         case IDLE:
            idle_func();
            break;
         case RUN:
            run_func();
            break;
         case HIDRO_OFF:
            HIDRO_off_func();
            break;
      }
   }
}

In ceea ce priveste situatia semnalata la postul #326 te las pe tine sa iti dai seama cum trebuie modificat programul.

 

O idee :) Creezi o noua stare in masina de stari, HIDRO_STAND-BY.

Editat de mars01
Link spre comentariu

Am inteles....maine sper sa vin cu solutia...pe al colegului n l-am edidat ca nu mi-a placut modul de lucru(cu toate ca este cerd mai la punct-gen ca stie fiecare stare)

 

maine o sa-l postez pe al meu....acum nu pot ca doar la serv il am pe laptop....

 

 

treaba cu stop nu vreau nici un detaliu...vreau sa muncesc...colegul meu m-a apostrofat ca i-am zis ca nu stiu ce ineamna ||..(sau)....chiar nu ma lovisem de el...am multe de invatat

 

PS:superba editarea...cred ca eu ma cam grabesc in general

Editat de catalin004
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