Autor Tema: Problemas con el CAD por interrupción de tres canales con pic18f4550  (Leído 3458 veces)

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

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Buenas compañeros,

Estoy realizando un proyecto un poco complejo que utilizaba 2 canales utilizando el CAD por interrupción. El problema surgió cuando quise utilizar otro canal y el programa me hacía cosas raras (asigna el valor del converor a otro canal que no es el suyo)... lo que he realizado con ayuda de azicuetano es hacer un código muy simple utilizando el CAD por interrupción y comprobar si funciona.

He cogido uno del foro (de Redpic), lo que pretendo es realizar conversiones por las patillas AN0, AN1, AN2 del pic18f4550 para luego enviarlas por la rs232. Las conversiones las hago por interrupción del AD.

Aquí os pego el código

Código: C++
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //
  5. // Ubicación: C:\Archivos de programa\PICC\Projects\
  6. //          
  7. //
  8. // Software: CS PCM Version 4.073
  9. //
  10. // Propósito:  
  11. //            
  12. //
  13. // Técnica Empleada:
  14. //
  15. //
  16. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. #include <18f4550.h>       // Definiciones del PIC 16F877A
  19. #device  adc=10         // Resolución 10 BITS
  20. #device ICD=TRUE        // Habilitamos el modo IDC
  21. #fuses   HSPLL,PLL5,CPUDIV1,USBDIV,MCLR,NOPBADEN,NOVREGEN
  22. #fuses   NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP,DEBUG
  23. #use delay(clock=48000000) // Oscilador a 48 Mhz
  24.  
  25. //##############################################################################
  26. // El compilador realiza las funciones de IO sin programar el registro dirección
  27. // ocupa menos memoria de programa en el PIC.
  28. //##############################################################################
  29.  
  30. #use standard_io(b)
  31.  
  32. #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
  33. // parity=N (no paridad), parity=E(Paridad par), parity=O (paridad impar)
  34. // RS232 Estándar xmit salida de datos, rcv entrada de datos
  35.  
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////
  38. //                            VARIABLES EN RAM                                //
  39. ////////////////////////////////////////////////////////////////////////////////
  40. float  Canal0=0x00;
  41. float  Canal1=0x00;
  42. float  Canal2=0x00;
  43. int   canal=0;
  44. char Keypress=' ';
  45.  
  46. ////////////////////////////////////////////////////////////////////////////////
  47. //                     DECLARACIÓN DE FUNCIONES                               //
  48. ////////////////////////////////////////////////////////////////////////////////
  49. void toma_adc_y_transmite(void); // pilla el valor de ADC y lo envia por RS232
  50.  
  51. //##############################################################################
  52. //#
  53. //#                  Interrupción recepcición serie USART
  54. //#
  55. //##############################################################################
  56.  
  57. #int_rda
  58. void rda_isr() {
  59.  
  60.    Keypress=0x00;
  61.    if(kbhit()){
  62.       Keypress=getc();
  63.    }
  64. }
  65.  
  66. //##############################################################################
  67. //#
  68. //#              Interrupción encargada del conversor AD
  69. //#
  70. //##############################################################################
  71.  
  72. # INT_AD
  73. void AD_isr()
  74. {
  75.    if (canal==0){
  76.  //     set_adc_channel(canal);
  77. //      delay_ms(1);
  78.       Canal0=Read_ADC(ADC_READ_ONLY);
  79.       delay_ms(1);
  80.       Read_ADC(ADC_START_ONLY);  //inicia nueva conversion.
  81.   //    ++canal;
  82.    }
  83.    if (canal==1){
  84. //      set_adc_channel(canal);
  85. //      delay_ms(1);
  86.       Canal1=Read_ADC(ADC_READ_ONLY);
  87.       delay_ms(1);
  88.       Read_ADC(ADC_START_ONLY);   //inicia nueva conversion.
  89.       ++canal;
  90.    }
  91.    if (canal==2){
  92.  //     set_adc_channel(canal);
  93.  //     delay_ms(1);
  94.       Canal2=Read_ADC(ADC_READ_ONLY);
  95.       delay_ms(1);
  96.       Read_ADC(ADC_START_ONLY);   //inicia nueva conversion.
  97.  //     ++canal;
  98.   }
  99.  
  100.  
  101. //  if (canal>2) {
  102. //  canal=0;
  103.  
  104.  // }
  105.  // canal++;
  106. }
  107.  
  108.  
  109. ////////////////////////////////////////////////////////////////////////////////
  110. //                       DESARROLO DE FUNCIONES                               //
  111. ////////////////////////////////////////////////////////////////////////////////
  112.  
  113. void toma_adc_y_transmite(void){
  114.    disable_interrupts(int_ad);
  115.  
  116.    printf(" Canal0= %Lf Canal1= %Lf Canal2= %Lf\r\n",Canal0,Canal1,Canal2);
  117.  
  118.    enable_interrupts(int_AD);
  119. //   Read_ADC(ADC_START_ONLY);
  120. }
  121.  
  122. ////////////////////////////////////////////////////////////////////////////////
  123. //                  PROGRAMA PRINCIPAL VOID MAIN()                            //
  124. ////////////////////////////////////////////////////////////////////////////////
  125.  
  126. void main() {
  127.  
  128.    setup_adc_ports( AN0_TO_AN2 || VSS_VDD ); // configuración del CAD
  129.    setup_adc( ADC_CLOCK_DIV_64 );
  130.    
  131.    output_low(PIN_B5);
  132.  
  133.    enable_interrupts(int_rda);
  134.    enable_interrupts(int_ad);
  135.    enable_interrupts(global);
  136.  
  137.    canal=0;
  138.    Read_ADC(ADC_START_ONLY);
  139.  
  140.    printf("\n\ AD - LM35a - Monitor\n\n");
  141.  
  142.    do {
  143.  
  144.       if(Keypress!=0x00){
  145.  
  146.          switch(Keypress){
  147.          
  148.             case 't': toma_adc_y_transmite();
  149.                       break;
  150.             case '0': output_low(PIN_B5);
  151.                       printf(" 0 - Calentador OFF\n");
  152.                       break;
  153.             case '1': output_high(PIN_B5);
  154.                       printf(" 1 - Calentador ON\n");
  155.                       break;
  156.          }
  157.  
  158.          Keypress=0x00;
  159.       }
  160.      
  161.       delay_ms(10);
  162.       canal=0;
  163.       set_adc_channel(canal);
  164.       delay_ms(10);
  165.       canal=1;
  166.       set_adc_channel(canal);
  167.       delay_ms(10);
  168.       canal=2;
  169.       set_adc_channel(canal);
  170.       delay_ms(10);
  171.  
  172.  
  173.    } while (TRUE);
  174.  
  175. }

1.- El código está programado con CCS versión 4.073 con un pic18f4550.
2.- Si podéis mejorar el código os lo agradecería.
« Última modificación: 27 de Mayo de 2008, 03:59:43 por umalrovi »
Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #1 en: 27 de Mayo de 2008, 06:00:23 »
¿Alguién ha hecho un programa que utilice el CAD por interrupción con mas de una canal?

Con un canal consigo que funcione pero cuando quiero ver más de uno no me lo hace correcta,ente.

Muchas gracias de antemano, estoy muy agobiado y muy apretado de tiempo.

Cualquier aporte se agradece he probado y rebuscado.
Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #2 en: 27 de Mayo de 2008, 06:19:12 »
Umalrovi, yo solo he hecho un par de pruebas con el AD y mi experiencia es corta, escasa y poco significativa. He estado leyendo el datasheet del 18F4550 pero no me aclaro. También he buscado en la documentación de as AppNotes de Microchip pero peor aún. Lo siento pero esta vez creo que no voy a ser de mucha ayuda.  :?
« Última modificación: 27 de Mayo de 2008, 09:42:48 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #3 en: 27 de Mayo de 2008, 06:59:55 »
Gracias por contestar Redpic, aún así con otro microcontrolador tienes algún ejemplo de como usar el CAD con interrupción con más de un canal?


GRACIAS!!!

Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado stk500

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4919
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #4 en: 27 de Mayo de 2008, 07:01:53 »
bueno aqui veo un Ej. del forum de CCS y lo veo algo diferente, no soy experto pero aqui te dejo un link, quizas te sirva de Ayudas
http://www.ccsinfo.com/forum/viewtopic.php?t=34641&highlight=adc+channel+config



Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #5 en: 27 de Mayo de 2008, 10:31:33 »
Solucionado.

Os pego el programa resuelto. Este programa envía por la RS232 los valores del CAD por interrupción de los tres canales.

Decidme que os parece aparentemente lo hace bien y lo he comprobado.

Código: C++
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //
  5. // Ubicación: C:\Archivos de programa\PICC\Projects\
  6. //          
  7. //
  8. // Software: CS PCM Version 4.073
  9. //
  10. // Propósito:  
  11. //            
  12. //
  13. // Técnica Empleada:
  14. //
  15. //
  16. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. #include <18f4550.h>       // Definiciones del PIC 16F877A
  19. #device  adc=10         // Resolución 10 BITS
  20. #device ICD=TRUE        // Habilitamos el modo IDC
  21. #fuses   HSPLL,PLL5,CPUDIV1,USBDIV,MCLR,NOPBADEN,NOVREGEN
  22. #fuses   NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP,DEBUG
  23. #use delay(clock=48000000) // Oscilador a 48 Mhz
  24.  
  25. //##############################################################################
  26. // El compilador realiza las funciones de IO sin programar el registro dirección
  27. // ocupa menos memoria de programa en el PIC.
  28. //##############################################################################
  29.  
  30. #use standard_io(b)
  31.  
  32. #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
  33. // parity=N (no paridad), parity=E(Paridad par), parity=O (paridad impar)
  34. // RS232 Estándar xmit salida de datos, rcv entrada de datos
  35.  
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////
  38. //                            VARIABLES EN RAM                                //
  39. ////////////////////////////////////////////////////////////////////////////////
  40. float  Canal0=0x00;
  41. float  Canal1=0x00;
  42. float  Canal2=0x00;
  43. int   canal=0;
  44.  
  45. static   int1  AdcDone;
  46.  
  47.  
  48. char Keypress=' ';
  49.  
  50. ////////////////////////////////////////////////////////////////////////////////
  51. //                     DECLARACIÓN DE FUNCIONES                               //
  52. ////////////////////////////////////////////////////////////////////////////////
  53. void toma_adc_y_transmite(void); // pilla el valor de ADC y lo envia por RS232
  54.  
  55. //##############################################################################
  56. //#
  57. //#                  Interrupción recepcición serie USART
  58. //#
  59. //##############################################################################
  60.  
  61. #int_rda
  62. void rda_isr() {
  63.  
  64.    Keypress=0x00;
  65.    if(kbhit()){
  66.       Keypress=getc();
  67.    }
  68. }
  69.  
  70. //##############################################################################
  71. //#
  72. //#              Interrupción encargada del conversor AD
  73. //#
  74. //##############################################################################
  75.  
  76. # INT_AD
  77. void AD_isr()
  78. {
  79.    AdcDone = 1;  //Activa el flag cuando termina la conversión
  80. }
  81.  
  82. ////////////////////////////////////////////////////////////////////////////////
  83. //                       DESARROLO DE FUNCIONES                               //
  84. ////////////////////////////////////////////////////////////////////////////////
  85.  
  86. void toma_adc_y_transmite(void){
  87.    disable_interrupts(int_ad);
  88.    printf(" Canal0= %Lf Canal1= %Lf Canal2= %Lf\r\n",Canal0,Canal1,Canal2);
  89.    enable_interrupts(int_ad);
  90. }
  91.  
  92. ////////////////////////////////////////////////////////////////////////////////
  93. //                  PROGRAMA PRINCIPAL VOID MAIN()                            //
  94. ////////////////////////////////////////////////////////////////////////////////
  95.  
  96. void main() {
  97.  
  98.    setup_adc_ports( ALL_ANALOG || VSS_VDD ); // configuración del CAD
  99.    setup_adc( ADC_CLOCK_DIV_64 );
  100.    
  101.    output_low(PIN_B5);
  102.  
  103.    enable_interrupts(int_rda);
  104.    enable_interrupts(int_ad);
  105.    enable_interrupts(global);
  106.  
  107.  
  108.    delay_ms(1);
  109.    set_adc_channel(0);
  110.    delay_ms(1);
  111.    Read_ADC(ADC_START_ONLY);
  112.  
  113.    printf("\n\ AD - LM35a - Monitor\n\n");
  114.  
  115.    do {
  116.  
  117.       if(Keypress!=0x00){
  118.  
  119.          switch(Keypress){
  120.          
  121.             case 't':
  122.                       toma_adc_y_transmite();
  123.                       break;
  124.             case '0':
  125.                       printf(" 0 - Calentador OFF\n");
  126.                       break;
  127.             case '1':
  128.                       printf(" 1 - Calentador ON\n");
  129.                       break;
  130.          }
  131.  
  132.          Keypress=0x00;
  133.       }            
  134.       set_adc_channel(0);
  135.       delay_ms(1);
  136.       AdcDone=0;
  137.       while(AdcDone==0){
  138.          Canal0=read_adc();
  139.       }
  140.       set_adc_channel(1);
  141.       delay_ms(1);
  142.       AdcDone=0;
  143.       while(AdcDone==0){
  144.          Canal1=read_adc();
  145.       }
  146.       set_adc_channel(2);
  147.       delay_ms(1);
  148.       AdcDone=0;
  149.       while(AdcDone==0){
  150.          Canal2=read_adc();
  151.       }      
  152.    } while (TRUE);
  153.  
  154. }

Muchas gracias.

Si veis algo que no es correcto os agradecería comentarios.
Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #6 en: 27 de Mayo de 2008, 10:49:46 »
He sustituido las funciones:
read_adc ();  por   ---->  read_adc(adc_read_only)
He añadido en la interrupción:
Read_adc(adc_start_only);
He definido las variables Canal0, Canal1, Canal2 como unsigned int16.

Faltaría ajustar los tiempo de conversión que luego postearé. Os pego el código a ver que os parece:

Código: C++
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //
  5. // Ubicación: C:\Archivos de programa\PICC\Projects\
  6. //          
  7. //
  8. // Software: CS PCM Version 4.073
  9. //
  10. // Propósito:  
  11. //            
  12. //
  13. // Técnica Empleada:
  14. //
  15. //
  16. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. #include <18f4550.h>       // Definiciones del PIC 16F877A
  19. #device  adc=10         // Resolución 10 BITS
  20. #device ICD=TRUE        // Habilitamos el modo IDC
  21. #fuses   HSPLL,PLL5,CPUDIV1,USBDIV,MCLR,NOPBADEN,NOVREGEN
  22. #fuses   NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP,DEBUG
  23. #use delay(clock=48000000) // Oscilador a 48 Mhz
  24.  
  25. //##############################################################################
  26. // El compilador realiza las funciones de IO sin programar el registro dirección
  27. // ocupa menos memoria de programa en el PIC.
  28. //##############################################################################
  29.  
  30. #use standard_io(b)
  31.  
  32. #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
  33. // parity=N (no paridad), parity=E(Paridad par), parity=O (paridad impar)
  34. // RS232 Estándar xmit salida de datos, rcv entrada de datos
  35.  
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////
  38. //                            VARIABLES EN RAM                                //
  39. ////////////////////////////////////////////////////////////////////////////////
  40. unsigned int16  Canal0=0x00;
  41. unsigned int16  Canal1=0x00;
  42. unsigned int16  Canal2=0x00;
  43. static   int1  AdcDone;
  44.  
  45.  
  46. char Keypress=' ';
  47.  
  48. ////////////////////////////////////////////////////////////////////////////////
  49. //                     DECLARACIÓN DE FUNCIONES                               //
  50. ////////////////////////////////////////////////////////////////////////////////
  51. void toma_adc_y_transmite(void); // pilla el valor de ADC y lo envia por RS232
  52.  
  53. //##############################################################################
  54. //#
  55. //#                  Interrupción recepcición serie USART
  56. //#
  57. //##############################################################################
  58.  
  59. #int_rda
  60. void rda_isr() {
  61.  
  62.    Keypress=0x00;
  63.    if(kbhit()){
  64.       Keypress=getc();
  65.    }
  66. }
  67.  
  68. //##############################################################################
  69. //#
  70. //#              Interrupción encargada del conversor AD
  71. //#
  72. //##############################################################################
  73.  
  74. # INT_AD
  75. void AD_isr()
  76. {
  77.    AdcDone = 1;  //Activa el flag cuando termina la conversión
  78.    Read_adc(adc_start_only);
  79. }
  80.  
  81. ////////////////////////////////////////////////////////////////////////////////
  82. //                       DESARROLO DE FUNCIONES                               //
  83. ////////////////////////////////////////////////////////////////////////////////
  84.  
  85. void toma_adc_y_transmite(void){
  86.    disable_interrupts(int_ad);
  87.    printf(" Canal0= %Ld Canal1= %Ld Canal2= %Ld\r\n",Canal0,Canal1,Canal2);
  88.    enable_interrupts(int_ad);
  89. }
  90.  
  91. ////////////////////////////////////////////////////////////////////////////////
  92. //                  PROGRAMA PRINCIPAL VOID MAIN()                            //
  93. ////////////////////////////////////////////////////////////////////////////////
  94.  
  95. void main() {
  96.  
  97.    setup_adc_ports( ALL_ANALOG || VSS_VDD ); // configuración del CAD
  98.    setup_adc( ADC_CLOCK_DIV_64 );
  99.    
  100.    output_low(PIN_B5);
  101.  
  102.    enable_interrupts(int_rda);
  103.    enable_interrupts(int_ad);
  104.    enable_interrupts(global);
  105.  
  106.  
  107.    delay_ms(1);
  108.    set_adc_channel(0);
  109.    delay_ms(1);
  110.    Read_ADC(ADC_START_ONLY);
  111.  
  112.    printf("\n\ AD - LM35a - Monitor\r\n\n");
  113.  
  114.    do {
  115.  
  116.       if(Keypress!=0x00){
  117.  
  118.          switch(Keypress){
  119.          
  120.             case 't':
  121.                       toma_adc_y_transmite();
  122.                       break;
  123.             case '0':
  124.                       printf(" 0 - Calentador OFF\n");
  125.                       break;
  126.             case '1':
  127.                       printf(" 1 - Calentador ON\n");
  128.                       break;
  129.          }
  130.  
  131.          Keypress=0x00;
  132.       }            
  133.       set_adc_channel(0);
  134.       delay_ms(1);
  135.       AdcDone=0;
  136.       while(AdcDone==0){
  137.          delay_ms(1);
  138.          Canal0=read_adc(adc_read_only);
  139.          delay_ms(1);
  140.       }
  141.       set_adc_channel(1);
  142.       delay_ms(1);
  143.       AdcDone=0;
  144.       while(AdcDone==0){
  145.          delay_ms(1);
  146.          Canal1=read_adc(adc_read_only);
  147.          delay_ms(1);
  148.       }
  149.       set_adc_channel(2);
  150.       delay_ms(1);
  151.       AdcDone=0;
  152.       while(AdcDone==0){
  153.          delay_ms(1);
  154.          Canal2=read_adc(adc_read_only);
  155.          delay_ms(1);
  156.       }      
  157.    } while (TRUE);
  158. }

Saludos
« Última modificación: 27 de Mayo de 2008, 11:06:48 por umalrovi »
Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #7 en: 27 de Mayo de 2008, 12:07:08 »
umalrovi recuerda borrar estas tres ultimas lineas que estan sobrando debajo del enable interrupts(global) (los 2 delay y el set adc)



Saludos
Código: C++
  1. enable_interrupts(global);
  2.    delay_ms(1);  
  3.    set_adc_channel(0);
  4.    delay_ms(1);


jeje gracias umal, muy facil me siento un idiota jaja :D
« Última modificación: 27 de Mayo de 2008, 12:16:16 por Arbolito »
Existo, aunque pienses que no pienso

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #8 en: 27 de Mayo de 2008, 12:21:01 »
Código: C++
  1. [code=cpp]////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //
  5. // Ubicación: C:\Archivos de programa\PICC\Projects\
  6. //          
  7. //
  8. // Software: CS PCM Version 4.073
  9. //
  10. // Propósito:  
  11. //            
  12. //
  13. // Técnica Empleada:
  14. //
  15. //
  16. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. #include <18f4550.h>       // Definiciones del PIC 16F877A
  19. #device  adc=10         // Resolución 10 BITS
  20. #device ICD=TRUE        // Habilitamos el modo IDC
  21. #fuses   HSPLL,PLL5,CPUDIV1,USBDIV,MCLR,NOPBADEN,NOVREGEN
  22. #fuses   NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP,DEBUG
  23. #use delay(clock=48000000) // Oscilador a 48 Mhz
  24.  
  25. //##############################################################################
  26. // El compilador realiza las funciones de IO sin programar el registro dirección
  27. // ocupa menos memoria de programa en el PIC.
  28. //##############################################################################
  29.  
  30. #use standard_io(b)
  31.  
  32. #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
  33. // parity=N (no paridad), parity=E(Paridad par), parity=O (paridad impar)
  34. // RS232 Estándar xmit salida de datos, rcv entrada de datos
  35.  
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////
  38. //                            VARIABLES EN RAM                                //
  39. ////////////////////////////////////////////////////////////////////////////////
  40. unsigned int16  Canal0=0x00;
  41. unsigned int16  Canal1=0x00;
  42. unsigned int16  Canal2=0x00;
  43. static   int1  AdcDone;
  44.  
  45.  
  46. char Keypress=' ';
  47.  
  48. ////////////////////////////////////////////////////////////////////////////////
  49. //                     DECLARACIÓN DE FUNCIONES                               //
  50. ////////////////////////////////////////////////////////////////////////////////
  51. void toma_adc_y_transmite(void); // pilla el valor de ADC y lo envia por RS232
  52.  
  53. //##############################################################################
  54. //#
  55. //#                  Interrupción recepcición serie USART
  56. //#
  57. //##############################################################################
  58.  
  59. #int_rda
  60. void rda_isr() {
  61.  
  62.    Keypress=0x00;
  63.    if(kbhit()){
  64.       Keypress=getc();
  65.    }
  66. }
  67.  
  68. //##############################################################################
  69. //#
  70. //#              Interrupción encargada del conversor AD
  71. //#
  72. //##############################################################################
  73.  
  74. # INT_AD
  75. void AD_isr()
  76. {
  77.    AdcDone = 1;  //Activa el flag cuando termina la conversión
  78.    Read_adc(adc_start_only);
  79. }
  80.  
  81. ////////////////////////////////////////////////////////////////////////////////
  82. //                       DESARROLO DE FUNCIONES                               //
  83. ////////////////////////////////////////////////////////////////////////////////
  84.  
  85. void toma_adc_y_transmite(void){
  86.    disable_interrupts(int_ad);
  87.    printf(" Canal0= %Ld Canal1= %Ld Canal2= %Ld\r\n",Canal0,Canal1,Canal2);
  88.    enable_interrupts(int_ad);
  89. }
  90.  
  91. ////////////////////////////////////////////////////////////////////////////////
  92. //                  PROGRAMA PRINCIPAL VOID MAIN()                            //
  93. ////////////////////////////////////////////////////////////////////////////////
  94.  
  95. void main() {
  96.  
  97.    setup_adc_ports( ALL_ANALOG || VSS_VDD ); // configuración del CAD
  98.    setup_adc( ADC_CLOCK_DIV_64 );
  99.    
  100.    output_low(PIN_B5);
  101.  
  102.    enable_interrupts(int_rda);
  103.    enable_interrupts(int_ad);
  104.    enable_interrupts(global);
  105.  
  106.  
  107.       Read_ADC(ADC_START_ONLY);
  108.  
  109.    printf("\n\ AD - LM35a - Monitor\r\n\n");
  110.  
  111.    do {
  112.  
  113.       if(Keypress!=0x00){
  114.  
  115.          switch(Keypress){
  116.          
  117.             case 't':
  118.                       toma_adc_y_transmite();
  119.                       break;
  120.             case '0':
  121.                       printf(" 0 - Calentador OFF\n");
  122.                       break;
  123.             case '1':
  124.                       printf(" 1 - Calentador ON\n");
  125.                       break;
  126.          }
  127.  
  128.          Keypress=0x00;
  129.       }            
  130.       set_adc_channel(0);
  131.       delay_ms(1);
  132.       AdcDone=0;
  133.       while(AdcDone==0){
  134.          delay_ms(1);
  135.          Canal0=read_adc(adc_read_only);
  136.          delay_ms(1);
  137.       }
  138.       set_adc_channel(1);
  139.       delay_ms(1);
  140.       AdcDone=0;
  141.       while(AdcDone==0){
  142.          delay_ms(1);
  143.          Canal1=read_adc(adc_read_only);
  144.          delay_ms(1);
  145.       }
  146.       set_adc_channel(2);
  147.       delay_ms(1);
  148.       AdcDone=0;
  149.       while(AdcDone==0){
  150.          delay_ms(1);
  151.          Canal2=read_adc(adc_read_only);
  152.          delay_ms(1);
  153.       }      
  154.    } while (TRUE);
  155. }

Bueno y ya de atrevido lo corregi yo.[/code]
« Última modificación: 27 de Mayo de 2008, 12:23:29 por Arbolito »
Existo, aunque pienses que no pienso

Desconectado Gonzalo_BlackHawk

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 519
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #9 en: 27 de Mayo de 2008, 14:25:44 »
Hola a todos. Siento ser el que siempre trae las malas noticias sobre el ADC  :mrgreen: :mrgreen:, los que me conocen saben que no lo hago de malvado. Me he tomado el atrevimiento de corregir tu programa, pero primero revisemos lo que ha mi entender no es correcto:
 
Código: [Seleccionar]
//##############################################################################
// El compilador realiza las funciones de IO sin programar el registro dirección
// ocupa menos memoria de programa en el PIC.
//##############################################################################

#use standard_io(b)

Justamente el standard_io le dice al compilador que haga lo contrario a lo del comentario, que programe el registro TRIS antes de cada acción I/O, sin importar si ya lo hizo en un paso anterior o si no necesita realmente cambiar la dirección del puerto. Este es el metodo de direccionamiento menos eficiente, pero el mas facil de implementar. Si quieres lograr lo del comentario puedes utlizar fast_io, pero tendras que configurar tu mismo los puertos mediante la instrucción set_tris. El 18F4550 no anda precisamente escaso de memoria asi que por el momento te diria que sigas utilizando el standard_io.

Código: [Seleccionar]
static   int1  AdcDone;
AdcDone no necesita ser estatica pues ya es global, esto no es critico, solo lo comento a modo de información.

Código: [Seleccionar]
#INT_AD
void AD_isr()
{
  AdcDone = 1;  //Activa el flag cuando termina la conversión
  Read_adc(adc_start_only);
}

La interrupcion AD se produce en pocas palabras cuando el ADC termino de convertir la tensión, asi que aqui debes leer el valor que has convertido y no empezar con otra conversión, coloca el código así:

Código: [Seleccionar]
#INT_AD
void AD_isr()
{
  AdcDone = 1;  //Activa el flag cuando termina la conversión
  Read_adc(adc_read_only); //Lee el útlimo valor digital convertido por el ADC.
}

Bueno, ando un poco corto de tiempo, asi que no podre terminar de exponer mis observaciones (Para suerte de algunos seguramente :D :D ). En realidad creo que habria que reorganizar un poco el código para hacerlo más eficiente, asi que volvere
con el código algo renovado y asi podremos discutir sobre el tema. Ahora me espera el gimnasio y el gimnasio es sagrado, incluso más que los PIC :-/ :-/.

Saludos a todos.

"Siempre piensa si el jugo vale la exprimida..."

"La muerte esta tan segura de vencer que nos da toda una vida de ventaja."

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: Problemas con el CAD por interrupción de tres canales con pic18f4550
« Respuesta #10 en: 28 de Mayo de 2008, 07:56:22 »
En primer lugar datr las gracias Gonzalo_BlackHawk por tu contestación y a todos los demás también. Las críticas son buenas  desde mi punto de vista con ellas aprendemos muchos TODOS.

Esperamos tu 2º Round en este post, Gracias por tu contestación.

A.
Aplicaciones Electrónicas
http://www.neoingenia.com/