# source code for voltage & freq detection

#### keverin

Joined Sep 13, 2012
3
hi guys

I am new to the pic programming . I need source code example for measuring frequency and voltage . Currently , the complier i using is Mikroc .. and the pic i be using is PIC 16F887. Any one can help ??? i need the code urgently ....

#### Papabravo

Joined Feb 24, 2006
12,877
I'll get right on that after my coffee break.

The code for reading voltage is to have the A2D converter do a conversion and read the result.

Measuring frequency requires reading the value of a free running timer, then reading it again on the next edge of the same type. the difference is the period and the reciprocal of the period is the frequency.

Why don't you show us what you come up with and we'll help you refine it. Would that work for you?

#### Dodgydave

Joined Jun 22, 2012
8,797
this is an A/D routine to measure temperature in binary, that i built,which is the same principle , getting a voltage on the Analogue i/p using a Pic-16F690, it uses external Vref for the A/D

you may need to modify your registers if they are not the same>>

Rich (BB code):
;  USING A LM35CZ sensor on AN2, Vref (AN1)set to 2,56Volts gives 1mVolt =0.4bits,
;   Sensor gives out 10mVolt per degree C= 4 bits per degree
; because we are using upper 8 bits, there is an automatic divide by 4, so 1 degree =1 bit
;  0 Deg to 100Deg'C= 0mV to 1V output from sensor =0 to 1024 bits.

list        p=16f690        ; list directive to define processor
#include    <P16F690.inc>    ; processor specific variable definitions

__CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
; 4Mhz clock

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

errorlevel -302     ; suppress banksel warning messages during assembly
errorlevel -311     ;  suppress HIGH operator warning messages during assembly

org 0000
goto  Main

;***** VARIABLE DEFINITIONS
cblock 0x20
RESULTLO     ; temp regs for routine
RESULTHI
Set_temp
d1
d2
d3

endc

Main

; set up registers ***************************************************

BSF STATUS,RP0   ;Bank 1
BCF STATUS,RP1    ; set up status bits
MOVLW b'01010000' ; A/D 1/8 osc =2usec a/d time at 4mhz clock
BSF TRISA,0       ;Set RA0 to input
clrf TRISC
clrf TRISB        ; set port c output
BCF STATUS,RP0    ;Bank 2
BSF STATUS,RP1    ; setup status bits
clrf ANSEL        ;****************** portc to digital i/o
BSF ANSEL,0       ;Set RA0 to analog
clrf ANSELH       ; set port b/c to digital I/O
BCF STATUS,RP1    ;Bank 0
clrf PORTB        ; clear output ports
clrf PORTC
goto Begin
;*************************************************************************

;**********************************************************************
Temperature
MOVLW b'01001001' ;Left justified(bit 7),  Vref(bit 6 ,1=external source), AN2 source input(bit 3) temp i/p
call Delay
GOTO \$-1        ;No, test again
MOVWF RESULTHI  ; store upper 8 bits
BSF STATUS,RP0  ;Bank 1
BCF STATUS,RP0  ;Bank 0
MOVWF RESULTLO  ; save lower 2 bits
return
;*************************************************************************************
Begin
call Temperature
movfw RESULTHI
movfw PORTC   ;  display temp on leds
goto Begin

end

Last edited:

#### keverin

Joined Sep 13, 2012
3
The code as follow:

seem not right ...

Rich (BB code):
// Lcd module connections

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

// End of Lcd module connections

void main() {
unsigned long frequency;               // complete frequency count
unsigned long freq_low;                // low word of frequency count
char freq_txt[11];                     // buffer for ASCII conversion
unsigned char ch;                    //
unsigned int adc_rd;                 // Declare variable
char *text;                          //
long tlong;                          //

ANSEL = 0x04;                    // Pin RA2 is configured as an analog input
ANSELH = 0;                      // Rest of pins are configured as digital
TRISA = 0xFF;

/*ANSELA = 0;                       // Configure PORTA pins as digital
ANSELB = 0;                       // Configure PORTB pins as digital
ANSELC = 0;                       // Configure PORTC pins as digital
ANSELD = 0;*/                       // Configure PORTD pins as digital

ADCON0 = 0;                       // A/D off
ADCON1 = 0x0f;                    // all digital

CM1CON0 = 0;                    // disable 18F45K22 comparator
CM2CON0 = 0;                      // disable 18F45K22 comparator

TRISB = 0;                        // PORTB is output
PORTB = 0x00;                     // Initialize PORTB

//LATA = 0;                         // all off
//LATB = 0xff;                      // disable GLCD if fitted
//LATC = 0;                         // all off

//TRISA = 0xC0;                     // all output except OSC pins
//TRISB = 0x00;                     // all output
//TRISC = 0x01;                     // all output except RC0

Delay_ms(100);                       // Wait for LCD to stabilise
Lcd_Init();                          // Initialize Lcd
Lcd_Cmd(_LCD_CLEAR);                 // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF);            // Turn cursor off
Lcd_Out(1,1, "Frequency on RA2");        // Print text to Lcd, 1st row, 1st column
Lcd_Out(2,1, "00 Hz   ");                 // Print text to Lcd, 2nd row, 1st column

tlong = (long)adc_rd * 5000; // Convert the result in millivolts
tlong = tlong / 1023;        // 0..1023 -> 0-5000mV
ch = tlong / 1000;             // A/D conversion. Pin RA2 is an input.

//PWM1_Init(2000);                  // Test frequency PWM1 module
//PWM1_Start();                     // start PWM1
//PWM1_Set_Duty(127);              // Set current duty for PWM1 50%

T2CON = 0b00001111;                     // T0 on, 16 bit, prescaler 256
T1CON = 0b11000101;
//T1CON = 0x85;                     // T1 on, ext input, no prescale
//1GCON = 0x00;                    // no gating

while(1){

TMR0 = 0x85; //0b10000101     // set up timer 0 for 1 second time out
// Timer register
TMR0 = 0xee;                  // writing TMR0L also writes TMR0H
INTCON.TMR0IF = 0;            // reset time-out indicator
frequency = 0;                // initialise count
TMR1L = 0;                    // reset to 0
TMR1H = 0;                    // reset to 0
PIR1.TMR1IF = 0;              // initialise

while(!INTCON.TMR0IF){        // wait for 1 second time-out
if(PIR1.TMR1IF){          // monitor frequency count overflow
PIR1.TMR1IF=0;        // reset overflow
frequency += 65536;   // increment count high bytes
}
}

freq_low = (TMR1H << 8) + TMR1L;  // collect frequency bytes
frequency += freq_low;            // collect frequency bytes
LongWordToStrWithZeros(frequency, freq_txt);          // covert result to ASCII
Lcd_Out(2,1, freq_txt);       // Print text to Lcd, 2nd row, 1st column
// LATA=LATA^1;                  // show some life by toggling LED
}
}

Last edited by a moderator:

#### Dodgydave

Joined Jun 22, 2012
8,797
Mine is in Assembly Language, yours must be in C?