Autor Tema: Problema con rutina antirebote en Pic 18f4620  (Leído 3921 veces)

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

Desconectado charlosh

  • PIC10
  • *
  • Mensajes: 12
Problema con rutina antirebote en Pic 18f4620
« en: 24 de Marzo de 2010, 12:43:32 »
Buenos dias, he utilizado en varios proyectos anteriores un programa para evitar los rebotes al utlizar los teclados matriciales basado en un programa que entiendo que realizó Pocher pero que modificó PalitroqueZ, el cual trasnscribo en la parte de abajo de este mensaje. El asunto es que como comento  la he utilizado varias veces con un 16f877A, un teclado 4x4 y un Lcd 2x16 y me ha funcionado muy bien, pero debido a que mi programa consume demasiados recursos (mayor Rom, ram, etc.) he comprado un pic 18f4620, pero al cargarle el programa no me funciona la seccion de antirebote (le cargo un programa que corre bien en el 16f877A) y solo le modifico la seccion del device y le pongo que se utiliza  18f4620.h , lo compilo en el Pcwhd y compila bien. Cuando trato de simularlo en el Proteus hago las modificaciones pertinentes  (borro el anterior Pic y le le cargo el nuevo Pic, y lo alambro de manera semejante) si oprimo una tecla en el teclado se imprime varias veces mientras esta oprimida. Al ver esto vuelvo a hacer las modificaciones necesarias en el Pcwhd y el proteus para dejar el programa en las condiciones originales (con Pic 16f877A) y funciona bien otra vez(no rebotes).
Si vuelvo a hacer los cambios (tratar de correr con el 18f4620) me aparece el mismo problema, he visualizado en la watch windows la variables del programa  iContador_1ms que en el programa cuando llega a un valor de 30 debe de deternerse, pues se visualiza que llega a 30 se resetea a 0 y vuelve a contar.

Salvo ese problema el programa funciona correctamente (despliega mensajes, hace operaciones, acepta introduccion de password, etc) solo que no respeta la seccion de antirebotes del teclado.

No se si internamente haya alguna instruccion que el pic18f4620 no la procese igual que el 16f877A.

Necesito de su ayuda y experiencia para saber si me pueden dar una orientacion por donde viene el problema


Saludos.

Aqui esta el programa al que me refiero




1.   /* v1.0
2.      Programa ejemplo que hace uso del teclado matricial
3.      4x4 mediante interrupciones y liberando 4 pines del portb,
4.      haciendo posible cambiarlas por cualquier pin del uC PIC.
5.      Los 4 pines liberados corresponden a las columnas que maneja el teclado
6.      
7.      Caracteristicas:
8.      - Cambio de estado en los pines RB[7-4]
9.      - Retardo antirrebotes por Timer0
10.      
11.      con la interrupción por cambio en PORTB, se gestiona el teclado sin tener
12.      que encerrar todo el programa principal en un bucle.
13.      
14.      la interrupción del timer0 sirve para crear un retardo antirrebotes SIN
15.      hacer demorar la ejecución del programa principal.
16.      
17.      el próposito de ambas interrupciones es detectar la pulsación de una
18.      tecla y garantizar que no sea un falso contacto todo ello sin "detener"
19.      el bucle principal.
20.      
21.      solo se gestionará el proceso correspondiente cuando se pulsa la tecla
22.      (está validado para no responder a soltar la tecla o mantenerla
23.       indefinidamente).
24.      si quiere ejecutar el proceso asociado a la tecla nuevamente, basta pulsar
25.      otra vez dicha tecla.
26.   
27.   
28.      Autor: Pocher
29.      Modificación: PalitroqueZ  14-May-2008 11:10am
30.      
31.      Este código puede usarse libremente siempre que se mantenga/n y/o respete/n
32.      el/los credito/s de/los autor/es
33.   
34.   */
35.   
36.   #include <18F4550.h>
37.   #fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,
38.   #fuses NOLVP,NODEBUG,NOPBADEN,USBDIV,PLL1
39.   #fuses CPUDIV1,NOVREGEN,NOIESO // IESO bit ignorado
40.   #use delay(clock=48M)
41.   
42.   #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // opcional
43.   
44.   #use fast_io(A)   // opcional
45.   #use fast_io(B)   //    "
46.   #use fast_io(C)   //    "
47.   #use fast_io(D)   //    "
48.   #use fast_io(E)   //    "
49.   
50.   #byte PORTB=0xF81
51.   // declarar la dirección del portb
52.   
53.   //*********************************
54.   // variables globales
55.   //*********************************
56.   
57.   int8 const iVeces_iContador_1ms=30;
58.   int8 iFlanco_RB=0;  // bandera que detecta el primer flanco del pulsador
59.   int8 iContador_1ms=0;  // con Fcpu=48MHz, el timer0 cuenta máximo ~ 5ms
60.   int8 iTecla_capturada=0;
61.   int1 fImprimir=0;  // Bandera ejemplo para imprimir tecla presionada
62.   
63.   #define iColumna0   PIN_D7
64.   #define iColumna1   PIN_C2
65.   #define iColumna2   PIN_A0
66.   #define iColumna3   PIN_D0
67.   
68.   //*********************************
69.   // archivos a incluir
70.   //*********************************
71.   #include "Teclado_flex_change_portb.C"
72.   //----------------------------------------------------
73.   #int_timer0
74.   void  tmr0_isr(){
75.   int8 temp;
76.   
77.      if(iContador_1ms==iVeces_iContador_1ms){ 
78.         // retardo antirebotes = 1ms * iVeces_iContador_1ms
79.         // ya pasaron 30 ms después de la interrupción
80.         // por cambio de PORTB (el retardo puede variarse)
81.         temp = input_b() & iLos_Cuatro_MSB_PORTB;
82.         if(iFlanco_RB == temp){
83.         // pregunta si realmente la tecla se pulsó
84.         // o por el contrario es un falso contacto
85.        
86.         // aqui es donde se procesa la tecla para lo que queramos hacer
87.            iTecla_capturada=kbd_getc();
88.            fImprimir=1;
89.          }
90.         Limpiar_Columnas();
91.         iContador_1ms=0;
92.         disable_interrupts(INT_TIMER0);
93.         #asm movf PORTB,0 #endasm
94.         clear_interrupt(int_rb); // RBIF = 0 limpia la bandera
95.         enable_interrupts(int_rb);
96.      }else{
97.         iContador_1ms++;
98.         // continua el miniretardo que es multiplo de retardo deseado
99.      }
100.   }
101.   //----------------------------------------------------
102.   #int_rb // Interrupcion cambio de estado RB[4-7]
103.   void control_rb() {
104.      iFlanco_RB = input_b() & iLos_Cuatro_MSB_PORTB;
105.      // almacena el valor de RB[7-4] inicial
106.      if(iFlanco_RB != iLos_Cuatro_MSB_PORTB){
107.         // este condicional sirve para validar cuando se pulsa
108.         // la tecla (mas NO cuando se suelta).
109.         // consume 4 lineas de asm.
110.         disable_interrupts(INT_RB);
111.         // deselecciona la interrupción por cambio en PORTB
112.         // para comenzar el retardo antirebote
113.         iContador_1ms=0;
114.         setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
115.         // configura el Timer0 base de tiempo interno, pre-escaler=1:256
116.         set_timer0(68); // retardo de ~ 1ms
117.         enable_interrupts(INT_TIMER0);
118.      }
119.      #asm movf PORTB,0 #endasm
120.      Limpiar_Columnas();
121.   }
122.   
123.   //--------------------------------------------------
124.   void main() {
125.      output_a(0);
126.      output_b(0);
127.      output_c(0);
128.      output_d(0);
129.      output_e(0);
130.      
131.      set_tris_a(0x0);
132.      set_tris_b(0b11110000);  // RB[7-4] son entradas
133.      set_tris_c(0x0);
134.      set_tris_d(0x0);
135.      set_tris_e(0x0);
136.      
137.      port_b_pullups(true); 
138.      // no es obligatorio. Si es false, se colocan pull-up externas en RB[7-4]
139.      disable_interrupts(global);
140.      disable_interrupts(INT_TIMER0);
141.   
142.      printf("Preparando al teclado por interrupcion (int_RB)\n\r");
143.   
144.      Limpiar_Columnas();
145.      
146.      enable_interrupts(int_rb);
147.      #asm movf PORTB,0 #endasm  // con estas 2 lineas, se borra
148.      clear_interrupt(INT_RB);   // RBIF al inicio del programa
149.      enable_interrupts(global);
150.      
151.      while(1){
152.         if(fImprimir){
153.            printf("interrupcion: %x\n\r",iTecla_capturada);
154.            iTecla_capturada=0;
155.            fImprimir=0;









 

anything