Autor Tema: Problema PWM y ADC con 16F873A  (Leído 6812 veces)

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

Desconectado MaRveLsHiNe

  • PIC10
  • *
  • Mensajes: 4
Problema PWM y ADC con 16F873A
« en: 15 de Enero de 2010, 19:35:02 »
Lo que me propongo es variar la velocidad de un motor cc mediante PWM utilizando el CCP1 y variando el duty cycle de éste mediante la lectura de un potenciómetro conectado al puerto A0, el problema aparece cuando, aun leyendo correctamente el valor de la entrada analógica, el CCP1 no responde a la variación del ciclo de trabajo, ésto programando en ASM, ya que en C directamente no hace nada! Les dejo el código y agradezco su ayuda.

Código: C
  1. #include <16F873A.h>
  2. #device adc=8
  3.  
  4. #FUSES NOWDT                    //No Watch Dog Timer
  5. #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
  6. #FUSES PUT                      //Power Up Timer
  7. #FUSES NOPROTECT                //Code not protected from reading
  8. #FUSES NODEBUG                  //No Debug mode for ICD
  9. #FUSES NOBROWNOUT               //No brownout reset
  10. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  11. #FUSES NOCPD                    //No EE protection
  12. #FUSES NOWRT                    //Program memory not write protected
  13.  
  14. #use delay(clock=8000000)
  15. #use fast_io (C)
  16.  
  17.  
  18.  
  19. void main()
  20. {
  21.  
  22. int a;
  23.  
  24.    setup_adc_ports(AN0);
  25.    setup_adc(ADC_CLOCK_DIV_64);
  26.    set_adc_channel(0);
  27.    setup_spi(SPI_SS_DISABLED);
  28.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  29.    setup_timer_1(T1_DISABLED);
  30.    setup_timer_2(T2_DIV_BY_16,249,1);
  31.    setup_ccp1(CCP_PWM);
  32.    //set_pwm1_duty(512);
  33.    setup_comparator(NC_NC_NC_NC);
  34.    setup_vref(FALSE);
  35.    
  36.      SET_TRIS_A(0x03);
  37.      SET_TRIS_C(0x00);
  38.      
  39.      
  40.    
  41.    
  42. While (TRUE){
  43. delay_us(100);
  44. a = read_adc();
  45. set_pwm1_duty(a);
  46.    }
  47.  
  48. }


Código: ASM
  1. LIST            P=16F873
  2.         INCLUDE         <P16F873A.INC>
  3.         __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF
  4.         CBLOCK  0x20
  5.         ENDC
  6.        
  7.  ORG 0
  8.        
  9. Inicio
  10.         bcf STATUS,RP0
  11.         bcf STATUS,RP1                  ;Banco 0
  12.         movlw b'10000011'      
  13.         movwf ADCON0                    ;Canal 0 del ADC, Conversión en 64/Fosc
  14.         movlw 0x4F     
  15.         movwf CCP1CON           ;PWM CCP1
  16.         movlw 0x80
  17.         movwf CCPR1L                    ;Ciclo de trabajo
  18.         movlw b'00000110'
  19.         movwf T2CON                     ;Timer 2 activado, prescaler 16
  20.         bsf STATUS,RP0                  ;Banco 1
  21.         bcf STATUS,RP1
  22.         movlw b'01001110'      
  23.         movwf ADCON1            ;AN0 entrada analogica, resto del puerto digital
  24.         movlw b'00000001'      
  25.         movwf TRISA                     ;AN0 entrada, resto del puerto salidas
  26.         movlw b'11111001'
  27.         movwf TRISC                     ;CCPx como salidas
  28.         movlw 0x7F
  29.         movwf PR2                       ;Período PWM
  30.         bcf STATUS,RP0
  31.         bcf STATUS,RP1                  ;Banco 0
  32.                                                
  33.                
  34. ;Conversión ADC Y variación Duty cycle PWM
  35.        
  36. PWMADC 
  37.         call Retardo_1ms
  38.         bsf ADCON0,GO
  39. AD     
  40.         btfsc ADCON0,GO
  41.         goto AD
  42.         movfw ADRESH   
  43.         movwf CCPR1L
  44.         nop
  45.         goto PWMADC
  46.        
  47.         INCLUDE <RETARDOS.INC>
  48.         END

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problema PWM y ADC con 16F873A
« Respuesta #1 en: 16 de Enero de 2010, 04:26:46 »
¿Lo vas a intentar en C o seguirás con ASM?

Si es el primer caso intenta eliminar del main todos los "setup" que no utilices, por ejemplo el del SPI, el del comparador...
A veces provocan efectos indeseados.

¿Sabes si el programa está corriendo?. Una buena costumbre es poner un led al circuito y encenderlo al comenzar el programa, o al llegar a un determinado punto, lo que te permite debuggear un poco.

Desconectado MaRveLsHiNe

  • PIC10
  • *
  • Mensajes: 4
Re: Problema PWM y ADC con 16F873A
« Respuesta #2 en: 16 de Enero de 2010, 07:06:22 »
Pues la idea es seguir intentándolo tanto en C como ASM hasta que lo logre jejeje, acabo de hacer lo de quitar las declaraciones de setup que no utilizo y tampoco funciona. En ambos casos sé que el programa llega correctamente a leer la entrada analógica, el problema es que, en C, el circuito no hace nada, y en ASM lee el valor del ADC, lo pasa al registro del duty cycle del pwm y en vez de hacer la regulación de velocidad el motor se pone a la máxima velocidad que da. Gracias por la ayuda!

Desconectado om@r

  • PIC12
  • **
  • Mensajes: 86
Re: Problema PWM y ADC con 16F873A
« Respuesta #3 en: 16 de Enero de 2010, 10:56:29 »
Hola
mirando el codigo en asm veo que usas el registro ADRESH para tomar como valor que te entrega el conversor ADC ,no tendrias que usar el registro ADRESL ? para tu aplicacion ?  :shock: pregunto porque si usas el registro adresh solo tienes la parte alta del valor de conversion ,si usas el adresh solo tienes 2 bits y si usas el adresl tienes 8 ,el registo adrsh y adresl forman el valor de conversion adc que es de 10 btis que se reparten entre estos dos registros.
Salu2
   

Desconectado MaRveLsHiNe

  • PIC10
  • *
  • Mensajes: 4
Re: Problema PWM y ADC con 16F873A
« Respuesta #4 en: 16 de Enero de 2010, 11:10:33 »
Uso el ADRESH porque configuré el ADCON1 para entregar el resultado de la coversión AD justificado a la izquierda, así tengo los 8 MSB en ADRESH y dos LSB en ADRESL, de todas maneras el problema está en que cuando introduzco el valor leído del ADC en CCP1RL dependiendo del valor que sea el PWM pasa a un valor fijo de 0 ó 1.
« Última modificación: 16 de Enero de 2010, 11:37:26 por MaRveLsHiNe »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema PWM y ADC con 16F873A
« Respuesta #5 en: 16 de Enero de 2010, 13:20:49 »
Lo estas simulando o lo pruebas en hard real?


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

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Problema PWM y ADC con 16F873A
« Respuesta #6 en: 16 de Enero de 2010, 14:07:47 »
Calculaste la frecuencia del pwm y su resolucion??????

Como a  es int  e Int es a 8bits , en tu pwm solo mueves la parte alta.

Puede que el resultado  de la conversion este superando los 255 y no notes cambio en el duty
.

Lo manejas a 8bits mmmm , casualidad que hare la misma practica xD , lo posteo en un rato más.

Saludos!

« Última modificación: 16 de Enero de 2010, 14:37:52 por AKENAFAB »

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Problema PWM y ADC con 16F873A
« Respuesta #7 en: 16 de Enero de 2010, 20:36:48 »
Hola

Hice este programita , en proteus no sirve el pwm , pero me doy cuenta que lo carga correctamente porque mando el valor de Duty por el puerto serie.

Saludos!
Código: C
  1. #include <16F88.h>
  2.  
  3. #FUSES HS,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP,NOPROTECT,NODEBUG,CCPB0,NOFCMEN,NOIESO
  4. #use delay(clock=8M)
  5. #use rs232(uart1,baud=9600)
  6.  
  7. #USE FAST_IO(A)
  8. #USE FAST_IO(B)
  9.  
  10. ///////////////////////////////////////////////////////////
  11. //   Control PWM duty Motor DC mediante Potenciometro ADC //
  12. ///////////////////////////////////////////////////////////
  13.  
  14. /// Tarjeta   ///
  15. #define Boton_1         PIN_B3
  16. #define Led_1           PIN_B1
  17. ///
  18. /////////////////////////////////////////////////////////
  19. //      Potenciometro conectado en A0                  //
  20. //    - Salida PWM por B0                           //
  21. //                                                     //
  22. //                                                     //
  23. /////////////////////////////////////////////////////////
  24.  
  25.  
  26. //#zero_ram
  27.  
  28. int16 ADC_pot;
  29. int8  duty,x,mem;
  30.  
  31. void main(){
  32.  
  33.             output_a(0);                     //Latch puertos
  34.             output_b(0b00100000);                     //Latch puertos
  35.            
  36.            
  37.             set_tris_a(0b00000001);             //Config Puertos ADC0=A0
  38.             set_tris_b(0b00000100);             // PWM por B0,TX=B5,RX=B2
  39. //------------- Config ADC -----------------//
  40.             setup_adc_ports(sAN0|VSS_VDD);      //A0 entrada analoga
  41.             setup_adc(ADC_CLOCK_DIV_16);
  42.             set_adc_channel( 0 );
  43.            
  44.             setup_comparator(NC_NC_NC_NC);
  45.             setup_vref(FALSE);            
  46. //------------------------------------------//            
  47.            
  48.            
  49. //----- Configuracion PWM    ---------------------  //
  50.  
  51.          SETUP_CCP1(CCP_PWM);                // Seleccionamos PWM
  52.          SETUP_TIMER_2(T2_DIV_BY_1, 254,1);   // Frecuencia = KHz
  53.          SET_PWM1_DUTY(0);                   // DUty cycle =
  54.          
  55. //------------------------------------------------
  56. for(x=0;x<4;x++){
  57. output_toggle(Led_1);
  58. delay_ms(100);
  59. }
  60. ////////////// Programa   ////////////////////////
  61. while(1){
  62.  
  63.    for(x=0;x<255;x++){
  64.        
  65.        adc_pot+=read_adc();
  66.        delay_us(20);
  67.       }//for
  68.      
  69.    output_low(Led_1);
  70.    adc_pot=adc_pot>>8;
  71.    duty=adc_pot;
  72.    
  73.    SET_PWM1_DUTY(duty);
  74.    
  75.    if(duty!=MEM){printf("Duty = %u \r ",duty);
  76.       mem=duty;
  77.       output_high(Led_1);
  78.       delay_ms(20);
  79.       output_low(Led_1);
  80.       }//if
  81.    
  82.    adc_pot=0;
  83.  
  84. }//endwhile
  85.  
  86.    
  87. }// en main

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema PWM y ADC con 16F873A
« Respuesta #8 en: 16 de Enero de 2010, 20:55:26 »
La versión 7.4 de proteus simula correctamente PWM, creo que es la versión mas estable  :?


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

Desconectado MaRveLsHiNe

  • PIC10
  • *
  • Mensajes: 4
Re: Problema PWM y ADC con 16F873A
« Respuesta #9 en: 16 de Enero de 2010, 22:45:29 »