mars01 Postat Octombrie 2, 2017 Partajează Postat Octombrie 2, 2017 (editat) La pornire pompa este OFF. Deci delay-urile nu sunt active. Cand pompa devine ON atunci va fi introdus acest delay. Medicament: foloseste-te de timer-ul care este deja in program si creaza un delay non-blocking. Editat Octombrie 2, 2017 de mars01 Link spre comentariu
catalin004 Postat Octombrie 2, 2017 Partajează Postat Octombrie 2, 2017 Ok, o sa folosesc acelasi delay...insa nu stiu ce inseamna non-blocking...de aceea cer mereu exemple ca invat mult mai repede cand vad... Link spre comentariu
mars01 Postat Octombrie 2, 2017 Partajează Postat Octombrie 2, 2017 (editat) Cand esti in dubii cu privire la cum sa programezi ceva in C, da un search dupa cuvintele cheie adaugand dupa ele cuvantul cheie "Arduino". Sansele sunt foarte mari ca un Arduino-guy sa se fi izbit de problema si o solutie este deja disponibila. Gen asa. Solutia este ca sa introduci o variabila globala de tip LONG (cu atributul volatile in fata) care se incrementeaza in functia de intrerupere. Apoi privesti acea variabila ca si cum ar fi functia millis() in Arduino si procedezi similar ca aici. Editat Octombrie 2, 2017 de mars01 Link spre comentariu
catalin004 Postat Octombrie 2, 2017 Partajează Postat Octombrie 2, 2017 Ma bag la studii si incerc sa fac ceva.... Link spre comentariu
catalin004 Postat Octombrie 4, 2017 Partajează Postat Octombrie 4, 2017 Am incercat sa folosesc cu timer 0...insa nu mai imi da start la pompa #define pompa_dir TRISC.F1 //pompa pe iesirea RC1 #define pompa PORTC.F1 #define hidro_dir TRISC.F3 //hidrofor pe iesirea RC3 #define hidro PORTC.F3 #define LED_dir TRISC.F6 //hidrofor pe iesirea RC3 #define LED PORTC.F6 #define buton_dir TRISB.F0 //butonul pe intrarea RB00 #define buton PORTB.F0 #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 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(); // 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 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++; } } // 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; } void InitTimer0() //initializare timer 0 { OPTION_REG = 0x81; TMR0 = 6; INTCON = 0xA0; } void Interrupt0() { if (TMR0IF_bit && pompa==ON) { TMR0IF_bit = 0; TMR0 = 6; //Enter your code here if (cnt >= 500) { cnt=0; LED=!LED; } else { cnt++ ; } } } void bec_delay() { LED_dir=OUTPUT; InitTimer0(); } // 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 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(); bec_delay(); switch (state) { case IDLE: idle_func(); break; case RUN: run_func(); break; case HIDRO_OFF: hidro_off_func(); break; } } } Link spre comentariu
mars01 Postat Octombrie 4, 2017 Partajează Postat Octombrie 4, 2017 (editat) Ma grabesc asa ca scriu rapid: 1. Exista o singura functie apelata de intreruperi. Cuvantul cheie pentru aceasta in mikroC este interrupt() La PIC18 sunt doua (prioritati) dar e alta mancare de peste, vorba vine. 2. Cand ai mai multe timere active, cum este cazul la tine, testezi flag-urile lor in functia unica interrupt() 3. Initializarea timerelor este bine sa o pui in aceasi functie, pentru ca sunt unii biti care afecteaza pe toti. In cazul de fata in hw_init(). 4. Incearca sa intelegi ce ai pus in functia InitTimer0(). Te folosesti de registri dar nu stii ce faci acolo. Foloseste alias-urile pentru biti asa cum am facut eu in hw_init() pentru Timer-ul 1. Editat Octombrie 4, 2017 de mars01 Link spre comentariu
catalin004 Postat Octombrie 4, 2017 Partajează Postat Octombrie 4, 2017 (editat) Pffff...imi ine sa dau cu calculatorul de pamant...ajung tot de unde am plecat...nu stiu nimic din timere....nu am nici unde sa studiez...ma mai duc peste un coleg sa vad ce zice...am cautat si pe gogu programe cu timere, dar nu prea sunt...ma refer asa detaliate ma pot folosi din aceste exemple? https://forum.mikroe.com/viewtopic.php?f=88&t=58169&hilit=timer0&start=15 Editat Octombrie 4, 2017 de catalin004 Link spre comentariu
mars01 Postat Octombrie 4, 2017 Partajează Postat Octombrie 4, 2017 (editat) Gasesti ajutor aici. LE: Programul, probabil, ar trebui sa arate cam asa (se putea si mai bine dar acum nu am chef de scris mai mult - vin de la o inmormantare ...) #define pompa_dir TRISC1_bit //pompa pe iesirea RC1 #define pompa PORTC1_bit #define hidro_dir TRISC3_bit //hidrofor pe iesirea RC3 #define hidro PORTC3_bit #define LED_dir TRISC6_bit //hidrofor pe iesirea RC3 #define LED PORTC6_bit #define buton_dir TRISB0_bit //butonul pe intrarea RB00 #define buton PORTB0_bit #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 volatile unsigned char sec_timer_cnt = 0; // variable to store time in multiples of 0.1sec for LED blink //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(); // 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) { 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 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; } } } Editat Octombrie 4, 2017 de mars01 Link spre comentariu
catalin004 Postat Octombrie 4, 2017 Partajează Postat Octombrie 4, 2017 (editat) Condoleante si multumiri ...Sanatate sincer ma chiunuiam si eu , dar incepusem sa vad cum sta treaba...insa eu facusem functie, dar cred ca iar aparea delay-ul...atasez mai jos inecrcarea mea....sincer ma bucur ca depistasem ce vreti sa imi transmiteti void bec() { LED_dir = OUTPUT; if ( pompa==ON) { cnt++; if(cnt=200); { LED=!LED; cnt=0; } } else { LED=OFF; } } Editat Octombrie 4, 2017 de catalin004 Link spre comentariu
catalin004 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 Nu merge...am incercat mai multe modificari prin interupt dar imi bruiaza imaginea displayului, imi face mai multe probleme... este ok.mai trebuia un sec_timer_cnt++; inainte de if (sec_timer_cnt == 5) { sec_timer_cnt = 0; LED = !LED; } else { sec_timer_cnt++; }}else Tot bruiaza display-ul...o ia razna...fara el nu face figuri Link spre comentariu
mars01 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 Ce ai conectat pe RC6, pinul LED-ului? Direct un LED? Sau grila la un tranzistor MOSFET? Link spre comentariu
catalin004 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 (editat) Am un tranzistor NPN, 2N2222, Emitor la masa, 10k din uC in Baza, si led-ul legat intre Colector si +12V...posibil sa intre in oscilatii si sa perturbe? Editat Octombrie 5, 2017 de catalin004 Link spre comentariu
mars01 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 Ma gandeam la o problema de tipul Read - Write - Modify. Incearca sa ai toti pinii LCD-ului legati la un singur port, spre exemplu PORTB. Link spre comentariu
catalin004 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 Asa ii am....toti pe B...dar cred ca este din soft, face si fara led cuplat...daca scot acea particica din program nu mai face.... Link spre comentariu
mars01 Postat Octombrie 5, 2017 Partajează Postat Octombrie 5, 2017 (editat) Nu stiu ce sa iti spun decat ca dpdv al secventei introduse in functia interrupt() din codul postat de mine mai sus, nu are cum sa apara problema pe care tu o reclami. Inreruperea apare foarte lent, o data la 100ms, nu face dacat sa incremementeze o variabila pe 8 biti, si odata la 5 iteratii face flip la pinul unde este pus LED-ul. Vezi configurarile de registri. Editat Octombrie 5, 2017 de mars01 Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum