Autor Tema: Pulsadores con 2 pines,deteccion por interrupcion a traves adc y comparador  (Leído 1532 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Pues como dice el enunciado, he estado trabajando en este codigo para poder usar varios pulsadores con  el uso de solo 2 pines y que la deteccion se realizara por interrupciom, para ello uso un canal del comparador analogico y uno del adc y diversos divisores de tension.
Para que la deteccion se haga por interrupcion el grueso del programa se realiza en la rutina del comparador; el comparador se configura con la tension de referencia maxima de forma que cualquier divisor de tension este por debajo y active el comparador. El esquema seria:

Vcc---R--Al adc y comparador del pic---Pulsador1---R1----Tierra
                                                      \-Pulsador2---R2----Tierra
                                                           -----
                                                       \-Pulsadorn---Rn----Tierra

De esta forma segun el pulsador activado la tension en la entrada del pic sera distinta. Para que el funcionamiento sea adecuado creo que lo importante es tomar los valores de las resistencia de forma que disten bastante los valores del adc; y en la toma de decisiones, ya que el valor del adc no sera siempre exacto, hacerlo a traves de if(adc>x)...else if(adc>x2)...else if()....else de forma escalonada de mayor valor del adc a menor. Al no trabajar con un solo valor del adc no da problemas por pequeñas fluctuaciones.

Mi idea es usarlo en un mando, por eso uso una usart viartual solo para transferir. En este caso con los 8 pines del 12f683 hubiera tenido los pines justos, de esta forma me quedan 3 libres para poder usarlos en otra cosa si se me ocurre; y solo se necesita una resistencia mas ya que para cada pulsador hay que usar de todas formas una resistencia. Pero creo que para diseños de otro tipo donde los pines sean cruciales y siempre que el micro disponga de adc y comparador puede servirle a alguien.

En mi caso la resistencia R es de 1kohm y las restantes : 1'8kohm,1kohm,330ohm,100ohm y 0ohm.

Código: C
  1. #include <12f683.h>
  2. #device ADC=8
  3. #fuses INTRC_IO,NOWDT, PUT, NOBROWNOUT, NOCPD,NOMCLR, NOPROTECT
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, xmit=PIN_A2)
  6. /*El programa detecta el accionamiento de disntintos pulsadores, para ello se
  7. conectaran a la entrada del adc distintos divisores de tension cada uno
  8. correspondiente a un pulsador.
  9. La ejecucion del programa se realiza mediante interrupciones, para ello se diseña
  10. los divisores de tension de forma que todos sean inferiores a la tension de
  11. referencia maxima del comparador (High range y 15 = 0'71875 Vdd).En la rutina del
  12. comparador se toma valor adc y se envia por uart.
  13. */
  14. //El envio se realiza en hexadecimal
  15. //Constasntes toma decision
  16. const int modo       = 0xFA;//00001001 reposo
  17. const int adelante   = 0xA5;//00101011 recto
  18. const int atras      = 0xAA;//00011101 atras los dos
  19. const int derecha    = 0xA6;//00011011 derecha
  20. const int izquierda  = 0xA9;//00101101 izquierda
  21. //Vatiables
  22. int valor;
  23. int orden;
  24. //Rutina comparador, lee valor
  25. #INT_COMP
  26. void compara(){
  27.       delay_ms(20);
  28.       if (C1out){
  29.          valor = read_adc(ADC_START_AND_READ);
  30.          delay_us(50);
  31.          //Toma decisiones para envio usart
  32.          if(valor>160){
  33.             orden=atras;
  34.             }
  35.          else if(valor>124){
  36.             orden=derecha;
  37.             }
  38.          else if(valor>61){
  39.             orden=izquierda;
  40.             }
  41.          else if(valor>21){
  42.             orden=adelante;
  43.             }
  44.          else{
  45.             orden=modo;
  46.             }
  47.          printf("%X",orden);// %x envie en hexadecimal
  48.          }
  49.    }
  50.  
  51.  
  52. void main()
  53. {
  54.  
  55.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  56.    setup_adc(ADC_OFF);
  57.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  58.    setup_timer_1(T1_DISABLED);
  59.    setup_timer_2(T2_DISABLED,0,1);
  60.    //Arranca el oscilador
  61.    setup_oscillator(OSC_4MHZ|OSC_INTRC);
  62.    setup_comparator(A1_VR);//Entrada en a1 y Vreferencia interna
  63.    setup_vref(VREF_HIGH|15);        //Vref rango alto y 15 en VR3-0 = >0'70 Vdd
  64.    //ADC
  65.    setup_adc_ports(sAN0);           //Entrada an0/gpio0
  66.    setup_adc(ADC_CLOCK_DIV_64||VSS_VDD);//Reloj y referencias
  67.    //Interrupciones
  68.    enable_interrupts(INT_COMP);
  69.    enable_interrupts(GLOBAL);      //todas las interrupciones desactivadas
  70.    //Programa
  71.    do{
  72.  
  73.    }while(TRUE);               //bucle infinito
  74.    // TODO: USER CODE!!
  75.  
  76. }

Despues de acabarlo, creo que el unico problema es que pasaria si accionamos mas de un pulsador a la vez, lo he probado bastante y no me da ningun fallo.

Al principio pense que tendria que complementar el comparador pero no es necesario, no se si me lie en esa parte.

Espero que le pueda servir a alguien y si me equivoque en algo poder comentarlo con vosotros
Saludos desde Córdoba, españa



 

anything