/*============================ d:\pic\2016\timeri\timeri1.c TIMER 0-30min Project: Customer: -- File: timeri.c, lcd.c date 9.09.2016 Name: Pekka Ritamaki,Probyte, Tampere Finland (c) 2016 software : CCS/PCH compiler v5.08 Hardware : Keno.pcb Current: 6V 14 mA, 5V 9mA CPU : PIC18F2331-I/SO Clock source internal 8MHz Start button RB.7, Mode button RB.6 power 6V battery without regulator Function Start button gives electricty to transistor Q4 ja Q2 at start read potentiometer P1 and full scale gives 30min time the mode button can set +/- seconds, when pushin constantly it increase seconds or decreases seconds. POWER output keeps power on for set time At end of time Sounf output gives 2 s sound and then stops power off *************************************/ #include <18F2331.h> #device adc=10 // 10 bit adc #device *=16 //more RAMia #use delay(internal=8MHz,restart_wdt) #FUSES WDT // Watch Dog Timer #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale #FUSES INTRC_IO //Internal RC Osc, no CLKOUT #FUSES NOPROTECT //Code not protected from reading #FUSES IESO //Internal External Switch Over mode enabled #FUSES BROWNOUT //Reset when brownout detected #FUSES BORV20 //Brownout reset at 2.0V #FUSES PUT //Power Up Timer #FUSES NOCPD //No EE protection //#FUSES STVREN //Stack full/underflow will cause reset #FUSES NODEBUG //No Debug mode for ICD #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NOWRT //Program memory not write protected //#FUSES NOWRTD //Data EEPROM not write protected #FUSES FCMEN //Fail-safe clock monitor enabled #FUSES NOMCLR // no MCLR pin used // // ========= constants #define BATTERYLIMIT 50 // 259 = 7V 10. sekunnin välein vastus 4k7/LM335-2.5 = 0.248 * //===================Eprom- addres // #rom 0xF00000= { 'P'+('R' <<8),'O'+('B' <<8), 'Y'+('T' <<8),'E'+(' ' <<8), ' '+(' ' <<8),'K'+('E' <<8), 'N'+('O' <<8), '9'+('9' <<8), '1'+('6' <<8)} // 245 lukema paristossa vastaa 6.8V //#case #ID 0,6,1,2 // #use delay(clock=8000000,RESTART_WDT) //BYTE PORTs #BYTE T0CON = 0xFB5 #BYTE PORTA = 0x0F80 #BYTE PORTB = 0x0F81 #BYTE PORTC = 0x0F82 #BYTE PORTD = 0x0F83 #BYTE PORTE = 0x0F84 #BYTE TRISA = 0x0F92 #BYTE TRIAB = 0x0F93 #BYTE TRISC = 0x0F94 #BYTE TRISD = 0x0F95 #BYTE LATA = 0x0F89 #BYTE T3CON = 0xFB1 #BYTE CCP1CON =0xFBD #BYTE CCPR1H = 0xFBF #BYTE CCPR1L = 0xFBE #BYTE CCPR2H = 0xFBC #BYTE CCPR2L = 0xFBB #BYTE PIR1 = 0xF9E // bits #BYTE T1CON = 0xFCD #BIT TMR1CS = T1CON.1 #BIT T1OSCEN = T1CON.3 #BIT TMR2IF = PIR1.1 //#BIT PWM1BIT =CCP1CON.5 //#BIT PWM0BIT =CCP1CON.4 #BIT TRISC2 = TRISC.2 #BIT TRISC1 = TRISC.1 #BIT T3CCP2 = T3CON.6 #BIT T3CCP1 = T3CON.3 #use fast_io (B) #BIT MODE =PORTB.6 // left button #BIT START=PORTB.7 // right button void DisplyBatteryVoltage ( void) ; int8 Button=0; int8 up=1; // direction of sec int16 Battery=0; unsigned int8 sec_timer=1; int8 time_ready=0; unsigned int8 powerOffTimer=5; //#BIT DEFAULT_BIT= PORTB.2 // calibration =0V, normal =open #BIT BUZZ = PORTC.2 #BIT POWER =PORTC.3 #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,errors) #define POWEROFFSTATE 0 /// ================== Global Variables =========== unsigned int8 batteryLow =0 ; unsigned int16 batFilter=0; int16 BatterydiplayTimer; unsigned int8 watchdog_timer; /// ================== Function introduction =========== #include #include "lcd.c" void display_min_sec(void) { lcdrow2 (); printf(lcd_putc,"T=%d:%02us ", watchdog_timer, sec_timer); } // hardware setup void init_tasks(void ) { setup_adc_ports(sAN0|sAN1); setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0|ADC_SINGLE_SHOT_A |ADC_FIFO_DISABLED|ADC_WHEN_INT0); set_adc_channel( 1 ); // setup_comparator(NC_NC_NC_NC); // setup_vref(FALSE); setup_spi(FALSE); port_b_pullups(TRUE); //OSCCON |=0xE0; // //setup_oscillator( OSC_8MHZ ); // OSCCON = 0b01110100; //oskillaattori 8MHz // setup_comparator(NC_NC_NC_NC); // A0_A3_A1_A2); setup_timer_0 ( RTCC_DIV_256| RTCC_INTERNAL ); // | RTCC_8_BIT); // 51.2us 25.6 us interrupt setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); // Käynnistä capture ajastin Timer1 // setup_timer_3(T3_INTERNAL|T3_DIV_BY_1); // Käynnistä capture ajastin Timer3 setup_ccp2(CCP_OFF); setup_ccp1(CCP_OFF); set_tris_a(0b11011111); // BATT = adc mittaus ja POWER set_tris_b(0b11000000); set_tris_c(0x30) ; //(0b00110000); // sound RC.3 // set_tris_a(0xFF) ; //(0b1000011000); // set_tris_b(0xFF) ; //(0b1000011000); // setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); PORTB =0xFF; PORTA =0; PORTC =0xC0; OUTPUT_HIGH(PIN_C3) ; // power on // set_timer0( 0xD9DA); // aseta timer0:n perusarvo enable_interrupts(INT_TIMER0); enable_interrupts(INT_RB); // näppäimistökeskeytys enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL) ; //readSETUP(); // lue kallistusanturien offsetit EEPROMMISTA // InitLEVELSENSOR( ); // alusta CCP1 ja CCP2 keskeytyset TIMER1:lle ja timer2 lcd_init(); //init LCD BatterydiplayTimer=10; // set start } #INT_TIMER1 void timer1Isr( void) { restart_wdt(); } // read new minutes and set sec timer to 0 void readadc ( void) { set_adc_channel(1); // select right ADC delay_ms(1); watchdog_timer= read_adc()/34; // 10230> 30 minutes // sec_timer=1; } /*============= Button interrupts if START button pressed, starts the device countin down MODE increase or decrease seconds and then minutes =================*/ #INT_RB void buttonIsr( void) { if(!MODE) { // RB6 readadc(); // read new minutes delay_ms(100); // Button on/off while (!MODE) { // while !MODE is DOWN if(up) { // if increase is on sec_timer++; if( sec_timer >59) { // watchdog_timer ++; sec_timer =59; } } else { // down mode if( sec_timer) sec_timer --; else { sec_timer=0; // if( watchdog_timer) // watchdog_timer--; } } display_min_sec(); delay_ms(200); } if(up) up=0; else up=1; } // !mode end if(!START) { DisplyBatteryVoltage(); time_ready=0; // readadc(); // read new minutes // Button=1; powerOffTimer = watchdog_timer + 2; // 40 minutes time } } /*========================== TIMER0 päivittää näyttöä 10MHz/4/256 = 102,4us pulssit TIMER0:lle reload = 256*256- 9765 = 0xD9DA 9766 pulssia = 1 sek tämä on 10MHz set_timer0( 0xD9DA); // aseta uusi sekuntti timeriin 0 tämä on (MHz int timer set_timer0( 0xE200); 8MHz/4/256 = 7812,5 Hz /256 =30.5176 Hz ================================*/ int8 sec=0; #int_TIMER0 void tmr0_isr( void){ set_timer0( 0xE180); // aseta uusi sekuntti timeriin 0 // restart_wdt(); /* if ( ++timer1_counter < 1 ) { // 10=1 sek välein return; // ei ole kulunut vielä 1 sekuntiia } */ sec++; // displaytime every second if(!watchdog_timer && ! sec_timer ) { time_ready=1; // time end return; } sec_timer --; if(sec_timer >59) sec_timer=0; if( !sec_timer &&watchdog_timer) { // 1 minute sec_timer=60; if( BatterydiplayTimer) BatterydiplayTimer--; // 10 minutes time between battery read if( powerOffTimer) { // 5 minutes on -- powerOffTimer ; // decrease timer } else time_ready=1; // time end if( watchdog_timer ) { // minutes goes watchdog_timer --; } } } // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 unsigned int8 cal []={39,40,41,42,43,44,44,45,45,45,47,48,49,49,49,50,51} ; // 16 battery calibration values.First is 6.0V and last is 4.5V // ADC-value is divided /10 void DisplyBatteryVoltage ( void) { unsigned int8 hi,lo,i; unsigned int8 val ; set_adc_channel( 1 ); delay_ms(1); Battery= read_adc(); batFilter = batFilter*9 + Battery; batFilter /=10; val=batFilter/10; printf("\r batt=%u", val); for(i=0; i<16;i++) { // printf("\r i=%u val=%d cal %u", i, val, cal[i]); if(val< cal[i] ) { // printf("\r break"); break; } } Battery =60 - i ; printf("\ri=%u BAT %ld ", i, Battery); hi=(unsigned int8)( Battery/10 ) ; // kalibroint lo =(unsigned int8) ( Battery - (unsigned int16)hi*10) ; lcdrow1 (); printf(lcd_putc,"BAT=" ); printf(lcd_putc,"%u.%uV ", hi,lo ); printf( " \rBAT=%u.%uV ", hi,lo ); //delay_ms(1000); } /* mittaa ja tarkista paristojännite , jos alle 4V tulosta BatterydiplayTimer välein pariston tilaa */ void readBattery( void){ set_adc_channel(0); delay_ms(1); Battery= read_adc()/10; // printf("\n adc=%ld Limit %ld", Battery, BATTERYLIMIT) ; if( BATTERYLIMIT> Battery) { if( !batteryLow) { // vain 1. kerralla tulosta battery lo lcdrow2 (); printf(lcd_putc,"BATT LOW " ); DisplyBatteryVoltage (); delay_ms(2000); // BatterydiplayTimer =BATTERYTIMER ; // kuinka usein mitataan ja näytetään pariston tilaa batteryLow =1; } } } void initBattery(void ){ int8 i; i=10; set_adc_channel( 0 ); delay_ms(1); batFilter=0; while(i--) batFilter += read_adc(); batFilter /=10; printf("\r badfiler =%lu", batfilter); } void logo( void) { printf("\rOH3GDO "); printf(" %s\r",__DATE__); printf ("Timer 9600 baud "); } /* give a sound for ending timer Three beeps 1s */ void sound (void) { int16 i,j; for(j=0;j<3; j++) { for(i=0; i<500; i++) { output_high (PIN_C2); delay_us(500); output_low(PIN_C2); delay_us(500); } delay_ms(1000); } } //====================================================== // Main program starts //===================================================== void main ( void) { int16 i; PORTB =0xFF; init_tasks(); POWER=1; // poweri päälle aluksi initBattery(); // lue pariston tila aluksi ja näytä se DisplyBatteryVoltage (); logo(); lcdlogo(); readadc(); // read potentimeter to minutes values lcdrow1 (); printf(lcd_putc,"Timer ") ; printf( "Timer ") ; lcdrow2 (); printf(lcd_putc,"%d:%02us ", watchdog_timer, sec_timer); while(1) { if( sec) { display_min_sec(); // Display mins and secs readBattery(); // read if low voltage in Battery printf("\rBatterydiplayTimer=%ld", BatterydiplayTimer); sec=0; } if(!BatterydiplayTimer) { BatterydiplayTimer=10 ; // 10 minutes time DisplyBatteryVoltage(); } if( time_ready) { printf("\r Time=%d", time_ready); printf(lcd_putc,"Time out ") ; sound(); time_ready=0; OUTPUT_LOW(PIN_C3) ; // Shut down } // readBattery(); // testaa paristo } }