Autor Tema: Ayuda con interruciones en RB0 y RB1  (Leído 6501 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Ayuda con interruciones en RB0 y RB1
« en: 09 de Abril de 2011, 22:43:53 »
Buenas a todos, haber si alguien me puede ayudar, sigo con mi proyecto USB en el 18f4550. Tengo q capturar un voltaje por RA0 y las interrupciones de un encoder por RB0 y RB1, despues enviar los valores por USB. He desarrollado el siguiente codigo, donde la comunicación USB funciona correctamente, también la captura del ADC, pero he tenido problemas con las interrupciones RB0 y RB1 ya que no me captura la cantidad de interrupciones recibidas. He programado varios PIC's y he modificado muchas veces el codigo pero nada q encuentro el fallo, entonces he programado el PIC y lo he montado en protoboard, luego he mirado los voltajes en RB0 y RB1 y resulta q me aparecen 4V en RB0 y 1,5V en RB1 y no tengo ni idea por q razon salen esos voltajes si estoy configurando RB0 y RB1 como entradas y el resto como salidas. Me gustaria q alguien probara mi código y me dijera si tambien salen esos voltajes en RB0 y RB1. El codigo es el siguiente:


#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use fast_io(b)

#Byte PortB = 0xF81

#define USB_HID_DEVICE FALSE // deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 32 // size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 32 // size to allocate for the rx endpoint 1 buffer
#include <pic18_usb.h> // Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include "header.h" // Configuración del USB y los descriptores para este dispositivo
#include <usb.c> // handles usb setup tokens and get descriptor reports

int16 x = 0;
int16 adc0=0;
char  voltage[9];
char  bufer[];
char  Conexion[] = "o.k";
const int8 Lenbuf = 32;
int8  recbuf[Lenbuf];

#INT_EXT
void prueba()
{     
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
   { 
       Ext_Int_Edge(H_TO_L);    // entonces activar la siguiente interrupción por flanco de bajada.
       If (Bit_Test(PortB, 1))  // Si RB1 está a 1,
       {
         x++;                      // entonces incrementar una unidad el valor de X.
       }
   }
   Else                         // Si RB0 se ha puesto a 0 (flanco de bajada),
   { 
       Ext_Int_Edge(L_TO_H);    // entonces activar la siguiente interrupción por flanco de subida.
       If (Bit_Test(PortB, 1))  // Si RB1 está 1,
       {
           x--;                 // entonces decrementar una unidad el valor de X.
       }
   }
}

void main()
{
   port_b_pullups(false);
   setup_adc_ports(AN0|VSS_VDD);//para escoger el canal cero y el vss y vdd
   SETUP_ADC(ADC_CLOCK_INTERNAL);//la frecuencia de muestreo es 2-6us
   SET_ADC_CHANNEL(0);
   delay_ms(333);
   disable_interrupts(Int_Ext);
   disable_interrupts(GLOBAL);
   
   Ext_Int_Edge(L_TO_H);        // Inicialmente detectar interrupción por flanco de subida.
   Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa a través de RB0.
   Enable_Interrupts(GLOBAL);   // Interrupciones Generales Activadas.
   Set_Tris_B(0b00000000);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
   PortB=0;
   usb_init();
   usb_task();
   delay_ms(333);
   output_high(PIN_C2);
   
   while (TRUE)  // Si el PIC esta conectado al PC a través del USB.
   {
    while(!usb_enumerated())
    {
      output_high(PIN_B0);
      delay_ms(500);
      output_low(PIN_B0);
      output_high(PIN_B1);
      delay_ms(500);
      output_low(PIN_B1);
      output_high(PIN_B2);
      delay_ms(500);
      output_low(PIN_B2);
      output_high(PIN_B3);
      delay_ms(500);
      output_low(PIN_B3);
      output_high(PIN_B4);
      delay_ms(500);
      output_low(PIN_B4);
      output_high(PIN_B5);
      delay_ms(500);
      output_low(PIN_B5);
      output_high(PIN_B6);
      delay_ms(500);
      output_low(PIN_B6);
      output_high(PIN_B7);
      delay_ms(500);
      output_low(PIN_B7);
      }
    while(usb_enumerated())
    {
      if (usb_kbhit(1))
      {
        usb_get_packet(1, recbuf, Lenbuf);       
        if(recbuf[0]==127)
        {
           output_high(PIN_B2);
        }
        if(recbuf[0]==126)
        {
          output_low(PIN_B2);
        }
        if(recbuf[0]==125)
        {
          usb_put_packet(1,Conexion,3,USB_DTS_TOGGLE);
          output_high(PIN_B2);
        }
        if(recbuf[0]==124)
        {
          output_high(PIN_D6);
          output_low(PIN_D7);
        }
        if(recbuf[0]==123)
        {
          output_high(PIN_D7);
          output_low(PIN_D6);
        }
        if(recbuf[0]==122)
        {
          output_low(PIN_D7);
          output_low(PIN_D6);
        }
        if(recbuf[0]==121)
        {
          int16 muestra;
          int s;
          for(s=0;s<=64;s++)
          {
            muestra = read_adc();  //para leer el valor del adc0
            adc0=adc0+muestra;
            delay_ms(50);
          }
          adc0=adc0/65;
          sprintf(voltage, "%f", (float)adc0 * 0.01960784); //esta instruccion nos permite convertir  el valor del adc en un string.       
          usb_put_packet(1,voltage,4,USB_DTS_TOGGLE);//con esta instruccion mandamos el arrglo que se creo en la instruccion anterior
        }
        if(recbuf[0]==120)
        {
          char contador[6];
          sprintf(contador, "%06lu", x);
          usb_put_packet(1,contador,6,USB_DTS_TOGGLE);
        }
      }
    }
  }
}

Creo que el problema esta a la hora de configurar el ADC o depronto debido a las resistencias pull-up de RB0 y RB1, no se si tengo errores en esas partes.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #1 en: 09 de Abril de 2011, 23:14:49 »
  Pues según tu línea "set_tris_b(0b00000000)" estás configurando todo el puerto B como salida, inclusive RB0 y RB1
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #2 en: 09 de Abril de 2011, 23:22:05 »
Hola mauro2555, dando un ojeada rápida a tu código veo que en los fuses te haría falta este: NOPBADEN que configura al Puerto B como E/S digitales en el Reset.

Otro problema sería que #int_ext solo te maneja la interrupción externa de RB0.  Si quisieras manejar una interrupción externa por RB1 debes usar #int_ext1.

Finalmente, otro error sería lo que te acaba de mostrar AngelGris.

Saludos!

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #3 en: 09 de Abril de 2011, 23:35:33 »
Gracias por darle una ojeada al codigo, AngelGris tienes razon debe ser "set_tris_b(0b00000011)" asi lo tengo solo q hice una prueba antes de crear el tema y olvide arreglar eso, gracias por recordarmelo. bmb no sabia lo del NOPBADEN, tiene mucho sentido q obtenga esos voltajes si no he configurado ese fuse, voy a arreglar el codigo y probare inmediatamente, en unos minutos les cuento como me fue.

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #4 en: 10 de Abril de 2011, 01:46:07 »
Excelente, agregue el fuse NOPBADEN y ya no tengo voltajes en RB0 y RB1, sin embargo sigo sin obtener interrupciones, no se por q razon pareciera q no entra al #INT_EXT, si alguien encuentra algun error en el codigo me informan, gracias

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #5 en: 10 de Abril de 2011, 13:09:41 »
Hola mauro2555, revisando más detenidamente tu código veo que estás usando a RB0 y RB1 como salidas:

Código: C
  1. while(!usb_enumerated())
  2.     {
  3.       output_high(PIN_B0);
  4.       delay_ms(500);
  5.       output_low(PIN_B0);
  6.       output_high(PIN_B1);
  7.       delay_ms(500);
  8.       output_low(PIN_B1);
  9.       .
  10.       .
  11.       .

Como no tengo todas las librerías que usas para USB, hice un pequeño código para prender y apagar un LED usando exactamente el mismo encabezado y configuración que usas y eliminando todo tu código, la interrupción funciona bien:

Código: C
  1. #include <18F4550.h>
  2. #device adc=10
  3. #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOPBADEN,USBDIV,PLL5,CPUDIV1,VREGEN
  4. #use delay(clock=48000000)
  5. #use fast_io(b)
  6.  
  7. #Byte PortB = 0xF81
  8.  
  9. int1 x = false;
  10.  
  11. #INT_EXT
  12. void prueba()
  13. {    
  14.    x++;
  15. }
  16.  
  17. void main()
  18. {
  19.    port_b_pullups(false);
  20.    setup_adc_ports(AN0|VSS_VDD);//para escoger el canal cero y el vss y vdd
  21.    SETUP_ADC(ADC_CLOCK_INTERNAL);//la frecuencia de muestreo es 2-6us
  22.    SET_ADC_CHANNEL(0);
  23.    delay_ms(333);
  24.    disable_interrupts(Int_Ext);
  25.    disable_interrupts(GLOBAL);
  26.    
  27.    Ext_Int_Edge(L_TO_H);        // Inicialmente detectar interrupcion por flanco de subida.
  28.    Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa a traves de RB0.
  29.    Enable_Interrupts(GLOBAL);   // Interrupciones Generales Activadas.
  30.    Set_Tris_B(0b00000011);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
  31.  
  32.    while(true)
  33.    {
  34.       if(x)
  35.          output_high(PIN_C2);
  36.       else
  37.          output_low(PIN_C2);
  38.    }
  39. }

Como ves, solo le he adicionado la directiva #device adc=10 para que la captura ADC sea de 10 bits.  Te anexo el código y la prueba en proteus.

Saludos!

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #6 en: 10 de Abril de 2011, 21:20:25 »
bmb ya corregi los errores, he probado tu codigo y no responde la interrupcion, es muy extraño por q es un codigo sencillo pero nada. Quisiera saber q version utilizas de Proteus y CCS. Yo estoy trabajando en CCS 4.104 y Proteus 7.6, las pruebas USB las realizo en XP debido a la libreria JpicUsb de java, pero las pruebas de ADC e interrupciones las realizo en Windows 7 de 64x. Saludos.

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #7 en: 10 de Abril de 2011, 23:38:47 »
bmb gracias por tu aporte!!! despues de varias pruebas he conseguido q me funcionen las interrupciones en RB0 y RB1, hice los arreglos q ustedes me aconsejaron al codigo, luego he conectado resistencias pullups externas al micro en las entradas a RB0 y RB1 y me ha detectado las interrupciones. Me base en el esquema de protesus q subiste, gracias por quitarme un dolor de cabeza jeje. Exitos a todos..

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #8 en: 11 de Abril de 2011, 08:29:13 »
Hola mauro2555, me alegra mucho que puedas seguir avanzando con tu proyecto!

Saludos!

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #9 en: 13 de Abril de 2011, 22:09:37 »
hola a todos, he seguido con mi proyecto, pero ahora se me ha presentado otro inconveniente. Necesito guardar la cantidad de interrupciones del encoder en la eeprom externa, el inconveniente es q necesito almacenar el dato cada vez q se realice la interrupcion. Entonces lo q hice fue incluir en la funcion de la interrupcion el comando para guardar el dato en la eeprom, pero al programar el pic y probarlo me doy cuenta q no inicia, encontre q cuando compilo el CCS con el codigo aparece un warning de escritura en la eeprom, el codigo de la interrupcion es el siguiente:

#INT_EXT
void prueba()
{     
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
   {
       Ext_Int_Edge(H_TO_L);    // entonces activar la siguiente interrupción por flanco de bajada.
       If (Bit_Test(PortB, 1))  // Si RB1 está a 1,
       {
         x++;                      // entonces incrementar una unidad el valor de X.
       }
   }
   Else                         // Si RB0 se ha puesto a 0 (flanco de bajada),
   {
       Ext_Int_Edge(L_TO_H);    // entonces activar la siguiente interrupción por flanco de subida.
       If (Bit_Test(PortB, 1))  // Si RB1 está 1,
       {
           x--;                 // entonces decrementar una unidad el valor de X.
       }
   }
   write_int16_ext_eeprom(0,x);//guardo el valor de X en la eeprom
}

He intentado de muchas formas pero no hallo la manera de guardar en la eeprom el valor de X cada vez q se incremente o decremente. q me pueden aconsejar, donde puedo poner la linea de escritura en la eeprom teniendo en cuenta q haya cambiado el valor de X???

Helppp...

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #10 en: 13 de Abril de 2011, 22:56:20 »
Hola mauro1555, cual eeprom estás usando?

Saludos!

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #11 en: 13 de Abril de 2011, 23:37:21 »
Hola bmb, la eeprom es un FM24C512, ahi te envio la pag del fabricante donde se encuentra el datasheet.

http://www.ramtron.com/products/nonvolatile-memory/serial-product.aspx?id=5

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #12 en: 14 de Abril de 2011, 09:07:52 »
Hola mauro2555 , le tienes las resistencias pullup en los pines SDA y SCL?  En que pines los definiste? Tienes en el encabezado esto?

Citar
#include <24512.C>
#include <external_eeprom.c>

Saludos!

Desconectado mauro2555

  • PIC10
  • *
  • Mensajes: 18
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #13 en: 14 de Abril de 2011, 17:49:51 »
si tengo las resistencias y los include, estoy trabajando SDA=D0 y SCL=D1. He hecho pruebas con la eeprom y la escritura y lectura es exitosa, el problema es q necesito escribir un dato cada vez q el encoder me active la interrupcion. Otra cosa es q estoy enviando desde java 5 caracteres por ejemplo "43500" y consigo q lleguen al pic, el problema es q quiero almacenar ese valor en la eeprom pero como int16 y no he conseguido convertir esos 5 char en int16, sabes como hacerlo??

gracias por la ayuda...

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Ayuda con interruciones en RB0 y RB1
« Respuesta #14 en: 14 de Abril de 2011, 18:22:30 »
Utiliza atoi, atol algo por el estilo. Usa la ayuda para informarte cual corresponde, dado que por lo visto los 43500 van en ascii.


Saludos!
No contesto mensajes privados, las consultas en el foro


 

anything