Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
Gracias por tu pronta respuesta anteriormente ya lo habia realizado asi pero con un cristal de 20 pero sin conexion a USB pero ahora mi pregunta es la siguiente que no se supone que los calculos estan basados en la frecuencia del cristal pero ya ves que el modulo USB trabaja asta 48Mhz o nadamas se toma la frecuencia del cristal externo sin tomar en cuenta el PLL del pic modulo USB???
Muchas gracias por aclararme esa duda en el transcurso de la semana lo pruebo y te comento que tal jala, oye amigo una pregunta mas influye el numero de salidas pwm que tengo es decir es la misma frecuencia para 3 salidas que para 8???
Esque pude modificar tu libreria para que me diera 8 salidas pwm y me las da sin ningun problema pero mi pregunta es si no afecta en la frecuencia que era para 3??
#include <18F2550.h> //pic utilizado en este caso el 18f2550
#DEVICE ADC=8 //Bits del modulo convertidor analógico
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN //Fuses utilizados para este proyecto
/*
HSPLL: utilizamos un cristal HS de alta velocidad,
en conjunto con el PLL para generar los 48Mhz.
MCLR: Utilizamos reset por Hadware.
NOWDT: No utilizamos el perro guardían.
NOPROTECT: Desactivamos la protección de código.
NOLVP: Desactivamos la programación a bajo voltaje.
NODEBUG: No entramos al modo debug.
USBDIV: signfica que el clock del usb se tomará del
PLL/2 = 96Mhz/2 = 48Mhz.
PLL5: significa que el PLL prescaler dividirá en 5 la frecuencia
del cristal. para HS = 20Mhz/5 = 4Mhz.
CPUDIV1: El PLL postscaler decide la división en 2 de la
frecuencia de salida del PLL de 96MHZ, si queremos
48MHZ, lo dejamos como está.
VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB
*/
#use delay(clock=48000000) //Frecuencia de relog a 48MHz
#define USB_HID_DEVICE FALSE //Desactivamos el modulo HID ya que trabajaremos en modo Bulk
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //Habilitamos el modo TX en Bulk
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //Habilitamos el modo RX en Bulk
#define USB_EP1_TX_SIZE 4 //Tamaño del TX para nuestro Bulk
#define USB_EP1_RX_SIZE 8 //Tamaño del RX para nuestro Bulk
#Define CH0 PIN_C0 //Asignación del canal 0 para el PWM
#Define CH1 PIN_C6 //Asignación del canal 1 para el PWM
#Define CH2 PIN_C7 //Asignación del canal 2 para el PWM
#Define CH3 PIN_B0 //Asignación del canal 3 para el PWM
#Define CH4 PIN_B1 //Asignación del canal 4 para el PWM
#Define CH5 PIN_B2 //Asignación del canal 5 para el PWM
#Define CH6 PIN_B3 //Asignación del canal 6 para el PWM
#Define CH7 PIN_B4 //Asignación del canal 7 para el PWM
#include <pic18_usb.h> //Mandamos llamar a la librería para poder controlar este pic
#include "daqDescriptor.h" /*Mandamos llamar la librería para que esta informe a la computadora
sobre el vendedor y producto esta librería es llamada como
descriptores y es la que conecta a la pc con el pic*/
#include "PWM.h" //Mandamos llamar la libreria del PWM por software
#include <usb.c> //Mandamos llamar la librería de las funciones del modulo USB
#use fast_io(b)
#use fast_io(c)
int8 datoRX[8], datoTX[4]; //Variables del programa
int8 count=0;
void main( void ) //Programa principal
{
PWM_init(80); //Numero de conteo del timer para esta librería en base a la frecuencia
setup_port_a(AN0_TO_AN2); //Configuramos las entradas análogas
setup_adc(ADC_CLOCK_INTERNAL); //Con una señal de reloj interna
set_tris_a(0xFF); //Puerto A de la siguiente manera(11111111) 1=entradas, 0=salidas
set_tris_b(0xE0); //Puerto B de la siguiente manera(11100000) " "
set_tris_c(0x00); //Puerto C de la siguiente manera(00000000) " "
output_a(0); output_b(0); output_c(0); //Reseteamos el puerto A,B,C
write_duty0(255); //Reseteamos las salidas PWM
write_duty1(255);
write_duty2(255);
write_duty3(255);
write_duty4(255);
write_duty5(255);
write_duty6(255);
write_duty7(255);
usb_init(); //Iniciamos el modulo USB
usb_task();
output_low(PIN_A3); //Led indicador de estado
usb_wait_for_enumeration(); //Espera a que el USB sea enumerado por la PC
output_high(PIN_A3); //Led indicador de estado
delay_ms(100); //Milipausa para estabilidad
While(TRUE) //Bucle infinito para envió y recepción de datos al buffer
{
if(usb_enumerated()) //Si el dispositivo a sido enumerado
{
if (usb_kbhit(1)) //Si llegan nuevos caracteres en el buffer de recepcion
{
usb_get_packet(1,datoRX,8); //Leer buffer de ingreso
write_duty0(datoRX[0]); //El valor del write duty x es igual a el dato que llega del vector datoRX[x]
write_duty1(datoRX[1]);
write_duty2(datoRX[2]);
write_duty3(datoRX[3]);
write_duty4(datoRX[4]);
write_duty5(datoRX[5]);
write_duty6(datoRX[6]);
write_duty7(datoRX[7]);
}
for(count=0;count<=2;count++) //Ciclo for para enviar datos de entradas analogicas
{
set_adc_channel(count); //Lee los valores de ADC según sea el contador
delay_us(80); //Micro pausa para estabilidad en la lectura
datoTX[count]=read_adc(); /*Igualamos nuestro buffer de salida a la lectura
adc mediante el vector que indique nuestro for*/
}
usb_put_packet(1,datoTX,4,USB_DTS_TOGGLE); /*Enviamos nuestro paquete de datos almacenados en nuestros
vectores a la PC*/
}
}
}
Te explico un poco el problema la primer entrada si me da todos los bits pero no concuerdan es decir a 5v serian 255 bits y se supone que a 2.5v serian 127bits pero no concuerdan, la segunda entrada no jala solo da uno o cero, y el tercero jala como el primero aparte tienen mucho ruido, a ver si podrías orientarme con ese problema gracias
AllDigital
Dim pwm1 As Word
Dim contador As Word
Dim x As Word
OPTION_REG = %10000000 'pre 128 (110) - 2 (000)
INTCON = %10100000 'Activa int globales(bit7) e int Tmr0(bit5)
T1CON = %00000000 'Activa Tmr1(bit0)
PIE1 = %00000000 'Activa int de Tmr1 (bit0)
TRISB = %01111111
PORTB.7 = 0
contador = 0
pwm1 = 0
TMR0 = 0
ciclo:
If pwm1 = 0 Then PORTB.7 = 0
pwm1 = 0
x = 0
While x < 255
x = x + 1
pwm1 = pwm1 + 1
WaitMs 20
Wend
pwm1 = 255
x = 0
While x < 255
x = x + 1
pwm1 = pwm1 - 1
WaitMs 20
Wend
Goto ciclo
End
On Interrupt
contador = contador + 1
If pwm1 >= contador Then
PORTB.7 = 1
Else
PORTB.7 = 0
Endif
If contador = 255 Then
contador = 0
Endif
INTCON.2 = 0 'borro bandera int tmr0
Resume
//////////////////////////////////////////////////////////////////////////
////Control de 3 canales PWM por software //
////se utiliza para mesclar el brillo de tres leds;rojo,verde,azul //
////utilizando potenciometro conectados a puerto AN0,AN1 y AN2 //
////recuerde que la libreria PWM.h debe estar en la misma carpeta //
////donde se encuentre su codigo fuente //
//////////////////////////////////////////////////////////////////////////
#include <18F4550.h>
#device ADC=8
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#include "usb_bootloader.h"
#use delay(clock = 48000000)
#Define CH0 PIN_D0 //led ROJO conectado a rb5, cambie de pin si desea
#Define CH1 PIN_D1 //led VERDE conectado a rb6, cambie de pin si desea
#Define CH2 PIN_D3 //led AZUL conectado a rb7, cambie de pin si desea
#include <PWM.h> //libreria para generar PWM de 8 bit por software
#use fast_io(d)
//#use fast_io(a)
void main (void)
{
unsigned byte value;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2); //A0,A1,A2 entradas analogicas
set_tris_d(0xF0);
output_d(0);
//output_a(0);
delay_ms(20);
PWM_init(150); //Inicia MACRO para generar PWM por software, RTCC_DIV_2
while(true)
{
set_adc_channel(0);
delay_us(50);
value=read_adc(); //lee canal AN0
write_duty0(value);//escribe canal PWM0
output_high(CH0);
set_adc_channel(1);
delay_ms(150);
value=read_adc(); //lee canal AN1
write_duty1(value);//escribe canal PWM1
output_low(CH0);
output_high(CH1);
set_adc_channel(2);
delay_ms(150);
value =read_adc(); //lee canal AN2
output_low(CH1);
write_duty2(value);//escribe canal PWM2
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////libreria PWM.h, version 8Bit //
////author: dinoelectro //
////www.forosdeelectronica.com //
////dino_barreto@hotmail.com //
////Con esta libreria podra generar ondas PWM con una resolucion de 8bit. //
////Por defecto las ondas generadas salen por los pines B0, B1 y B2, pero cualquier otro PIN puede ser //
////configurado como salida PWM; Por ejemplo: para generar las ondas en los pines A0,A1 y A2 usted deberia //
////hacer la definicion de los canales como sigue: //
//// #define CH0 PIN_A0 //
//// #define CH1 PIN_A1 //
//// #define CH2 PIN_A2 //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CH0 #define CH0 PIN_D0 #endif //si no ha definido, PIN_B0 sera canal0 PWM por defecto
#ifndef CH1 #define CH1 PIN_D1 #endif //si no ha definido, PIN_B1 sera canal1 PWM por defecto
#ifndef CH2 #define CH2 PIN_D3 #endif //si no ha definido, PIN_B2 sera canal2 PWM por defecto
unsigned byte intcount =0;
unsigned byte dutycycle0=0;
unsigned byte dutycycle1=0;
unsigned byte dutycycle2=0;
unsigned byte Reload;
///////////////////////////////////////////////////////////////////////////////////////////////////////
////Funcion PWM_init(load) //
////USO: //
//// Esta funcion inicia y habilita interrupcion por timer0 //
//// el timer0 es necesario para generar la onda PWM cuya //
//// frecuencia esta directamente realacionada con el cristal //
//// que haya elejido y con el valor que carga en el timer0 //
////Parametros: //
//// load: puede tomar un valor de 0... 255 //
//// mientras mayor sea el valor de load, mayor sera la frecuencia de la onda PWM // //
////VALOR DE RETORNO: //
//// ninguno //
///////////////////////////////////////////////////////////////////////////////////////////////////////
void PWM_init(load)
{
if (load >240) load=240;
Reload = load;
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
////Funciones Write_Duty0, Write_Duty1, Write_Duty2 //
////USO: //
//// Estas funciones escriben el valor del ciclo util en los canales 0, 1 y 2; respectivamente //
////PARAMETROS: //
//// value, es el ciclo util, puede tomar un valor entre 0 y 255 //
////VALOR DE RETORNO: //
//// ninguno //
///////////////////////////////////////////////////////////////////////////////////////////////////////
void write_duty0(value) {dutycycle0=value;}
void write_duty1(value) {dutycycle1=value;}
void write_duty2(value) {dutycycle2=value;}
///////////////////////////////////////////////////////////////////////////////////////////////////////
#int_timer0
void timer0_isr()
{ set_timer0(Reload);
if (intcount--==0)
{
output_high(CH0);
output_high(CH1);
output_high(CH2);
}
if (intcount==dutycycle0)output_low(CH0);
if (intcount==dutycycle1)output_low(CH1);
if (intcount==dutycycle2)output_low(CH2);
}