mars01 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 (editat) Daca folosesti 16F73 (uC-ul nu pare sa aiba osc intern - nu am sapat in datasheet dar e vechi contorller-ul asa ca nu cred) cu un cuartz extern de 16MHz atunci pentru un firing rate de 1ms se configureaza Timer-ul 0 asa (am folosit aplicatia Timer Calculator): //Timer0 //Prescaler 1:16; TMR0 Preload = 6; Actual Interrupt Time : 1 ms //Place/Copy this part in declaration section void InitTimer0(){ OPTION_REG = 0x83; TMR0 = 6; INTCON = 0xA0; } void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 6; //Enter your code here } } Tradus ar fi asa: OPTION_REG = 0x83; Ce ne intereseaza este ca aici se face LOW bitul T0CS, ceea ce inseamna ca incrementarea Timer0 se face pe internal instruction clock (adica la Microchip este Fosc/4 adica 16MHz/4 = 4MHz). Tot aici, se fac btii PSA2 = 0, PSA1 = 1, PSA0 = 1 adica se seteaza un prescaler de 1:16 adica Timer0 merge la 4MHz / 16 = 250KHz adica fiecare tick incrementare Timer0 are o valoare de 4 microsecunde. Fiindca se face: TMR0 = 6; inseamna ca timerul pleaca mereu de la 6 si numara astfel pana la 255 cand apare intreruperea. Adica numara de 250 ori pana are intrerupere adica o intrerupere apare la 250 x 4microsecunde = 1000 microsecunde = 1ms. Editat Septembrie 20, 2017 de mars01 Link spre comentariu
catalin004 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 (editat) Folosesc quartz extern de 4Mhz..l-am luat de pe placi de tv.... deci inseamna ca se modifica iarasi.... PS:eu timer 0 il am pe RA4, trebuie sa leg ceva fizic de acel pin? PS2:se mai poate folosi pinul daca timerul este pe el? Editat Septembrie 20, 2017 de catalin004 Link spre comentariu
mars01 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 Cu un cuartz de 4MHz setarile pentru 16F73 (TIMER0) sunt asa: //Timer0 //Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms //Place/Copy this part in declaration section void InitTimer0(){ OPTION_REG = 0x81; TMR0 = 6; INTCON = 0xA0; } void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 6; //Enter your code here } } Te-am avertizat ca de la uC la uC se schimba lucrurile (pozitii biti in registri, registri intregi etc). Iar functionarea timer-elor depinde de frecventa la care lucreaza uC. Implicit configurarea acestora. Link spre comentariu
catalin004 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 Am inteles si am vazut calculatorul...foarte interesant...iti da functia direct..... am mai postat 2 intrebari la postul anterior...astept raspuns stima Link spre comentariu
mars01 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 (editat) PS:eu timer 0 il am pe RA4, trebuie sa leg ceva fizic de acel pin? PS2:se mai poate folosi pinul daca timerul este pe el? Citeste si tu datasheet-ul (in special sectiunea Timer0, dar tot ce tine de configurare; nu exista un "quick fix"). Scrie clar ca incrememntarea Timer0 se face ori pe instruction clock intern ori pe un clock extern primit pe RA4. Din moment ce se foloseste clock-ul intern, pinul RA4 este liber sa faca ce vrei tu. Configurarea se face cum am scris mai sus, ma citez: Ce ne intereseaza este ca aici se face LOW bitul T0CS, ceea ce inseamna ca incrementarea Timer0 se face pe internal instruction clock (adica la Microchip este Fosc/4 adica 16MHz/4 = 4MHz). PS: Mi-era clar ca astepti raspuns, doar erau intrebari si am raspuns in postul curent. Editat Septembrie 20, 2017 de mars01 Link spre comentariu
catalin004 Postat Septembrie 20, 2017 Partajează Postat Septembrie 20, 2017 MERGEEEEEEEEEEEEEEEEEE!!!!!!!!!!!!!!!!!!!! Link spre comentariu
catalin004 Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 Neatza....se poate folosi acelasi timer pentru mai multe treburi/leduri/programari intrari/iesiri? De exemplu o alta iesire sa actioneze la 300ms... Link spre comentariu
catalin004 Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 (editat) Vreau si eu cateva explicatii aici daca se poate...ma refer la diferenta dintre primele 2 randuri.... //init timer T1CKPS1_bit = 1; T1CKPS0_bit = 0; TMR1ON_bit = 1; // start Timer1 TMR1IF_bit = 0; // clear Timer1 interrupt flag TMR1H = 0x3C; TMR1L = 0xB0; TMR1IE_bit = 1; PEIE_bit = 1; 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 Editat Septembrie 21, 2017 de catalin004 Link spre comentariu
Elison Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 Bitii 5 (T1CKPS1) si 4 (T1CKPS0), din registrul de control al timerului 1, determina valoarea presclaerului. In cazul PIC16F73, in functie de ce se doreste, se pot alege urmatoarele valori: T1CKPS1 T1CKPS0 Prescale value 1 1 1:8 1 0 1:4 0 1 1:2 0 0 1:1 Link spre comentariu
catalin004 Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 Deci la aceste uC trebuie studiat in detaliu PDF-ul...acum revin la intrebarea precedenta se poate folosi acelasi timer in acelasi timp pentru alte iesiri? Multumesc Link spre comentariu
mars01 Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 Deci la aceste uC trebuie studiat in detaliu PDF-ul...acum revin la intrebarea precedenta se poate folosi acelasi timer in acelasi timp pentru alte iesiri? Multumesc Da, se poate. Link spre comentariu
catalin004 Postat Septembrie 21, 2017 Partajează Postat Septembrie 21, 2017 Cand aveti timp va rog sa modificati programul cu Led-ul , cu inca o iesire...de ex la 300ms....cand aveti timp doar...pe cel precedent l-am cam inteles, dar nu stiu cum sa le dau la fiecare comanda.... Link spre comentariu
catalin004 Postat Septembrie 28, 2017 Partajează Postat Septembrie 28, 2017 Salutare...am schimbat cele necesare prin program si l-am pus in aplicatie...am creat si o functie de afisare pe display cu functiile, ma gandeam sa fac un SHIFT_LEFT pe al doilea rand , insa nu stiu daca merge pe un singur rand , am facut teste insa merge, dar pe tot ecranul... O alta problema este ca nu stiu ce sa modific la timer sa fie in acelasi timp cu procesorul meu...am micsorat timpul in program doar pentru teste( ca sa nu astept atat timp sa vad cum lucreaza). Inca o problema este ca in momentul in care ambele utilaje se opresc, pompa nu o mai pot porni, as fi vrut sa mai mearga aceasta activitate, intrucat dupa oprirea ei automata as fi stiut ca nu mai este apa, si de exemplu as dori apa de baut, sa o pot porni, adica functia RUN cred ca ar fi repornita dupa ce ambele sunt OFF. - momentan asta o putem lasa ultima data , nu ma intereseqaza in mod deosebit... Atasez programul meu modificat... #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 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 //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 Lcd_Out(1,3, "POMPA OPRITA"); hidro = ON; //hidrofor stare initiala on Lcd_Out(2,2, "HIDROFOR PORNIT"); //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; TMR1H = 0x3C; TMR1L = 0xB0; 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; } // 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; // Lcd_Out(1,3, "POMPA PORNITA"); clrwdt(); if (check_button() == ON) { state = RUN; init_timer(); initial_time = timer_func(); } else { //Lcd_Out(1,3, "POMPA OPRITA"); } } void run_func() { pompa = ON; clrwdt(); // if time is less than 15' if ((timer_func() - initial_time) < 90) { if (check_button() == ON) { state = IDLE; } } else { state = HIDRO_OFF; // Lcd_Out(2,2, "HIDROFOR OPRIT"); } } void hidro_off_func() { hidro = OFF; clrwdt(); // if the time is less than 30' if ((timer_func() - initial_time) < 180) { if (check_button() == ON) { pompa = !pompa; } } else pompa = OFF; //Lcd_Out(1,3, "POMPA OPRITA"); // if the time is more than 45' if ((timer_func() - initial_time) >= 270) { state = IDLE; // Lcd_Out(1,3, "POMPA OPRITA"); // Lcd_Out(2,2, "HIDROFOR PORNIT"); } } void display() { if(hidro==ON && pompa == OFF) { Lcd_Out(1,3, "POMPA OPRITA"); Lcd_Out(2,2, "HIDROFOR PORNIT"); } else if(hidro==ON && pompa == ON) { Lcd_Out(1,3, "POMPA PORNITA"); Lcd_Out(2,2, "HIDROFOR PORNIT"); } 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_Cmd(_LCD_SHIFT_LEFT); Lcd_Out(2,2, "LIPSA APA"); } } 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; } } } Link spre comentariu
catalin004 Postat Septembrie 29, 2017 Partajează Postat Septembrie 29, 2017 Am modificat timerul cu cel din calculatorul mikcroC, PIC16, 4Mhz, 1 Interrupt, timer 1...dar parca nu face 15 minute.... Am mai bagat si un led pe RUN, care la pupitru sa imi arate ca am pompa prnita, un fel de avertizare... #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 //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 = 0x01; // start Timer1 TMR1IF_bit = 0; // clear Timer1 interrupt flag TMR1H = 0xFC; // Clear High byte TMR1L = 0x18; // 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; TMR1H = 0xFC; TMR1L = 0x18; 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; } // 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; // Lcd_Out(1,3, "POMPA PORNITA"); 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) < 9000) { 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) < 18000) { if (check_button() == ON) { pompa = !pompa; } } else pompa = OFF; // if the time is more than 45' if ((timer_func() - initial_time) >= 27000) { state = IDLE; } } void display() { if(hidro==ON && pompa == OFF) { Lcd_Out(1,3, "POMPA OPRITA"); Lcd_Out(2,2, "HIDROFOR PORNIT"); } else if(hidro==ON && pompa == ON) { Lcd_Out(1,3, "POMPA PORNITA"); Lcd_Out(2,2, "HIDROFOR PORNIT"); } 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 bec() { LED_dir = OUTPUT; if ( pompa==ON) { LED=ON; delay_ms(200); LED=OFF; delay_ms(200); LED=ON; delay_ms(200); LED=OFF; delay_ms(1000); } else { LED=OFF; } } void main() { hw_init(); state = IDLE; clrwdt(); while (1) { clrwdt(); display(); bec(); switch (state) { case IDLE: idle_func(); break; case RUN: run_func(); break; case HIDRO_OFF: hidro_off_func(); break; } } } Scuze acum am vazut ca s-a calculat la 100ms intreruperea, eu calculasem la 1ms...merge perfect.... Link spre comentariu
catalin004 Postat Octombrie 2, 2017 Partajează Postat Octombrie 2, 2017 void bec() { LED_dir = OUTPUT; if ( pompa==ON) { LED=ON; delay_ms(200); LED=OFF; delay_ms(200); LED=ON; delay_ms(200); LED=OFF; delay_ms(1000); } else { LED=OFF; } } De ce imi baga acest delay total(1600ms) cand incerc sa opresc pompa?la pornire imi porneste instant.... 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