danpin Postat Martie 10, 2017 Partajează Postat Martie 10, 2017 (editat) Salut, De parca nu ar fi fost destule si aici pe forum sau aiurea pe net, m-am apucat si eu de un soft pt. o cutie de expunere... Nu sunt specialist, am mai tras cu ochiul pe ici pe colo... si cam asta mi-a iesit. In linii mari functionarea ar fi astfel: - Butoanele MIn si Sec modifica timpul de expunere, in sens crescator - Min si Sec apasate simultan reseteaza timpul setat - Start si Min apasate simultan seteaza ultimul timp memorat - La prima apasare a butonului Start perneste timerul, la urmatoarea apasare se opreste - La deschiderea capacului timerul se opreste, pt. reluare trebuie inchis capacul si apasata tasta Start - Pe timpul temporizarii apasarea butoanelor Min sau Sec nu are efect - In timpul pauzei se poate modifica timpul, Set Time creste cu valoarea adaugata Nu am momentan posibilitatea sa-l probez fizic intr-un montaj, in simulator pare ca merge, cu urmatoarele probleme: - uneori ultima secunda din countdown ramane 1 in loc de 0 - uneori butonul Start trebuie sa-l apas de mai multe ori ca sa ia comanda Vorbesc de ce se intampla in simulare. Nu am mai lucrat pana acum cu functia "Button" din Mikroc, posibil sa trebuiasca sa mai ajustez timpii, am sa vad cum se comporta cand am sa-l realizez fizic. Cine are idei de imbunatatire sau sesizeaza greseli este rugat sa posteze. // Countdown Timer using PIC16F690 microcontroller #define XTAL_FREQUENCY 6000000 #define TIMER1_FREQUENCY (XTAL_FREQUENCY / 4) // 1 clock tick = 1 instr. cycle = crystal frequency / 4 //Lid #define open 0 #define close 1 // Lcd pinout settings sbit LCD_RS at RC2_bit; sbit LCD_EN at RC1_bit; sbit LCD_D7 at RA0_bit; sbit LCD_D6 at RA1_bit; sbit LCD_D5 at RA2_bit; sbit LCD_D4 at RC0_bit; // Pin direction sbit LCD_RS_Direction at TRISC2_bit; sbit LCD_EN_Direction at TRISC1_bit; sbit LCD_D7_Direction at TRISA0_bit; sbit LCD_D6_Direction at TRISA1_bit; sbit LCD_D5_Direction at TRISA2_bit; sbit LCD_D4_Direction at TRISC0_bit; // End LCD module connections char msg[17]; // declare array set to max size required plus 1 [for terminator] for copying into // copy const to ram string char * CopyConst2Ram(char * dest, const char * src) { char * d ; d = dest; for(;*dest++ = *src++;) ; return d; } // Intro Mesages const char LCD_txt1[] = "Hello Man!"; const char LCD_txt2[] = "How are you?"; const char LCD_txt3[] = "UV Box Timer"; const char LCD_txt4[] = "00 Sec to 99 Min"; const char LCD_txt5[] = " SET TIME LEFT"; const char LCD_txt6[] = "00:00 00:00"; const char LCD_txt7[] = " The End "; const char LCD_txt8[] = " Lid Open "; const char LCD_txt9[] = "STOP"; const char LCD_txt10[]= " "; // define Buzzer, LED's and Relay pins. sbit LED_YELLOW at RC5_bit; sbit LED_GREEN at RB7_bit; sbit LED_RED at RC7_bit; sbit RELAY at RC3_bit; sbit LID at RC6_bit; // Variables char b; bit oldstate; // Old state flag //bit Lid; long int Ticker = TIMER1_FREQUENCY; int Seconds=0; int SetSecond=0, SetMinut=0, LeftSecond=0, LeftMinut=0; int readsec=0, readmin=0; int memsec, memmin; int x=0; void Tone1() {Sound_Play(659, 50);} // Frequency = 659Hz, duration = 250ms void Tone2() {Sound_Play(698, 300);} // Frequency = 698Hz, duration = 250ms void show_intro(void) // Initial splash screen { char i; INTCON.GIE = 0; Tone1(); delay_ms (100); Lcd_Out(1,4,CopyConst2Ram(msg,LCD_txt1)); // Write text "Hello Dan!" in first row delay_ms (500); Tone1(); Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt2)); // Write text "How are you?" in second row delay_ms (1500); Lcd_Cmd(_LCD_CLEAR); Tone1(); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt3)); // Write text "UV Box Timer" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt4)); // Write text "0 Sec. to 99 Min." in second row delay_ms(2000); } // =Process Zero Drift Real Time Clock Information=- // Most algorithms configure the timer to generate an interrupt every 100ms, and // then count the number of interrupts. The problem in that approach is that most // clock frequencies can't be divided by 256 and you don't get an exact 100ms. // The small errors will add up to an error of several seconds a day. // The algorithm presented here is exact in the long run because it doesn't // count the number of interrupts but counts the number of clock cycles. // /* void Interrupt() { if (PIR1.TMR1IF ==1) { Ticker -= 65536; // Decrement ticker by clocks per interrupt if (Ticker < 65536 ) // If second has expired { Ticker += TIMER1_FREQUENCY; // Increment ticker by clocks per second seconds++; // Increment number of seconds x++; if (b == 0) { if (LeftSecond == 0) { readsec = 60; readmin--; } readsec=readsec--; LeftSecond=readsec; LeftMinut=readmin; } } } PIR1.TMR1IF = 0x00; // Timer1 interrupt Flag cleared } void LCD_2nd_row() { Lcd_Chr(2, 1, SetMinut/10 + '0'); Lcd_Chr_CP(SetMinut%10 + '0'); Lcd_Chr(2, 3, ':'); Lcd_Chr(2, 4, SetSecond/10 + '0'); Lcd_Chr_CP(SetSecond%10 + '0'); Lcd_Chr(2, 12, LeftMinut/10 + '0'); Lcd_Chr_CP(LeftMinut%10 + '0'); Lcd_Chr(2, 14, ':'); Lcd_Chr(2, 15, LeftSecond/10 + '0'); Lcd_Chr_CP(LeftSecond%10 + '0'); } void LIDOPEN() { RELAY = 0; LED_RED = 0; LED_GREEN = 1; INTCON.GIE = 0; // Disables all interrupts Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt8)); // Write text " Lid Open " in first row if (b > 0) // If timer is not running Lcd_Out(2,7,CopyConst2Ram(msg,LCD_txt9)); // Write text "STOP" else Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt5)); // Write text " SET TIME LEFT" in first row LCD_2nd_row(); // Execute function "void LCD_2nd_row()" } void START() { if (LID == open) // Open == 0 { LIDOPEN(); // Execute function "void LIDOPEN()" } if (LID == close) // Close == 1 { RELAY = 1; // Switch ON relay LED_RED = 1; // Switch ON RED LED LED_GREEN = 0; // Switch OFF GREEN LED INTCON.GIE = 1; // Enables all unmasked interrupts //b = 1; Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt5)); // Write text "SET TIME LEFT" in first row LCD_2nd_row(); // Execute function "void LCD_2nd_row()" Lcd_Out(2,6,CopyConst2Ram(msg,LCD_txt10)); // Write text " " in second row } } void PAUSE() { RELAY = 0; // Switch OFF relay LED_RED = 0; // Switch OFF RED LED LED_GREEN = 1; // Switch ON GREEN LED INTCON.GIE = 0; // Disables all interrupts if (LID == open) { LIDOPEN(); // Execute function "void LIDOPEN()" } else Lcd_Out(2,7,CopyConst2Ram(msg,LCD_txt9)); // Write text "STOP" in second row LCD_2nd_row(); // Execute function "void LCD_2nd_row()" } void main() { // registers and ports configuration OPTION_REG = 0b10000000; //Option register INTCON = 0b11000000; // Interrupt Control Register CM1CON0 = 0b00000000; // Comparator 1 Control Register CM2CON0 = 0b00000000; // Comparator 2 Control Register ANSEL = 0; // Analog select Register ANSELH = 0; // Analog select High Register PIE1.TMR1IE = 0x01; // Timer1 interrupt enabled T1CON = 0b00000101; // Timer1 Control Register TMR1L = 0x00; // Reset Timer1 lower 8 bits TMR1H = 0x00; // Reset Timer1 upper 8 bits TRISA = 0b00111000; // TRISA Register TRISB = 0b01110000; // TRISB Register TRISC = 0b01000000; // TRISC Register PORTA = 0; // PORTA Register PORTB = 0; // PORTB Register PORTC = 0; // PORTC Register Sound_Init(&PORTC, 4); // Configures the MCU pin RC4 for sound generation Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off show_intro(); // Show splash screen Tone1(); Lcd_Cmd(_LCD_CLEAR); // Clear LCD Delay_ms(100); // 100 milliseconds delay Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt5)); // Write text "SET TIME LEFT" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt6)); // Write text "00:00 00:00" in second row b=1; LED_RED = 0; // LED RED off LED_GREEN = 0; // LED GREEN off RELAY = 0; // RELAY off readsec=0; readmin=0; delay_ms(100); EEPROM_Write(0x10, 0); delay_ms(100); EEPROM_Write(0x20, 0); delay_ms(100); while(1) { if (Button(&PORTB, 4, 100, 1)) // START Button Detect logical one { switch(b) { case 0: START(); break; case 1: RELAY = 0; LED_RED = 0; LED_GREEN = 1; break; case 2: PAUSE(); break; case 3: INTCON.GIE = 0; default: b = 1; // Update flag } oldstate = 1; } if (oldstate && Button(&PORTB, 4, 100, 0)) // START Button Detect one-to-zero transition { b = 0; // At first press counter run oldstate = 0; // Update flag Tone1(); // Beep on if the button is pressed } if ((oldstate == 0) && (Button(&PORTB, 4, 100, 0))) // START Button Detect one-to-zero transition { b = 2; // At second press counter paused // At second press counter paused readsec = EEPROM_Read(0x10); readmin = EEPROM_Read(0x20); Tone1(); // Beep on if the button is pressed } if (Button(&PORTB, 5, 20, 1)) // MIN Button Detect logical one { oldstate = 1; // Update flag } if (oldstate && Button(&PORTB, 5, 20, 0)) // MIN Button Detect one-to-zero transition { oldstate = 0; // Update flag if (b == 0) { SetMinut = SetMinut; // Can't increment minutes if timer is running LeftMinut = LeftMinut; } else { if ((b != 0) && (Button(&PORTB, 5, 20, 0)) && (Button(&PORTB, 6, 20, 0))) { SetMinut = 0; // If timer not running and Min+Sec are pressed LeftMinut = 0; // then reset the set time } else { SetMinut++; // If counter not running, increment Set ans Left minuts LeftMinut++; } } if (SetMinut>99) SetMinut=0; if (LeftMinut>99) LeftMinut=0; Lcd_Chr(2, 1, SetMinut/10 + '0'); Lcd_Chr_CP(SetMinut%10 + '0'); Lcd_Chr(2, 12, LeftMinut/10 + '0'); Lcd_Chr_CP(LeftMinut%10 + '0'); if (b != 0) Tone1(); } EEPROM_Write(0x20, LeftMinut); if (Button(&PORTB, 6, 50, 1)) // SEC Button Detect logical one { oldstate = 1; // Update flag } if (oldstate && Button(&PORTB, 6, 20, 0)) // SEC Button Detect one-to-zero transition { oldstate = 0; // Update flag if (b == 0) { SetSecond = SetSecond; // Can't increment seconds if counter is running LeftSecond = LeftSecond; } else { if ((b != 0) && (Button(&PORTB, 5, 20, 0)) && (Button(&PORTB, 6, 20, 0))) { SetSecond = 0; // If counter not running and Min+Sec are pressed LeftSecond = 0; // then reset Set ans Left seconds } else { SetSecond++; // If counter not running, increment LeftSecond++; // Set ans Left seconds } } if (SetSecond>59) { SetSecond = 0; if ((b != 0) && (Button(&PORTB, 5, 20, 0)) && (Button(&PORTB, 6, 20, 0))) // If counter not running and min+sec button are press SetMinut = 0; else SetMinut++; // Increment SetMinut if (SetMinut>99) SetMinut = 0; } if (LeftSecond>59) { LeftSecond = 0; if ((b != 0) && (Button(&PORTB, 5, 20, 0)) && (Button(&PORTB, 6, 20, 0))) // If counter not running and min+sec button are press LeftMinut = 0; else LeftMinut++; // Increment LeftMinut if (LeftMinut>99) LeftMinut = 0; } LCD_2nd_row(); if (b != 0) // If counter not running play Tone1 Tone1(); } EEPROM_Write(0x10, LeftSecond); if ((b != 0) && (Button(&PORTB, 5, 1000, 0)) && (Button(&PORTB, 6, 1000, 0))) // MIN + SEC Button { SetMinut = 0; SetSecond = 0; LeftSecond = 0; LeftMinut = 0; LCD_2nd_row(); oldstate = 0; // Update flag } if ((readsec == 0) && (readmin == 0) && (b==0) && ((SetMinut || SetSecond) >= 0)) b = 2; if (LID == close) // LID Switch Detect logical one { //Lid = close; // Close == 1 if (((SetMinut || SetSecond) > 0) && (LeftSecond == 0 && LeftMinut == 0)) Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt7)); // Write text " The End " else Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt5)); // Write text "SET TIME LEFT" in first row LED_YELLOW = 1; } else { LED_YELLOW = 0; LIDOPEN(); b = 2; // b=2=PAUSE } if ((b == 0) && (LeftMinut == 0) && (LeftSecond <=5) && (LeftSecond >=0)) { LED_RED = 0; Tone1(); // Beep last 5 seconds LED_RED = 1; //Tone2(); } if (((SetMinut || SetSecond) > 0) && (LeftSecond == 0) && (LeftMinut == 0)) // When time elapsed { b = 1; // RELAY=0, LED_RED = 0, LED_GREEN=1 if (LID == close) // If Lid closed Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt7)); // Write text " The End " else // If Lid opened LIDOPEN(); // Execute function "void LIDOPEN()" //LCD_2nd_row(); Delay_ms(30); EEPROM_Write(0x30, SetMinut); // Write in the memory the last set time Delay_ms(30); EEPROM_Write(0x40, SetSecond); } if ((b != 0) && (Button(&PORTB, 4, 1000, 0)) && (Button(&PORTB, 5, 1000, 0))) // START + MIN Button { LeftMinut = SetMinut = EEPROM_Read(0x30); // Read from memory the last time set LeftSecond = SetSecond = EEPROM_Read(0x40); Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt5)); // Write text " SET TIME LEFT" LCD_2nd_row(); b = 2; // Update flag (b=2=PAUSE) } } } UV box timer PIC16F690.Rev00.rar Editat Martie 10, 2017 de danpin Link spre comentariu
Blacksmith Postat Martie 10, 2017 Partajează Postat Martie 10, 2017 Si eu am in plan sa fac asa ceva, deci voi avea de unde sa ma inspir. Mersi ! Link spre comentariu
kinderu56 Postat Martie 10, 2017 Partajează Postat Martie 10, 2017 (editat) http://laex.su/upload/UV_timer.zip asta cum vi se pare? Editat Martie 10, 2017 de kinderu56 Link spre comentariu
danpin Postat Martie 11, 2017 Autor Partajează Postat Martie 11, 2017 (editat) Domnule kinderu56, titlul topicului este: "Timer cutie expunere UV cu PIC16F690 si LCD (0 sec - 99 min)" si este postat la sectiunea PIC. Rog un moderator sa stearga postarile offtopic, multumesc! Editat Martie 11, 2017 de danpin Link spre comentariu
kinderu56 Postat Martie 11, 2017 Partajează Postat Martie 11, 2017 scuze nu am fost atent 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