// RCTIME.C (CCS Info - PIC16F84) // // Charges capacitor in parallel with a resistor on RB0 for one second. // RB0 is then made an input and capacitor discharges though capacitor and // and the time for detection of a one to zero transition is measured. // // Result in number of 2 usec ticks is displayed in hex on serial LCD // on RA.0. // // Illustrates use of TMR0 and external interrupt. // // This is similar to the BASIC Stamp "rctime" command. This is useful // in determining the value of a resistor. This is discussed at length // and many typical examples are offered in Chapter 7 of my "BASIC // Stamp 2 Tutorial". // // copyright, Peter H. Anderson, Scotland Co, NC, Mar, '99 #case #include <16f84.h> #include <defs_f84.h> // delay routines void delay_ms(long t); void delay_10us(int t); // LCD routines void lcd_init(void); void out_RAM_str(int *s); void lcd_hex_byte(int val); void lcd_dec_byte(int val, int digits); int num_to_char(int val); void lcd_char(int ch); void lcd_new_line(void); #define TxData 0 // RA.0 - interface to serial LCD short int overflow, ext_int_occurred; int count_hi, count_lo; void main(void) { while(1) { lcd_init(); trisb0=0; // output rb0=1; // charge capacitor delay_ms(1000); overflow=FALSE; ext_int_occurred=FALSE; t0cs=0; // clock psa=0; // prescale assignment ps2=0; ps1=0; ps0=0; // prescale 1:2 count_hi=0; intedg=0; // ext int on falling edge t0if = 0; intf=0; TMR0 = 0; // fire up the timer trisb0=1; // make RB0 an input, capacitor now discharging inte = 1; t0ie = 1; gie = 1; while(1) { #asm CLRWDT #endasm if (overflow || ext_int_occurred) { while(gie) { gie=0; } inte=0; t0ie = 0; // housekeeping // lcd_char('.'); break; } } // end of while if (overflow) // no external interrupt occurred { lcd_hex_byte(0xff); lcd_hex_byte(0xff); } else // external interrupt { lcd_hex_byte(count_hi); lcd_hex_byte(count_lo); } delay_ms(1000); } } #int_rtcc rtcc_handler(void) { ++count_hi; if (count_hi == 0) { overflow = TRUE; } t0if=0; } #int_ext ext_int_handler(void) { count_lo = TMR0; // get the low byte ext_int_occurred = TRUE; intf=0; } #int_default default_handler(void) { } // delay routines void delay_10us(int t) { #asm BCF STATUS, RP0 DELAY_10US_1: CLRWDT NOP NOP NOP NOP NOP NOP DECFSZ t, F GOTO DELAY_10US_1 #endasm } void delay_ms(long t) // delays t millisecs { do { delay_10us(100); } while(--t); } // LCD routines int num_to_char(int val) // converts val to hex character { int ch; if (val < 10) { ch=val+'0'; } else { val=val-10; ch=val + 'A'; } return(ch); } void lcd_char(int ch) // serial output to PIC-n-LCD, 9600 baud { int n, dly; // start bit + 8 data bits #asm BCF STATUS, RP0 MOVLW 9 MOVWF n BCF STATUS, C LCD_CHAR_1: BTFSS STATUS, C BSF PORTA, TxData BTFSC STATUS, C BCF PORTA, TxData MOVLW 32 MOVWF dly LCD_CHAR_2: DECFSZ dly, F GOTO LCD_CHAR_2 RRF ch, F DECFSZ n, F GOTO LCD_CHAR_1 BCF PORTA, TxData CLRWDT MOVLW 96 MOVWF dly LCD_CHAR_3: DECFSZ dly, F GOTO LCD_CHAR_3 CLRWDT #endasm } void lcd_init(void) // sets TxData in idle state and resets PIC-n-LCD { #asm BCF STATUS, RP0 BCF PORTA, TxData BSF STATUS, RP0 BCF TRISA, TxData BCF STATUS, RP0 #endasm lcd_char(0x0c); delay_ms(250); } void lcd_new_line(void) // outputs 0x0d, 0x0a { lcd_char(0x0d); delay_ms(10); // give the PIC-n-LCD time to perform the lcd_char(0x0a); // new line function delay_ms(10); } void out_RAM_str(int *s) { while(*s) { lcd_char(*s); ++s; } } void lcd_hex_byte(int val) // displays val in hex format { int ch; ch = num_to_char((val>>4) & 0x0f); lcd_char(ch); ch = num_to_char(val&0x0f); lcd_char(ch); } void lcd_dec_byte(int val, int digits) // displays byte in decimal as either 1, 2 or 3 digits { int d; int ch; if (digits == 3) { d=val/100; ch=num_to_char(d); lcd_char(ch); } if (digits >1) // take the two lowest digits { val=val%100; d=val/10; ch=num_to_char(d); lcd_char(ch); } if (digits == 1) // take the least significant digit { val = val%100; } d=val % 10; ch=num_to_char(d); lcd_char(ch); }