# Comparadores del PIC16F628A



## ingenierocesar (Sep 3, 2010)

Hola..

Soy estudiante de electrónica acá en Chile y me atrae bastante los microcontroladores, he aprendido a usar el TMR0, hacer PWM en Assembler y en C y he realizado decenas de proyectos con microcontroladores.

Pero.... tengo un problema.... ¿Podrian ayudarme y decirme como se utilizan los comparadores del PIC en Assembler?

es que no encuentro informacion en la web 

Se los agradecería mucho  de antemano muchas gracias.

--Ingeniero--


----------



## ByAxel (Sep 3, 2010)

Hola:
Según la hoja de datos este PIC tiene 2 comparadores, con el registro CMCON se multiplexar los pines de los comparadores (en el datasheet hay una tabla).
Tiene la posibilidad de usar referencia de voltaje externo o interno (usando el módulo de voltaje de referencia).
> La señal análoga presente en VIN- es comparada con la señal aplicada a VIN+ y la salida del comparador es una señal digital, cuando el voltaje en VIN+ es menor que el voltaje en VIN- la salida está a nivel bajo (0) y cuando VIN+ es mayor que VIN-, la salida esta a nivel alto (1); (la señal de salida tiene algo de incertidumbre debido a los desplazamientos de voltaje en las entradas y el tiempo de respuesta).

> La salidas de la señal se guarda en los bit C1OUT y C2OUT del registro CMCON, así mismo los valores en esos bit se pueden invertir poniendo a 1 los bit C1INV y C2INV.

> Es posible provocar una interrupción cuando la salida de uno de los comparadores cambia, para eso se debe de activar el bit CMIE del registro PIE1 (también interrupción global), echo así cuando la salida del comparador cambie, el bit CMIF del registro PIR1 se pone a 1 y ocurre la interrupción.

Revisa el datasheet... hasta ahí, no se donde más tengas las dudas...

saludos


----------



## ingenierocesar (Sep 4, 2010)

Gracias.... no pensé encontrar una respuesta tan pronto.

Me sirve de mucho tu ayuda, ya que no sabía casi nada de eso... Pero, ¿No tienes por casualidad algún código fuente en Assembler en donde se usen los comparadores?

He tratado de hacer un programa yo solo pero solo obtengo malos funcionamientos.

De nuevo muchas gracias...

--Ingeniero--


----------



## ByAxel (Sep 5, 2010)

```
PROCESSOR	16F628A
#include <P16F628A.inc> 
	errorlevel -302
	__CONFIG _LVP_OFF & _MCLRE_OFF & _INTOSC_OSC_NOCLKOUT

	org	0x00
	banksel	CMCON
	movlw	b'00000101'	; Comparador C2 (RA2:RA1), el resto digitales
	movwf	CMCON
	banksel TRISA
	movlw	b'00000110' ; Solo (RA2:RA1) análogos
	movwf	TRISA
	clrf	TRISB
	banksel	PORTA
	clrf	PORTB
	
Main:					; Pone a '0' ó '1' el RB0
						; de acuerdo con el estado del bit
						; de salida del comparador C2
	btfss	CMCON,C2OUT	
	bcf		PORTB,0
	btfsc	CMCON,C2OUT
	bsf		PORTB,0
	goto	Main	

	end
```
Gracias tambien, ya que aprendi un poco más de ese módulo, el cuál no es muy usado 
pero lo repito; todo está en el datasheet del PIC, incluso un ejemplo.

Como iniciarse en El Foro (Foros de Electrónica)

saludos.


----------



## ingenierocesar (Sep 5, 2010)

Gracias "ByAXEL" 

Esto me será de mucha utilidad.... y tienes razón, todo está en la datasheet, solo que sería mejor si la data estuviera en español. 

--Ingeniero--


----------



## everardors (Nov 5, 2014)

perdon que reviva el tema, pero me gustaria puedan ayudarme con un ejemplo similar en ccs, no soy experto y no se como sacarlo del datasheet, espero alguien pueda ayudarme, gracias


----------



## D@rkbytes (Nov 6, 2014)

Este ejemplo que adjunto con simulación, es el uso básico de uno de los dos comparadores del PIC16F628A.
Verás que funciona como un comparador estándar tal como el LM311.

Es muy sencillo el código y está escrito en C de CCS.

Saludos.


----------



## everardors (Nov 6, 2014)

gracias D@rkbytes era exactamente lo que buscaba, solo para para aclarar:

aqui comparas A1 con A2, y tu verificas que C2OUT baja, le dices que encienda el led, hasta ahi entiendo masomenso, pero me surge la duda si yo nesecito comparar si es alto o mas bajo de vref como lo puedo hacer, o sea no veo donde le preguntas si es mas bajo que o mas alto que, espero me entiendas, gracias


----------



## D@rkbytes (Nov 6, 2014)

everardors dijo:


> gracias D@rkbytes era exactamente lo que buscaba, solo para para aclarar:
> 
> aqui comparas A1 con A2, y tu verificas que C2OUT baja, le dices que encienda el led, hasta ahí entiendo más o menos, pero me surge la duda si yo necesito comparar si es alto o mas bajo de vref como lo puedo hacer, o sea no veo donde le preguntas si es mas bajo que o mas alto que, espero me entiendas, gracias


Pues como es el comparador de un microcontrolador, tienes dos opciones.
Puedes invertir el hardware o la lógica de comparación por software.
Si tomas *RA1* como *VRef*, la comparación será inversa.
Y si cambias *while (C2OUT)* por *while (!C2OUT)* también la comparación será inversa.
También puedes cambiar el *while* por un *if* para no crear un bucle.

De esta forma:

```
[COLOR=Blue]while[/COLOR] (true)
   {
      [COLOR=Blue]if[/COLOR] (!C2OUT)

         // Código
         
      [COLOR=Blue]else[/COLOR]
      
         // Código
   }
```
Suerte.


----------



## everardors (Nov 6, 2014)

ok, gracias ese fue mas que nada aclaracion, jeje como me lo pasaste primero lo adapte u funciono muy bien, gracias


----------



## everardors (Nov 7, 2014)

D@rkbytes, ahora me surge otra nesecidad, nesecito tener dos niveles de tencion a comparar, si esta en estado alto nesecito que haga una cosa y si esta en bajo otra, pero seria el mismo potenciometro, tengo dos teorias de como hacer esto. 

1 es setup_comparator(A0_A3_A1_A2); poner las dos referencias diferentes en A2 y A3, y conectar el potenciometro a A0 y  A1, no se si esto funcione??

2 creo que seria por programacion, pero no se como seria en setup_comparador para que fueran 2 pines de referencia y un pin comparador(espero explicarme).

otra pregunta, intente poner setup_comparator(A0_A1_NC_NC); y esto no me lo toma el compilador me marca error, ojala solo puedas aclararme por que, no me gusta quedarme con dudas jejeje. 

gracias por tu atencion.


----------



## D@rkbytes (Nov 7, 2014)

everardors dijo:


> D@rkbytes, ahora me surge otra necesidad, necesito tener dos niveles de tensión a comparar, si esta en estado alto necesito que haga una cosa y si esta en bajo otra, pero seria el mismo potenciómetro, tengo dos teorías de como hacer esto.
> 
> 1 es setup_comparator(A0_A3_A1_A2); poner las dos referencias diferentes en A2 y A3, y conectar el potenciómetro a A0 y  A1, no se si esto funcione??
> 
> 2 creo que seria por programación, pero no se como seria en setup_comparador para que fueran 2 pines de referencia y un pin comparador(espero explicarme).


Lee la hoja de datos en la sección 10.0 "COMPARATOR MODULE" viene la configuración de CMCON
Y en la sección 10.1 "Comparator Configuration" están los modos de entrada y salida del comparador.



everardors dijo:


> Otra pregunta, intente poner setup_comparator(A0_A1_NC_NC); y esto no me lo toma el compilador me marca error, ojala solo puedas aclararme por que, no me gusta quedarme con dudas jejeje.


En el archivo 16F628A.H vas a encontrar información sobre esto.
Éstas son las constantes permitidas para setup_comparator();
A0_A3_A1_A2
A0_A2_A1_A2
NC_NC_A1_A2
NC_NC_NC_NC
A0_VR_A1_VR
A3_VR_A2_VR
A0_A2_A1_A2_OUT_ON_A3_A4
A3_A2_A1_A2
CP1_INVERT
CP2_INVERT

Y los bits  6 y 7 del registro CMCON:
#bit C1OUT = 0x1f.6
#bit C2OUT = 0x1f.7

Me parece que con esta información ya tendrás una idea de cómo lo podrías hacer.

Saludos.


----------



## manuelsegundo (Jul 13, 2016)

Me estoy iniciando en el tema de los microtontroladores. Solamente manejo a medias la programación con PROTON IDE.He andado por toda la web y no hallo un ejemplo de programación que me solucione el asunto que están tratando. No se como programar RA0 y RA1 del 16F628A (necesito utilizar ambos como entradas análogas independientes). Solo les pido un ejemplo en PROTON. Mil gracias a todos.


----------



## D@rkbytes (Jul 13, 2016)

En la hoja de datos se encuentra esa información.
Busca en la sección "Comparator Module", ahí podrás ver cuales son las opciones disponibles.


----------



## manuelsegundo (Jul 15, 2016)

Gracias señor moderador. Problema solucionado; puse todos los pines como digitales con "ALL_DIGITAL" y posteriormente configuré AN0 y AN1 como análogos con TRISA.0 y TRISA.1 = 1, así conservé el resto de pines del puerto A como digitales.
Gracias.


----------



## D@rkbytes (Jul 15, 2016)

Así no es lo correcto.
En los PIC16F627/8/48 /A, el registro encargado de eso, es CMCON.
All_Digital actúa sobre él, y el registro TRISA convierte los pines en entradas o salidas, pero no actúa sobre los comparadores.

Así que la configuración sobre qué pines estarán dedicados al comparador, es en CMCON.
Y por defecto todos los pines están configurados como entradas.
Así que escribir; TRISA.0 = 1 y TRISA.1 = 1, resulta redundante e innecesario.


----------



## manuelsegundo (Jul 15, 2016)

Lo que expliqué lo hice y me funcionó. Quiero saber por qué?. El caso es que el pin AN2 lo estoy utilizado con entrada "digital"  y necesitaba AN0 y AN1 como análogos. Con ALL_DIGITALL me funcionaba el digital, pero no los análogos, y si suprimía el ALL_DIGITAL, el digital no me funcionaba. Ateniéndome a lo que me dices, sencillamente no entiendo. Salvo que en el momento en que estaba haciendo las pruebas me confundí. En todo caso quiero saber si con  solo ALL_DIGITAL  me funcionan los pines mencionados como análogos? Gracias.


----------



## D@rkbytes (Jul 15, 2016)

Repito nuevamente, en el PIC16F628A, "All_Digital" actúa sobre el registro CMCON
Lo configura en 0x07 = 0b00000111
O sea, le da el valor 7 que corresponde según la hoja de datos a desactivar los comparadores análogos.
CM2, CM1 y CM0 = 1
​ Si no entiendes, es porque necesitas leer la hoja de datos.
Ahí encontrarás la configuración que necesitas hacer en el registro CMCON.


----------



## RenzoFdk (May 19, 2018)

Bueno simplemente intento usar un comparador analogico con el pic 16F628A mi codigo es el siguiente:
Lo hice en MikroC


```
void main() {

     CMCON= 0x04;
     TRISA = 0b00001111;
     TRISB= 0x00;

}
```


Aqui la foto de la simulacion: (la resistencia deberia mostrar una tencion alta cuando el voltaje de entrada es menor al voltaje de referencia,)


Oculto: Foto simulacion en PROTEUS








Este mismo programa me funciono para otro pic (16F877A) pero con el PIC16F628A no funciona!. Espero que puedan ayudarme a usar el comparador de este pic, gracias!.


----------



## Miembro eliminado 356005 (May 19, 2018)

Pero... a ver... no entiendo... el resultado de la comparación debería hacerse a partir del propio registro CMCON, en concreto, el bit es C2OUT.


----------



## RenzoFdk (May 19, 2018)

Muchas gracias, solucionaste mi problema. 
Por alguna razon ese simple codigo funcionaba con el PIC17F877A pero no con el PIC16F628A.

este es el codigo que use para solucionar el problema:



```
void main() {
     CMCON= 0x04;
     TRISA = 0b00001111;
     TRISB.F0=0x00;
 while(1){

     if(CMCON.C2OUT)
     {
     PORTB = 0b00000001;
     }
     else
     {
     PORTB = 0b00000000;
     }
     }
}
```


----------

