As i adapted this driver to gcbasic, here are the code if useful for someone, there is an example of use following driver:
'________________________________________________________________________________
'
' COMPARATORS LIBRARY FOR PIC16F87X FAMILY AND COMPATIBLES
'
' (optimized asm)
'
' Original driver name: comp_87X.h
'________________________________________________________________________________
'
'
' This library is free software; you can redistribute it and/or
' modify it under the terms of the GNU Lesser General Public
' License as published by the Free Software Foundation; either
' version 2.1 of the License, or (at your option) any later version.
' This library is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
' Lesser General Public License for more details.
' You should have received a copy of the GNU Lesser General Public
' License along with this library; if not, write to the Free Software
' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
'
'________________________________________________________________________________
'
' AVAILABLE FUNCTIONS (examples):
'________________________________________________________________________________
'
'
'IMPORTANT: ANY CHANGE ON COMPARATORS CONFIGURATION WILL DISABLE COMPARATORS INTERRUPT
' YOU WILL HAVE TO RE-ENABLE IT AFTER OPERATION.
'
'
'Set comparator's mode to two comparators with internal Vref:
'
' comp_conf TWO_COMP_VREF
'
'
'Set multiplexed channels to RA0 RA1:
'
' comp_mpl RA0_RA1
'
'
'Set Vref to 60% of Vdd:
'
' comp_vref VREF_60
'
'
'Invert comparator1 output:
'
' comp_inv C1_INV
'
'
'read comparator1
'
' value = comp1_read
'
'
'read comparator2
'
' value2 = comp2_read
'
'
'Disable comparators
'
' comp_off
'
'________________________________________________________________________________
'
' DEFINITIONS (available options)
'________________________________________________________________________________
'
BCF PIR1,CMIF ; Borra flag interrupciones comparadores
MOVLW 0x07
MOVWF CMCON ; Establece modo off = 111
MOVLW 0x00
MOVWF CVRCON ; Deshabilita modulo Vref
end sub
'*******************************************************************************
' END OF DRIVER
'*******************************************************************************
'EXAMPLE:
'________________________________________________________________________________
'
' Example to be used with adc-87X.h driver
'
'
' A led attached to PORTB.7 will light when Volt. level at PORTA.0 < 60% Vdd
'
'________________________________________________________________________________
'
'General hardware configuration
#chip 16F876A, 20
#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON
#include <comp-87X.h>
'driver must be in "iclude" dir or provide full path
I found a simpler and more direct way to set up the comparator in GCBasic. Though the library is comprehensive, it seems daunting for basic comparator use. The datasheet notes only 2 registers are used to set up polled usage, and reading the datasheet for your particular chip is the best way to be sure each bit is chosen properly. I like to set the registers in binary so it matches closely with the datasheet decriptions. My test code:
#chip 16F627, 4
CMCON = b'00011010' ' Comparator 1 input RA3, internal reference, C1 inverted
VRCON = b'10101100' ' Reference voltage to 2.5V (3:0 / 24 * VDD, here 12/24*5 = 2.5V)
#define ANALOGIN CMCON.C1OUT ' Comparator C1 output bit
#define LED PORTB.1 ' test LED
dir LED out
Main:
IF ANALOGIN = 0 THEN
LED = 1
ELSE
LED = 0
END IF
Goto Main
It's that simple. Long live the Great Cow
-Norbert
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Norbert, you are right, it's simple when you know how comp registers works, but you have to calculate Vref, and is not that easy as you said when you want max resolution, the correct calculations are these:
bit 5
CVRR: Comparator VREF Range Selection bit
1 = 0 to 0.75 CVRSRC, with CVRSRC/24 step size
0 = 0.25 CVRSRC to 0.75 CVRSRC, with CVRSRC/32 step size
bit 3-0
CVR3:CVR0: Comparator VREF Value Selection bits 0 ≤ VR3:VR0 ≤ 15
As i adapted this driver to gcbasic, here are the code if useful for someone, there is an example of use following driver:
'________________________________________________________________________________
'
' COMPARATORS LIBRARY FOR PIC16F87X FAMILY AND COMPATIBLES
'
' (optimized asm)
'
' Original driver name: comp_87X.h
'________________________________________________________________________________
'
'
' This library is free software; you can redistribute it and/or
' modify it under the terms of the GNU Lesser General Public
' License as published by the Free Software Foundation; either
' version 2.1 of the License, or (at your option) any later version.
' This library is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
' Lesser General Public License for more details.
' You should have received a copy of the GNU Lesser General Public
' License along with this library; if not, write to the Free Software
' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
'
'________________________________________________________________________________
'
' AVAILABLE FUNCTIONS (examples):
'________________________________________________________________________________
'
'
'IMPORTANT: ANY CHANGE ON COMPARATORS CONFIGURATION WILL DISABLE COMPARATORS INTERRUPT
' YOU WILL HAVE TO RE-ENABLE IT AFTER OPERATION.
'
'
'Set comparator's mode to two comparators with internal Vref:
'
' comp_conf TWO_COMP_VREF
'
'
'Set multiplexed channels to RA0 RA1:
'
' comp_mpl RA0_RA1
'
'
'Set Vref to 60% of Vdd:
'
' comp_vref VREF_60
'
'
'Invert comparator1 output:
'
' comp_inv C1_INV
'
'
'read comparator1
'
' value = comp1_read
'
'
'read comparator2
'
' value2 = comp2_read
'
'
'Disable comparators
'
' comp_off
'
'________________________________________________________________________________
'
' DEFINITIONS (available options)
'________________________________________________________________________________
'
' Configuración de comparadores
#define COMP_RESET 0X00
#define COMP1_OUT 0X01
#define TWO_COMP 0X02
#define TWO_COMP_OUT 0X03
#define TWO_COMP_COMREF 0X04
#define TWO_COMP_COMREF_OUT 0X05
#define TWO_COMP_VREF 0x06
#define COMP_OFF 0X07
' Multiplexor: usados bits 0-3
#define RA0_RA1 0X00
#define RA2_RA3 0X08
' Invertir salidas: usados bits 4-5 = CMCON.C1INV-C2INV
#define NO_INV 0X00
#define C1_INV 0X10
#define C2_INV 0X20
#define C1_C2_INV 0X30
' Definiciones Vref, voltajes aproximados para Vpp=5v
#define VREF_0 0X20 'V = 0,000
#define VREF_5 0X21 'V = 0,208
#define VREF_6 0X21 'V = 0,208
#define VREF_7 0X22 'V = 0,417
#define VREF_8 0X22 'V = 0,417
#define VREF_9 0X22 'V = 0,417
#define VREF_10 0X22 'V = 0,417
#define VREF_11 0X23 'V = 0,625
#define VREF_12 0X23 'V = 0,625
#define VREF_13 0X23 'V = 0,625
#define VREF_14 0X23 'V = 0,625
#define VREF_15 0X24 'V = 0,833
#define VREF_16 0X24 'V = 0,833
#define VREF_17 0X24 'V = 0,833
#define VREF_18 0X24 'V = 0,833
#define VREF_19 0X25 'V = 1,042
#define VREF_20 0X25 'V = 1,042
#define VREF_21 0X25 'V = 1,042
#define VREF_22 0X25 'V = 1,042
#define VREF_23 0X26 'V = 1,250
#define VREF_24 0X26 'V = 1,250
#define VREF_25 0X26 'V = 1,250
#define VREF_26 0X26 'V = 1,250
#define VREF_27 0X01 'V = 1,406
#define VREF_28 0X01 'V = 1,406
#define VREF_29 0X27 'V = 1,458
#define VREF_30 0X27 'V = 1,458
#define VREF_31 0X02 'V = 1,562
#define VREF_32 0X02 'V = 1,562
#define VREF_33 0X28 'V = 1,667
#define VREF_34 0X03 'V = 1,719
#define VREF_35 0X03 'V = 1,719
#define VREF_36 0X04 'V = 1,875
#define VREF_37 0X04 'V = 1,875
#define VREF_38 0X04 'V = 1,875
#define VREF_39 0X04 'V = 1,875
#define VREF_40 0X05 'V = 2,031
#define VREF_41 0X05 'V = 2,031
#define VREF_42 0X2A 'V = 2,083
#define VREF_43 0X06 'V = 2,188
#define VREF_44 0X06 'V = 2,188
#define VREF_45 0X2B 'V = 2,292
#define VREF_46 0X2B 'V = 2,292
#define VREF_47 0X07 'V = 2,344
#define VREF_48 0X07 'V = 2,344
#define VREF_49 0X08 'V = 2,500
#define VREF_50 0X08 'V = 2,500
#define VREF_51 0X08 'V = 2,500
#define VREF_52 0X09 'V = 2,656
#define VREF_53 0X09 'V = 2,656
#define VREF_54 0X2D 'V = 2,708
#define VREF_55 0X2D 'V = 2,708
#define VREF_56 0X0A 'V = 2,812
#define VREF_57 0X0A 'V = 2,812
#define VREF_58 0X2E 'V = 2,917
#define VREF_59 0X0B 'V = 2,969
#define VREF_60 0X0B 'V = 2,969
#define VREF_61 0X0C 'V = 3,125
#define VREF_62 0X0C 'V = 3,125
#define VREF_63 0X0C 'V = 3,125
#define VREF_64 0X0C 'V = 3,125
#define VREF_65 0X0D 'V = 3,281
#define VREF_66 0X0D 'V = 3,281
#define VREF_67 0X0D 'V = 3,281
#define VREF_68 0X0E 'V = 3,438
#define VREF_69 0X0E 'V = 3,438
#define VREF_70 0X0E 'V = 3,438
#define VREF_71 0X0F 'V = 3,594
#define VREF_72 0X0F 'V = 3,594
#define VREF_73 0X0F 'V = 3,594
#define VREF_74 0X0F 'V = 3,594
#define VREF_75 0X0F 'V = 3,594
#define comp1_read CMCON.C1OUT
#define comp2_read CMCON.C2OUT
'________________________________________________________________________________
'
' FUNCTIONS
'________________________________________________________________________________
sub comp_conf(set_config) #NR
BCF PIE2,CMIE ; Desactiva interrupciones comparadores
BCF PIR1,CMIF ; Borra flag interrupciones comparadores
MOVF set_config,W
MOVWF CMCON ; Establece modo de operación
end sub
sub comp_mpl(set_switch) #NR
BCF PIE2,CMIE ; Desactiva interrupciones comparadores
BCF PIR1,CMIF ; Borra flag interrupciones comparadores
MOVF set_switch,W
BCF CMCON,CIS ; Borra anteriores selecciones
IORWF CMCON,F ; Establece canales multiplexados
end sub
sub comp_vref(set_cvr) #NR
MOVF set_cvr,W
MOVWF CVRCON ; Establece valor de Vref
BSF CVRCON,7 ; Habilita módulo Vref
end sub
sub comp_inv(set_inv) #NR
BCF PIE2,CMIE ; Desactiva interrupciones comparadores
BCF PIR1,CMIF ; Borra flag interrupciones comparadores
MOVF set_inv,W
BCF CMCON,4 ; Borra anteriores selecciones
BCF CMCON,5
IORWF CMCON,F ; Establece canales invertidos
end sub
sub comp_off
BCF PIE2,CMIE ; Desactiva interrupciones comparadores
BCF PIR1,CMIF ; Borra flag interrupciones comparadores
MOVLW 0x07
MOVWF CMCON ; Establece modo off = 111
MOVLW 0x00
MOVWF CVRCON ; Deshabilita modulo Vref
end sub
'*******************************************************************************
' END OF DRIVER
'*******************************************************************************
'EXAMPLE:
'________________________________________________________________________________
'
' Example to be used with adc-87X.h driver
'
'
' A led attached to PORTB.7 will light when Volt. level at PORTA.0 < 60% Vdd
'
'________________________________________________________________________________
'
'General hardware configuration
#chip 16F876A, 20
#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON
#include <comp-87X.h>
'driver must be in "iclude" dir or provide full path
#define LED1 PORTB.7
'________________________________________________________________________________
DIR A0 IN
DIR B7 OUT
comp_conf TWO_COMP_VREF
comp_mpl RA0_RA1
comp_vref VREF_60
do while true
LED1 = comp1_read
loop
'________________________________________________________________________________
I think this driver is useful with many other pics, just tested with 16f87X/87Xa and 16f62X/62Xa.
To use with other than 87X/87Xa just config this way:
comp_conf 0x02
or:
comp_conf b'010'
or:
comp_conf 2
I found a simpler and more direct way to set up the comparator in GCBasic. Though the library is comprehensive, it seems daunting for basic comparator use. The datasheet notes only 2 registers are used to set up polled usage, and reading the datasheet for your particular chip is the best way to be sure each bit is chosen properly. I like to set the registers in binary so it matches closely with the datasheet decriptions. My test code:
#chip 16F627, 4
CMCON = b'00011010' ' Comparator 1 input RA3, internal reference, C1 inverted
VRCON = b'10101100' ' Reference voltage to 2.5V (3:0 / 24 * VDD, here 12/24*5 = 2.5V)
#define ANALOGIN CMCON.C1OUT ' Comparator C1 output bit
#define LED PORTB.1 ' test LED
dir LED out
Main:
IF ANALOGIN = 0 THEN
LED = 1
ELSE
LED = 0
END IF
Goto Main
It's that simple. Long live the Great Cow
-Norbert
Hi nobody. Thanks for the feedback.
Norbert, you are right, it's simple when you know how comp registers works, but you have to calculate Vref, and is not that easy as you said when you want max resolution, the correct calculations are these:
bit 5
CVRR: Comparator VREF Range Selection bit
1 = 0 to 0.75 CVRSRC, with CVRSRC/24 step size
0 = 0.25 CVRSRC to 0.75 CVRSRC, with CVRSRC/32 step size
bit 3-0
CVR3:CVR0: Comparator VREF Value Selection bits 0 ≤ VR3:VR0 ≤ 15
When CVRR = 1:
CVREF = (VR<3:0>/ 24) • (CVRSRC)
When CVRR = 0:
CVREF = 1/4 • (CVRSRC) + (VR3:VR0/ 32) • (CVRSRC)
And when you want to deal with multiplexed and/or inverted channels, it takes some time to determine wich bits you have to set or clear.
Then that's why a driver: you don't have to deal with all those stuffs.
Regards