Que tal compañeros del foro, ya despues de un buen rato investiganto por aqui y en otros lados donde apareza "diseño de pwm con pic". Y encuentro bastante pero no puedo dar con algo que me de una solucion y el problema es que tambien yo programo en ensamblador y la mayoria de la infromacion es de programas en c, aunque es mas sencillo no entiendo bien, pero bueno, llendo al grano.
Necesito generar una onda pwm con pic variable de 1 Hz a 1 KHz y que el ciclo o duty sea siempre un septimo del periodo, algo como esto:
http://img181.imageshack.us/my.php?image=ciclopwmtb7.jpg
Despues de dos meses, aprendiendo a programar en ensamblador pude hacer algo que se le asemeja, pero el ciclo de servicio aparece de un octavo, y la frecuencia no es la que necesito
###########################################################
List p=16F877A ;Tipo de procesador
include "P16F877A.INC" ;Definiciones de registros internos
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
Periodo equ 0x20 ;Variable para el periodo
Duty_H equ 0x21
Duty_L equ 0x22 ;Variable para la anchura de pulso
resta equ 0x0c
org 0x00 ;Vector de Reset
goto Inicio
org 0x05 ;Salva el vector de interrupción
;Programa principal
Inicio clrf PORTA
clrf PORTB
clrf PORTC
bsf STATUS,RP0 ;Selecciona banco 1
clrf ADCON1 ;Puerta A analógica, justificación izda.
clrf TRISB ;Puerta B se configura como salida
movlw b'00000001'
movwf TRISA ;RA0 entrada
movlw b'11111011'
movwf TRISC ;RC2/CCP1 salida
movlw b'11001101'
movwf OPTION_REG ;Preescaler de 128 asociado al WDT
bcf STATUS,RP0 ;Selecciona banco 0
;Se activa el ADC y se selecciona el canal RA0/AN0. Frecuencia de trabajo Fosc/32
Loop clrwdt
movlw b'10000001'
movwf ADCON0 ;ADC en On, seleciona canal AN0
bcf PIR1,ADIF ;Restaura el flag del conversor AD
nop
bsf ADCON0,GO ;Inicia la conversión
ADC_0 btfss PIR1,ADIF ;Fin de conversión ?
goto ADC_0 ;Todavía no
movf ADRESH,w
movwf Periodo ;Registra valor actual para el periodo
movwf resta
movwf Duty_H ;Salva parte alta de la conversión
bsf STATUS,RP0 ;Selecciona página 1
bcf STATUS,C
rrf ADRESL,F
rrf ADRESL,F
bcf STATUS,C
rrf ADRESL,W
bcf STATUS,RP0 ;Selecciona página 0
andlw b'00110000'
movwf Duty_L ;Salva parte baja de la conversión
;El módulo CCP1 se configura en modo PWM con salida por RC2/CCP1. Los bits LSB se obtienen
;de la variable Duty_L
movlw b'00001100'
iorwf Duty_L,W
movwf CCP1CON ;Modo PWM para el módulo CCP1
;El periodo se determina según el valor de la variable "Periodo". Este se carga sobre el
;registro PR2.
movf Periodo,W
bsf STATUS,RP0 ;Selecciona página 1
movwf PR2
bcf STATUS,RP0 ;Selecciona página 0
;La anchura del pulso o "Duty" se determina según el valor con que se cargue el registro
;CCPR1L concatenado con los bits 4 y 5 de CCP1CON. Dichos valores se obtiene de las varia-
;bles Duty_H y Duty_L respectivamente.
clrw
bcf STATUS,C
rrf Duty_H,F
bcf STATUS,C
rrf Duty_H,F
bcf STATUS,C ; Ciclo de servicio dividido entre 4
rrf resta,F
bcf STATUS,C
rrf resta,F
bcf STATUS,C
rrf resta,F ; Ciclo de servicio dividido entre 8
bcf STATUS,C
movf resta,W
subwf Duty_H,F ; Resta del resultado entre 4 menos resultado de /8
bcf STATUS,C
rrf Duty_H,W
movwf CCPR1L
;Trabajando con un preescaler 1:1 y a una frecuancia de 4MHz, el TMR2 evoluciona cada 1 uS.
movlw b'00000110'
movwf T2CON ;TMR2 en On
goto Loop
end ;Fin del programa fuente
############################################################
Mi compañero hizo este otro en C que se acerca mas pero la frecuencia de salida es inestable, no se puede leer la frecuencia ya aca en la practica
###########################################################
#include <16f877A.h>
#device ADC=8
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT
#use fast_io (A)
#use fast_io (B)
#byte resultado=0x20
#byte PORTB=0x06
#use delay(clock=4000000)
main()
{
set_tris_a(0x01);
set_tris_b(0x00);
setup_adc(adc_clock_div_32);
setup_adc_ports(AN0);
while(1)
{
set_adc_channel(0);
resultado = read_adc();
bit_set(PORTB,0);
delay_ms(resultado);
bit_clear(PORTB,0);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
}
}
###########################################################
No hemos parado de investigar y buscar en varios sitios por algun empujoncillo que nos ayude a terminar esto, cualquier comentario o aportacion sera bien recibido, muchas gracias.
Necesito generar una onda pwm con pic variable de 1 Hz a 1 KHz y que el ciclo o duty sea siempre un septimo del periodo, algo como esto:
http://img181.imageshack.us/my.php?image=ciclopwmtb7.jpg
Despues de dos meses, aprendiendo a programar en ensamblador pude hacer algo que se le asemeja, pero el ciclo de servicio aparece de un octavo, y la frecuencia no es la que necesito
###########################################################
List p=16F877A ;Tipo de procesador
include "P16F877A.INC" ;Definiciones de registros internos
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
Periodo equ 0x20 ;Variable para el periodo
Duty_H equ 0x21
Duty_L equ 0x22 ;Variable para la anchura de pulso
resta equ 0x0c
org 0x00 ;Vector de Reset
goto Inicio
org 0x05 ;Salva el vector de interrupción
;Programa principal
Inicio clrf PORTA
clrf PORTB
clrf PORTC
bsf STATUS,RP0 ;Selecciona banco 1
clrf ADCON1 ;Puerta A analógica, justificación izda.
clrf TRISB ;Puerta B se configura como salida
movlw b'00000001'
movwf TRISA ;RA0 entrada
movlw b'11111011'
movwf TRISC ;RC2/CCP1 salida
movlw b'11001101'
movwf OPTION_REG ;Preescaler de 128 asociado al WDT
bcf STATUS,RP0 ;Selecciona banco 0
;Se activa el ADC y se selecciona el canal RA0/AN0. Frecuencia de trabajo Fosc/32
Loop clrwdt
movlw b'10000001'
movwf ADCON0 ;ADC en On, seleciona canal AN0
bcf PIR1,ADIF ;Restaura el flag del conversor AD
nop
bsf ADCON0,GO ;Inicia la conversión
ADC_0 btfss PIR1,ADIF ;Fin de conversión ?
goto ADC_0 ;Todavía no
movf ADRESH,w
movwf Periodo ;Registra valor actual para el periodo
movwf resta
movwf Duty_H ;Salva parte alta de la conversión
bsf STATUS,RP0 ;Selecciona página 1
bcf STATUS,C
rrf ADRESL,F
rrf ADRESL,F
bcf STATUS,C
rrf ADRESL,W
bcf STATUS,RP0 ;Selecciona página 0
andlw b'00110000'
movwf Duty_L ;Salva parte baja de la conversión
;El módulo CCP1 se configura en modo PWM con salida por RC2/CCP1. Los bits LSB se obtienen
;de la variable Duty_L
movlw b'00001100'
iorwf Duty_L,W
movwf CCP1CON ;Modo PWM para el módulo CCP1
;El periodo se determina según el valor de la variable "Periodo". Este se carga sobre el
;registro PR2.
movf Periodo,W
bsf STATUS,RP0 ;Selecciona página 1
movwf PR2
bcf STATUS,RP0 ;Selecciona página 0
;La anchura del pulso o "Duty" se determina según el valor con que se cargue el registro
;CCPR1L concatenado con los bits 4 y 5 de CCP1CON. Dichos valores se obtiene de las varia-
;bles Duty_H y Duty_L respectivamente.
clrw
bcf STATUS,C
rrf Duty_H,F
bcf STATUS,C
rrf Duty_H,F
bcf STATUS,C ; Ciclo de servicio dividido entre 4
rrf resta,F
bcf STATUS,C
rrf resta,F
bcf STATUS,C
rrf resta,F ; Ciclo de servicio dividido entre 8
bcf STATUS,C
movf resta,W
subwf Duty_H,F ; Resta del resultado entre 4 menos resultado de /8
bcf STATUS,C
rrf Duty_H,W
movwf CCPR1L
;Trabajando con un preescaler 1:1 y a una frecuancia de 4MHz, el TMR2 evoluciona cada 1 uS.
movlw b'00000110'
movwf T2CON ;TMR2 en On
goto Loop
end ;Fin del programa fuente
############################################################
Mi compañero hizo este otro en C que se acerca mas pero la frecuencia de salida es inestable, no se puede leer la frecuencia ya aca en la practica
###########################################################
#include <16f877A.h>
#device ADC=8
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT
#use fast_io (A)
#use fast_io (B)
#byte resultado=0x20
#byte PORTB=0x06
#use delay(clock=4000000)
main()
{
set_tris_a(0x01);
set_tris_b(0x00);
setup_adc(adc_clock_div_32);
setup_adc_ports(AN0);
while(1)
{
set_adc_channel(0);
resultado = read_adc();
bit_set(PORTB,0);
delay_ms(resultado);
bit_clear(PORTB,0);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
delay_ms(resultado);
}
}
###########################################################
No hemos parado de investigar y buscar en varios sitios por algun empujoncillo que nos ayude a terminar esto, cualquier comentario o aportacion sera bien recibido, muchas gracias.