Control de pwm con basic?

Hola como estan gente
vengo con una pregunta un poco ignorante pero nesecito ayuda
resulta que tengo un par de años programando microcontroladores en ASM
pero ya que es muy fastidioso lo deje para mudarme al basic

no recuerdo bien como generar el pwm en asm

pero eso no me importa lo que quiero es hacer el codigo en BASIC si alguien me puede hechar una mano con esto del codigo

y aora tengo un proyecto para unos letreros

lo que quiero es prender ùn led poco a poco y apagarlos igual poco a poco
tengo atraso con este trabajo y ya me fastidie con el asm
espero y me ayuden !

gracias
este es el codigo pero nose como varias los valores para prender poco a poco el led y viseversa


Frec var byte
Frec=127
inicio;

pwm portc.2,Frec,100
goto inicio;
 
Última edición:
En microbasic esta la instrucion "pwm_change_duty(j)" donde j es un valor de 0 a 255, creo, y con este valor ajustas el porcentaje del tiempo de encendido. si j tomas un valor que puedas incrementar o decrementar con el programa, puedes crear el efecto que buscas
 
Hola tronik si usas Pic Basic Pro la sentencia para usar PWM es
HPWM canal, duty, frecuencia
HPWM es por hardware asi que solo la puedes usar en PICs con modulo PWM, a diferencia de la sentencia PWM que es por software al usar la sentencia PWM no estas usando los modulos pwm fisicos del PIC, el valor de canal puede ser 1 o 2, la frecuencia minima que puedes usar depende del cristal consulta la ayuda, saludos espero te sirva, duty es por defecto una variable de 8 bits.

Hola tronik quia lo que quieres sea algo como esto:

define osc 4
i var byte
freq con 10000
for i=0 to 127
hpwm 1,i,freq
pause 10
next
 
Última edición:
estoy usando el 16f877 que tienen el RC1 y RC2 como CCP1 y CCP2
no se si me puedan decir como empieso una instruccion con HPWM
y como defino los valores para incrementar y aumentar la intencidad de los led's
 
define osc 4 'Definiendo la frecuencia del cristal en MHZ
duty var byte
freq con 10000 ' Frecuencia de conmutacion que usaremos prueba para encontrar la mejor
Inicio:
for duty=0 to 127 ' en este bucle for incrementamos la variable duty de cero a 127
hpwm 1,duty,freq ' con lo cual se incrementara la luminosidad del led
pause 10 ' pausa entre incrementos
next
goto inicio 'a comenzar de nuevo


' para manipular la luminosidad debes de cambiar el valor de la variable duty de 0-255, en
' cero el led estara totalmente apagado y en 255 encendido con todo el voltaje tener
' cuidado con las corrientes que salgan del pic, implementar con la interface adecuada entre ' el pic y el led.
 
Última edición:
jcristhian_1 eso es exactamente lo que busco simule en proteus con el pic16f870
y use tu codigo y eso es exactamento lo que busco
nose si me puedas dar un link donde buscas mas informacion acerca de esto de como variar mas el ancho de pulso yasea alto o bajo y como activar los ccp2 en caso de que trabaje con el pic16f877

gracias
 
Hola me alegra que te sirva
para usar ccp1, canal debe ser 1 y para usar ccp2 canal debe ser 2, lo demas es igual:
hpwm canal,duty,freq
consulta la propia ayuda del PBP cualquier cosa estare para responderte,
si quieres controlar el tiempo que esta en bajo seria el complemento del tiempo en alto
es decir
t_bajo=255-duty
 
Buenas noches, estimados , estaba revisando mucho, los temas en la pagina Pic basic Pro de Foros de Electronica y encontré aqui:
porque lo digo porque estoy queriendo hacer un proyecto de pwm con pic y lcd para manejar la velocidad de un motor dc 180 volts 1 hp. Queria saber, por donde empiezo, como lo hago. Programo en PBP, mas o menos.
Tengo el microcontrolador 16f877a que tiene 3 entradas analógicas, de las cuales, necesito la primera para el Potenciometro de 10 k, esta señal analógica tiene que entrar a un compartimento de ADCIN para leer , luego convertirlo a ciclo util entre 0 y 255, quisiera saber como empiezo para que sobre las bases de este Foro que maneja mucho conocimiento , yo pueda abordar el proyecto con seguridad y no a tumbos como dijo Darbytes por alli.

Les agradeceria bastante.
 

Adjuntos

  • esquema.rar
    11.2 KB · Visitas: 19
Has resucitado un hilo de 2012.
No aportas nada, solo preguntas. (ver normas del foro)
No se puede ver el esquema

Entiendo que debes de empezar tu solo y preguntar dudas.
 
Tengo el microcontrolador 16f877a que tiene 3 entradas analógicas
En primera debes empezar por conocer el microcontrolador que vas a usar.
El PIC16F877A tiene 8 canales de 10 bits para el ADC.
Esta señal analógica tiene que entrar a un compartimento de ADCIN para leer, luego convertirlo a ciclo útil entre 0 y 255
El ciclo activo no puede ir entre 0 y 255 porque es un periodo que típicamente se maneja como un porcentaje del 0% al 100% del ancho del pulso.
Lo que sí puede ir de 0 a 255 es la lectura del ADC cuando se realiza a 8 bits.
Estoy queriendo hacer un proyecto de PWM con PIC y LCD para manejar la velocidad de un motor DC 180 Voltios y 1 HP.
Para eso, aparte de conocer sobre programación, también necesitarás conocimientos sobre electrónica de potencia.

Como están actualmente tus conocimientos y si sigues estudiando, yo pienso que en un par de años lo estarás realizando.
 
Owww. 2 años. Qué bueno. Por lo menos sí lo voy a lograr. Peor es creer que nunca. Saludos. Ya envío mi primera pregunta.

Buenas noches mis Estimados amigos, no me quedo con las ganas de experimentar un proyecto de controlar la frecuencia de un motor dc, por hardware, por el cual ingrese a este foro de renombre por la calidad y la altura de sus ingenieros electrónicos.

Me puse a leer datashet un poco de 16f877, encontré un ADCON0, ADCON1 registros que se encargan de leer un canal o varios, de lectura análoga activa, desactiva canal, osc interno, y muchas cosas mas, , también con ayuda del pbp help¡ pude llegar a este pequeño programita que maneja un hpwm por hardware, y lo estoy probando ya con un led en protoboard, aqui quiero subir, y pedirle a los expertos que me den una revisadita a ver si me va a funcionar, la verdad estoy varios dias y quería saber si estoy avanzando bien, gracias

Adjunto esquema y programa en pbp. mcs.
 

Adjuntos

  • hpwm.rar
    42 KB · Visitas: 19
No soy un experto en PBP pero revisa a ver como ves esto...en la simulación tienes el oscilador a 4MHZ pero declaras en el programa a 8MHz
Código:
****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2020 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 17/05/2020                                        *
'*  Version : 1.0                                               *
'*  Notes   : 16F877A a 8MHz                                    *
'*          :                                                   *
'****************************************************************
DEFINE OSC 8

DEFINE LCD_DREG PORTB          ;bit de datos del LCD empezando
DEFINE LCD_DBIT 0              ;por B.0, B.1, B.2 y B.3

DEFINE LCD_RSREG PORTB        ;bit de registro del LCD conectar
DEFINE LCD_RSBIT 5            ;en el puerto B.5
DEFINE LCD_EREG PORTB          ;bit de Enable conectar en el
DEFINE LCD_EBIT 4              ;puerto B.4

DEFINE CCP1_REG PORTC 'Hpwm 1 pin port
DEFINE CCP1_BIT 2 'Hpwm 1 pin bit
DEFINE CCP2_REG PORTC 'Hpwm 2 pin port
DEFINE CCP2_BIT 1 'Hpwm 2 pin bit

anterior var byte              ' variable que contiene el valor anterior del ADC para comparación

   LCDOUT $fe, 1," Pwm MOTOR DC "    ;limpiar LCD y sacar texto
   ADCON1 =%1110                ;configura PortA 0 en conversores A/D
   ADCON0 =%1000001       ;activar canal 0 a Fosc/8
Inicio:
         ADCON0.2 = 1              ;iniciar conversión
         PAUSEUS 50                ;pausa para la conversión
         if anterior = ADRESH THEN goto inicio   ' si no hay cambios reinicio la medicion  
         hpwm 1,ADRESH,10000 ' con lo cual se incrementara la luminosidad del led
         LCDOUT $fe,$c1,dec3  ADRESH                ;casilla 1 el valor decimal de p1
         anterior =  ADRESH               ' cargo el valor de la medicion con el valor actual para futura comparacion
GOTO inicio

END

Por cierto no te acostumbres a usar retardos(pause) innecesariamente porque como el micro-controlador haces solo una cosa a la vez, lo tienes perdiendo tiempo esperando que pase esta "pausa" y se puede perder de hacer/revisar etc cosas, así como, depura el uso de variables y rutinas o subrrutinas que de por si no son necesarias.
 
Última edición:
Muchas gracias Ricbevi, por el aporte, queria hacer una consulta con respecto al otro canal hpwm 2, ¿es necesario activarlo también? por lo que el motor que voy a utilizar va a trabajar es de 180 v dc con 7.7 amp, 1.5 hp, 1750 rpm, me refiero al par motor,torque, la etapa de potencia ya lo tengo, y queria subirlo pero o me dio tiwmpo. sera nesesario o suficiente con esto ya lo puedo probar con carga al motor , esa es mi pregunta.
 

Adjuntos

  • Sin título.jpg
    Sin título.jpg
    115.7 KB · Visitas: 4
Realmente no tengo experiencia en controles de motores de ese tipo pero debes adaptar todo al sistema de control de potencia que ya posees.

Tenia entendido que para no perder las características del motor de ese tipo, el control se hacia en frecuencia no en anchura de pulso que es lo que estas programando pero te reitero que carezco de experiencia en ese campo.
 
La verdad, que montais unas liadas en los códigos.
Cuando un equipo trabaja en un código cada uno hace una parte su parte aveces se acuerda para enlazar bien esas partes... Pero......

Bueno me salgo del tema.
Tmr2 suele ser el encargado del contador pwm donde el máximo del conteo (y frecuencia del ciclo pwm) se determina con el prescaler y pr2 que seria el largo del duty pwm.
Al mismo tiempo tmr2 tiene un poscaler para dar los banderines de 1 a 16.

Ejemplo practico.
Ahora mismo estoy en un trabajo parecido de regulación de corriente. Configuración
Osc 8mhz, prescaler 1:1, pr2=28 (casi 74khz) el poscaler 1:3, a cada tres ciclos pwm tengo un banderín tmr2 (casi 24khz) para chequeos x, y bueno necesitaba 2 pwm mas pero no a tanta frecuencia. Ese pwm en un contador de 0 a 15 dentro de la interrupción tmr2.
Ese pwm seria por software.
24khz/16= 1,5khz la portadora pwm por software, que para lo que necesito me viene muy bien..
Para controlar un motor creo q también.. Ahora para una led... Poder se podría (pero menudas jaquecas producen)

Espero que este aporte te de una idea de aprovechar el banderín tmr2 como pwm por software

Un saludo
 
acabo de leer lo de pepibho: leere su mensaje detenidamente.

Buenas noches estimados Amigos, Controleros, estuve investigando algo mas acerca de mi projecto:

HPWM por hardware para mi motor CDP3575 180 volt dc, 1750 r/m, 7.7 amp.

Y pues estuve investigando por alli haciendo algunos ensayos pero con un cooler
de fuente de poder de cpu, 12volt,(motor brushlers) pensando que si logro lo que estoy buscando con un pequeño
ventilador, lo podre hacer con el motor grande y bueno sí se logra hacer hpwm, ya que en la entrada
ADC de pic 16f877a va un potenciometro de valor 10k y voltajes de referencia de 5v y 0v.

el programa es este:

DEFINE OSC 8

DEFINE LCD_DREG PORTB ;bit de datos del LCD empezando
DEFINE LCD_DBIT 0 ;por B.0, B.1, B.2 y B.3

DEFINE LCD_RSREG PORTB ;bit de registro del LCD conectar
DEFINE LCD_RSBIT 5 ;en el puerto B.5
DEFINE LCD_EREG PORTB ;bit de Enable conectar en el
DEFINE LCD_EBIT 4 ;puerto B.4

DEFINE ADC_BITS 10 ;Fije número de BITS del resultado (5,8,10)
DEFINE ADC_CLOCK 3 ;Fije EL CLOCK (rc = 3)
DEFINE ADC_SAMPLEUS 50 ;Fije el tiempo de muestreo en Us
;ADC_SAMPLEUS es el número de microsegundos que el programa espera
;entre fijar el canal y comenzar la conversión analogica/digital.

DEFINE CCP1_REG PORTC 'Hpwm 1 pin port
DEFINE CCP1_BIT 2 'Hpwm 1 pin bit
DEFINE CCP2_REG PORTC 'Hpwm 2 pin port
DEFINE CCP2_BIT 1 'Hpwm 2 pin bit

TRISA=%1
TRISB=%0
TRISC=%0

anterior var word ' variable que contiene el valor anterior del ADC para comparación

LCDOUT $fe, 1," Pwm MOTOR DC " ;limpiar LCD y sacar texto
ADCON1 =%00001110 ;configura PortA 0 en conversores A/D
ADCON0 =%11000001 ;activar canal 0 a Fosc/8 00=4mhz 10=8mhz
Inicio:
ADCON0.2 = 1 ;iniciar conversión
PAUSEUS 50 ;pausa para la conversión
if anterior = ADRESH THEN goto inicio ' si no hay cambios reinicio la medicion
hpwm 1,ADRESH,10000 ' con lo cual se incrementara la luminosidad del led
LCDOUT $fe,$c1,dec3 ADRESH
anterior = ADRESH ' cargo el valor de la medicion con el valor actual para futura comparacion
GOTO inicio

END

donde los registros:

adcon0 y adcon1 son registro donde se configura el tiempo de conversion, el canal de entrada, progreso de conversion,
etc, etc,
ademas de un registro de 16 bits llamado adresh y adresl donde se almacena el resultado de la conversion.(16 bits, cadauno de o bits)

BUeno en sintesis, tegno un inconveniente con mi projecto y no se como proceder, creo que me estoy dando cuenta
lo que dijo Darbytes , que me tomara dos años hacer, jejeje-.

el asunto es:
mi motor cooler comienza a girar cuando el potenciometro esta en 60 decimal (es decir desde 0 hasta 59 no mueve el ventilador) y llega hasta
255 decimal su maxima velocidad, hasta aqui muy bien, porque un ventilador es normal girar a muchas revoluciones
al final es un ventilador, pero el problema esta en que si le pongo a mi motor grande esta
configuracion lo primero que el potenciometro esta muy largo para iniciar su trabajo, imaginate para que empiece a girar el motor
el pot tiene que girar un 40% aproximadamente recien para que inicie el giro, y por otro lado no se desea el giro a maxima velocidad del motor,
saldria volando la maquina donde esta instalado el motor grande.

entonces se desea implementar en el programa basic "patrones para poder hacer ajustes de velocidad deseadas":

que el minimo y maximo del potenciometro varien entre el 45% y 60% suficientes.

E medido en la entrada del adc RA0 los siguientes voltajes por lo cual supongo que alli trabajaria muy bien el motor, en un ventana de:

potenciometro

MINIMO MAX
1.5 VOLT 2.5VOLT
O O
60 DECIMAL 130 DECIMAL

Entonces estuve estudiando un poco como hacer esto, y tengo la idea quiza de aplicar un "voltaje de referencia" por un segundo pin del puerto A,

entonces alli no se como hacer esa programacion, que idea me dan muchachos, ya que esto de la programacion es inmenso. waooo si que es inmenso
vi por alli algunos terminos como:

Tiempo de Adquision: Tiempo de Conversion: resolucion:

mi preguta es como lo úedo hacer ya que si el projecto llevara un timer X , me derrumbo porque eso aun no le eh podido entender muy bien.

Ante mano Gracias por su ayuda y estoy apto a lo que me digan.

Gracias
 
Claro, ahora te tocaría calibrar los valores que te da el integrado a los limites deseados.
Por un lado estas tomando la lectura ad de un potenciómetro (que no te quedo muy bien ajustado el calculo. Pero bueno, mientras tengas la lectura de todo el rango del potenciómetro) después seria una regla de 3 para ajustar en dos operaciones al valor pwm entre un 45-60% pwm.
En la configuración pwm podrías podrías invertir el ciclo pwm (en vez de arrancar en 1 para terminar ccp1 poniendo a 0 inviertes en la configuración que inicie en 0 ) incluso para asegurar que nunca este al 100% del ciclo pones a uno los 2 primeros bit de conteo.
Ccp1con:
bit 5-4 DC1B<1:0>: PWM Duty Cycle Least Significant bits.
PWM mode: These bits are the two LSbs of the PWM duty cycle.

Esto permite o bien que nunca sea 0% un ciclo pwm o vice versa nunca sea el 100%
Sobre criticas constructivas.
TRISA=%1
TRISB=%0
TRISC=%0

Esto así no lo veo muy bien. Se sobre entiende que solo estas configurando el estado del primer bit del puerto y los binarios quedan mejor poniendo la cadena entera.
TRISA=%00000011
TRISB=%00000000
TRISC=%00000000
Me imagino que querrás a.0 y a.1 como entradas. La otra forma mejor seria especificar el bit q cambias
TRISA.0=1 ' solo bit 0 como entrada
TRISB.0=0
TRISC.0=0

Y muy importante. No sabes usar el banderín de una lectura ad finalizada, si no esta definida como interrupción tan sólo es chequear el banderín. Esa manera que usas comparando .
If anterior = ADRESH THEN goto inicio
Te puede dar reinicio

No seria mejor

Adcon0.1=1 ' arrancamos solicitando una ad
Inicio:
If pir1.6=0 then goto inicio ' retiene asta tener una ad terminada
Pir1.6=0 ' borra banderín ad completado
Anterior=adresh ' traspasamos valor ad
Adcon0.1=1 ' solicitar otra ad, GO/DONE
...
....
Lo que tengas que segur haciendo
....
...
Goto inicio

No seria mucho mejor así (sigue sin ser correcta la forma)

Un saludo
..... Lo siento, no e debido explicar y pocas veces esplican. Que los banderines de acciones completadas no están obligadas a accionar una interrupción si no están definidas como interrupción en pie.
Lo cual que tan sólo son bit a secas indicando la conclusión de algo o un suceso (por un decir) jugar con eso es muy útil
 
Última edición:
Atrás
Arriba