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.
// programa de control de motor a pasos e interfas de datos analogos y digitales ambos de 8 canales, via USB.
// Programador: Abdul Saucedo.
// Basado en programa de Moyano Jonathan.
// Fecha: 10/05/09
//************************************************************************
#include <18F2550.h> // Definición de registros internos.
#DEVICE ADC=10 // CAD con 10 bits de resolución , justificación a la derecha.
#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
// Fuses utilizados:
/*
HSPLL: utilizamos un cristal HS de alta velocidad, en conjunto con el PLL para generar los 48Mhz.
NOMCLR: Utilizamos reset por software, y dejamos el pin 1 del micro como entrada/salida digital.
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
NOPBADEN: Deshabilitamos el módulo de conversión ADC del puerto B.
*/
#use delay(clock=48000000) // Frecuencia máxima de trabajo 48 Mhz.
short estado_usb; // boolean global, se debe declarar antes de llamar a usb_cdc.h
#define USB_CON_SENSE_PIN PIN_E3 // Definiendo este pin , detectamos si el host está conectado o no por hardware.
#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.
// Declaramos las funciones utilizadas.
void config_adcon2(int num); // Función que utilizamos para configurar el registro ADCON2.
void estado_conexion_usb(short bandera); // Muestra el estado de la conexión USB.
void main() { // Comienza el programa principal.
// Variables utilizadas en el programa.
int i;//variable de incremento
long valorA,valorB,valorC,valorD,valorE,valorF,valorG,valorH;//variables de valor analogico
// Configuramos los puertos del PIC.
set_tris_a(63); // RA0 a RA5, como entrada
set_tris_b(152); // RB1,RB2,RB3,RB4,RB7 como entrada
set_tris_c(199);// RC0,RC1,RC2,RC6,RC7 como entrada
// Otras configuraciones.
disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_spi(FALSE);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
setup_adc_ports(AN0 || VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64);
/*************************************************************************************/
estado_usb=false; // No se ha conectado al HOST.
usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB.
usb_init_cs(); // inicia el USB y sale. Va de la mano con usb_task().
/******************************Empieza bucle infinito*********************************/
while(true){
usb_task(); // configura el USB.
estado_conexion_usb(estado_usb); // Se fija en el estado de la conexión usb.
for(i=0;i<=7;i++){// ciclo de adquicicion de datos analogicos
config_adcon2(i); // Configuramos el conversor analógico digital.
delay_ms(10); // Espera 10 mseg a que la convercion acabe.
switch (i)//guarda cada convercion en una variable diferente.
{
case 1:
valorA = read_adc(); // El resultado de la conversión lo guarda en la variable valorA.
break;
case 2:
valorB = read_adc(); // El resultado de la conversión lo guarda en la variable valorB.
break;
case 3:
valorC = read_adc(); // El resultado de la conversión lo guarda en la variable valorC.
break;
case 4:
valorD = read_adc(); // El resultado de la conversión lo guarda en la variable valorD.
break;
case 5:
valorE = read_adc(); // El resultado de la conversión lo guarda en la variable valorE.
break;
case 6:
valorF = read_adc(); // El resultado de la conversión lo guarda en la variable valorF.
break;
case 7:
valorG = read_adc(); // El resultado de la conversión lo guarda en la variable valorG.
break;
case 8:
valorH = read_adc(); // El resultado de la conversión lo guarda en la variable valorH.
break;
default:
break;
}
}
if(usb_cdc_connected()){ // Si está conectado entonces....
// Espera a detectar una transmisión de la PC (Set_Line_Coding).
if (usb_enumerated()){ // aquí se enumera el dispositivo por el host y despúes sale.
// En espera de nuevos caracteres en el buffer de recepción.
switch (usb_cdc_kbhit())//dependiendo de la peticion del host es la accion que realizara.
{
case 'a'://¿lo que llegó fué el caracter a?
printf(usb_cdc_putc,"%Lx", valorA); // envia el ADRESH:ADRESL al HOST
break;
case 'b'://¿lo que llegó fué el caracter b?
printf(usb_cdc_putc,"%Lx", valorB); // envia el ADRESH:ADRESL al HOST
break;
case 'c'://¿lo que llegó fué el caracter c?
printf(usb_cdc_putc,"%Lx", valorC); // envia el ADRESH:ADRESL al HOST
break;
case 'd'://¿lo que llegó fué el caracter d?
printf(usb_cdc_putc,"%Lx", valorD); // envia el ADRESH:ADRESL al HOST
break;
case 'e': //¿lo que llegó fué el caracter e?
printf(usb_cdc_putc,"%Lx", valorE); // envia el ADRESH:ADRESL al HOST
break;
case 'f': //¿lo que llegó fué el caracter f?
printf(usb_cdc_putc,"%Lx", valorF); // envia el ADRESH:ADRESL al HOST
break;
case 'g': //¿lo que llegó fué el caracter g?
printf(usb_cdc_putc,"%Lx", valorG); // envia el ADRESH:ADRESL al HOST
break;
case 'h'://¿lo que llegó fué el caracter h?
printf(usb_cdc_putc,"%Lx", valorH); // envia el ADRESH:ADRESL al HOST
break;
case 'A'://¿lo que llegó fué el caracter A?
printf(usb_cdc_putc,"%d",PIN_A4);// envia el VALOR DEL PIN_A4 al HOST
break;
case 'B'://¿lo que llegó fué el caracter B?
printf(usb_cdc_putc,"%d",PIN_C0);// envia el VALOR DEL PIN_C0 al HOST
break;
case 'C'://¿lo que llegó fué el caracter C?
printf(usb_cdc_putc,"%d",PIN_C0);// envia el VALOR DEL PIN_C0 al HOST
break;
case 'D'://¿lo que llegó fué el caracter D?
printf(usb_cdc_putc,"%d",PIN_C1);// envia el VALOR DEL PIN_C1 al HOST
break;
case 'E'://¿lo que llegó fué el caracter E?
printf(usb_cdc_putc,"%d",PIN_C2);// envia el VALOR DEL PIN_C2 al HOST
break;
case 'F'://¿lo que llegó fué el caracter F?
printf(usb_cdc_putc,"%d",PIN_B4);// envia el VALOR DEL PIN_B4 al HOST
break;
case 'G'://¿lo que llegó fué el caracter G?
printf(usb_cdc_putc,"%d",PIN_B7);// envia el VALOR DEL PIN_B7 al HOST
break;
case 'H'://¿lo que llegó fué el caracter H?
printf(usb_cdc_putc,"%d",PIN_C0);// envia el VALOR DEL PIN_C0 al HOST
break;
case 'L'://¿lo que llegó fué el caracter L?paso a la izquierda
output_low(PIN_B5); // bit de sentido de giro, conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_low(PIN_B6); // desenergiza bobina, conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_high(PIN_B6); // energiza bobina , conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_low(PIN_B6); // completa el paso, conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
break;
case 'R'://¿lo que llegó fué el caracter R?paso a la derecha
output_high(PIN_B5); // bit de sentido de giro, conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_low(PIN_B6); //desenergiza bobina, conectada al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_high(PIN_B6); // energiza bobina , conectada al pin RB6.
delay_ms(100); // Espera 100 mseg.
output_low(PIN_B6); // completa el paso, conectado al pin RB6.
delay_ms(100); // Espera 100 mseg.
break;
default:
break;
}
}
}
}
}
//***********************************************
// Esta función, nos indica mediante 1 diodo LED conectados al
// puerto RB0. El estado de conexión del puerto usb.
// Conectado: Enciende el LED VERDE.
//Desconectado: de apaga el LED VERDE.
//***********************************************
void estado_conexion_usb(short bandera){
if(bandera){
output_high(PIN_B0); // Enciende LED VERDE.
}else{
output_low(PIN_B0); // Apaga LED VERDE.
}
}
// Esta función configura el registro ADCON2.
void config_adcon2(int num) {
if(num>=5){//necesidad de implementacion por vercion del pic ya que se salta algunos puetos analogos
num=num+3;
}
#asm
movlw 0b10111110 ;justificacion_derecha,20Tad,Fosc/64
iorwf 0xFC0,1 ; direccion de ADCON2
#endasm
set_adc_channel(num); // Selecciono el canal de conversión.
}
chipichape dijo:hola. para los que hayan trabajado con el pic18f4550, como se configura el ADC y que quieren decir estos bits:
#define ADC_ADFM_RIGHT 0x80
#define ADC_ACQT_2TAD 0x38
Me refiero a porque le ponen 0x80 y 0x38, que sentido tiene esto, la verdad no le veo ninguna utilidad,
y otra cosa, si le ponemos 20TAD en lugar de 2TAD en que afecta?