Source: http://www.ucontrol.com.ar/forosmf/jal-y-jalv2/ejemplos-de-programacio-con-jalv2-y-multiboard-pic-trainer/
Timestamp: 2016-02-10 02:33:30+00:00

Document:
Ejemplos de programación con JALv2 y Multiboard PIC Trainer
Febrero 09, 2016, 11:33:30 Bienvenido(a), Visitante. Por favor, ingresa o regístrate.¿Perdiste tu email de activación?	1 Hora
uControl > Programación de Microcontroladores > JAL y JALv2 (Moderador: Felixls) > Ejemplos de programación con JALv2 y Multiboard PIC Trainer
Tema: Ejemplos de programación con JALv2 y Multiboard PIC Trainer (Leído 10571 veces)
Sexo: Mensajes: 10746
« : Enero 25, 2011, 03:24:30 »
Hola!Este hilo va a contener una serie de ejemplos de programación con el lenguaje JALv2. No hay demasiado material sobre este compilador, así que es posible que esta pequeña colección de ejemplos sea un buen punto de partida para comenzar a utilizarlo.Los ejemplos van a utilizar solamente el compilador JALv2 (gratuito) y la placa entrenadora Multiboard PIC Trainer (gratuita) diseñada por Felixls. Para poder llevar a cabo los diferentes ejercicios utilizaremos algunos módulos del PIC TRAINER de uControl (gratuito también).El PIC que voy a utilizar como base para los ejemplos es el PIC18F4550, que tiene mucho para ofrecer por muy poco dinero Por supuesto, nada impide que -en la mayoría de los ejemplos- utilices prácticamente cualquier otro micro, simplemente cambiando el encabezado del código fuente y volviendo a compilar.Están invitados a colaborar con sus propios ejemplos o plantear sus inquietudes. INDICE DE EJEMPLOS:- 001 - LED parpadeando con 18F4550- 002 - 2 LEDs parpadeando alternadamente con 18F4550- 003 - 8 LEDs "Coche Fantástico" con PIC18F4550 (Versión 1)- 004 - PWM con un Led. PIC16F877A (versión 1)- 005 - 8 LEDs "Coche Fantástico" con PIC18F4550 (Versión 2)LCD y GLCD:- LCD Alfanumérico - Ejemplo 01- LCD Alfanumérico - Ejemplo 02http://www.youtube.com/v/B80iB-DvCRY http://www.youtube.com/v/wM3OFNscOoE http://www.youtube.com/v/gq6GUxe5GzYEsta es la disposición de los pines en los conectores de la Multiboard PIC Trainer:
SDC13194.JPG (178.7 KB - descargado 2524 veces.)
Pantallazo-2.png (33.96 KB - descargado 3064 veces.)
« Última modificación: Febrero 04, 2011, 04:13:49 por Ariel »
Re: Ejemplos de programación con JALv2 y Multiboard PIC Trainer
« Respuesta #1 : Enero 25, 2011, 03:29:18 »
001 - LED parpadeando con 18F4550Este es el "hola mundo" de los programas para PIC: un led que enciende y apaga continuamente, controlado mediante un pin E/S del microcontrolador. Esta es la parte más importante del programa:-- Incluyo la librería que contiene las rutinas de demoras:include delay-- Configuro los pines de E/S------------------------------------------------enable_digital_io() -- Todos los pines configurados como E/Salias LED1 is pin_b7 -- LED1 será equivalente al pin 40 (RB7)pin_b7_direction = output -- El pin que tiene el LED es una SALIDALED1 = off -- Apago el LED1-- Declaro las constantes y variables a utilizar en el programa -------------const word tiempo_encendido = 500 -- Milisegundos que permanecerá encendido.const word tiempo_apagado = 500 -- Milisegundos que permanecerá apagado.-- ---------------------------------------------------------------------------- Comienzo del bucle principal del programa -- --------------------------------------------------------------------------forever loop -- Bucle que se repite indefinidamente LED1 = on --Enciendo el LED1... delay_1ms(tiempo_encendido) --Y espero el tiempo prefijado LED1 = off --Apago el LED1... delay_1ms(tiempo_apagado) --Y espero el tiempo prefijadoend loop -- Fin del bucle.- Fin del programaComo puede verse, el código es muy simple y está comentado. Si tienes alguna duda, utiliza el hilo especial para los comentarios y sugerencias Veamos que es lo que hace cada una de las instrucciones que hemos utilizado:- En primer lugar, tenemos que saber que cada linea que comienza con "--" o con ";" es un comentario y es ignorada por el compilador. Como ocurre en cualquier lenguaje de programación, es muy conveniente utilizar los comentarios para documentar el código que uno escribe. Esto lo hace mucho más legible para los demás (y para uno mismo )- include delay le indica al compilador que incluya la libreria "delay". En ella (puedes ver su código dentro de la carpeta "jalv2/lib/" de tu ordenador) se encuentran las rutinas encargadas de proporcionar retardos.- enable_digital_io() hace que todos los pines del micro se comporten como pines de E/S digital. De esa manera, se deshabilitan comparadores, conversores A/D y cualquier otra función semejante.- alias LED1 is pin_b7 hace que podamos utilizar la cadena "LED1" en lugar de "pin_b7". Esto se denomina "alias" y es un recurso muy interesante, ya que si nuestro hardware cambia (por ejemplo, conectando el led al pin RD3) simplemente hay que cambiar esa linea y el resto del programa permanece inalterado.- pin_b7_direction = output configura el pin en que se encuentra el led (pin_b7) como salida.- LED1 = off hace que la salida en la que está el led -fijate: hemos utilizado el alias en lugar de pin_b7- se ponga en cero. JALv2 proporciona muchas formas equivalentes de decir "cero": off, low, 0 y false son algunas de ellas.- const word tiempo_encendido = 500 crea una constante -una región de la memoria del micro en la que se alojará un valor que permanecerá inalterado a lo largo de todo el programa- del tipo "word" (dos bytes) llamada "tiempo_encendido" y le asigna el valor (decimal) "500".- forever loop .... end loop es una estructura de control. Todas las sentencias que se encuentran entre una y otra de estas instrucciones se repetirán indefinidamente. Otros lenguajes de programación permiten esto a partir de sentencias del tipo "do" o "while", pero JALv2 posee una estructura especialmente creada para ello. Es posible salir de este loop, como veremos más adelante.- LED1 = on es lo opuesto a "LED1 = off": hace que la salida en la que está el led se ponga en uno. JALv2 proporciona muchas formas equivalentes de decir "uno": on, high, 1 y true son algunas de ellas.- delay_1ms(tiempo_encendido) utiliza la función "delay_1ms()" de la libreria "delay" para crear una demora de la cantidad de milisegundos que indica el valor de "tiempo_encendido" (en este caso 500, o lo que es lo mismo, medio segundo).Este es el resultado:http://www.youtube.com/v/B80iB-DvCRYNOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
18F4550_001.jal (5.16 KB - descargado 231 veces.)
18F4550_001.hex (0.39 KB - descargado 213 veces.)
SDC13191.JPG (219.81 KB - descargado 2277 veces.)
« Última modificación: Enero 31, 2011, 04:51:04 por Ariel »
« Respuesta #2 : Enero 25, 2011, 04:02:10 »
002 - 2 LEDs parpadeando alternadamente con 18F4550Una pequeña "evolución" del ejemplo anterior. Ahora tenemos dos LEDs encendiendo alternadamente. Esta es la parte más importante del programa:-- Incluyo la librería que contiene las rutinas de demoras:include delay-- Configuro los pines de E/S------------------------------------------------enable_digital_io() -- Todos los pines configurados como E/Salias LED1 is pin_b7 -- LED1 será equivalente al pin 40 (RB7)alias LED2 is pin_b6 -- LED2 será equivalente al pin 39 (RB6)pin_b7_direction = output -- El pin que tiene el LED1 es una SALIDApin_b6_direction = output -- El pin que tiene el LED2 es una SALIDALED1 = off -- Apago el LED1LED2 = off -- Apago el LED2-- Declaro las constantes y variables a utilizar en el programa -------------const word tiempo = 500 -- Milisegundos entre cambios.-- ---------------------------------------------------------------------------- Comienzo del bucle principal del programa -- --------------------------------------------------------------------------forever loop -- Bucle que se repite indefinidamente LED1 = on --Enciendo el LED1... LED2 = off --y apago el LED2. delay_1ms(tiempo) --Espero el tiempo prefijado LED1 = off --Apago el LED1... LED2 = on --y enciendo el LED2. delay_1ms(tiempo) --Espero el tiempo prefijadoend loop -- Fin del bucle.Como puede verse, el código es muy simple y está comentado. Si tienes alguna duda, utiliza el hilo especial para los comentarios y sugerencias No hemos utilizado más instrucciones que las vistas en el ejemplo anterior, así que directamente te mostramos el resultado:http://www.youtube.com/v/wM3OFNscOoENOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
SDC13195.JPG (81.6 KB - descargado 2240 veces.)
18F4550_002.jal (5.46 KB - descargado 220 veces.)
18F4550_002.hex (0.42 KB - descargado 193 veces.)
« Última modificación: Enero 31, 2011, 04:51:26 por Ariel »
« Respuesta #3 : Enero 25, 2011, 08:36:57 »
003 - 8 LEDs "Coche Fantástico" con PIC18F4550 (Versión 1)Este es el clásico efecto del punto luminoso que "va y viene", como el juego de luces que tenía el coche de la serie "El coche fantástico" en su frente. Esta es la forma de hacerlo "a lo bruto", controlando individualmente cada LED. Es posible hacerlo con las instrucciones vistas en los ejemplos anteriores. En el ejemplo siguiente veremos como hacer lo mismo de una forma mucho más eficiente.Este es el código fuente del programa:Código:---------------------------------------------------------------------------------- Ejemplos de programación con JALv2---- Ejemplo 003 c/PIC18F4550 y Multiboard PIC Trainer-- Más detalles en http://www.ucontrol.com.ar/forosmf/jal-y-jalv2/---------------------------------------------------------------------------------- Descripcion: -- 8 LEDs en el portB realizan el típico movimiento del "coche fantástico"-- sin sutilezas (ver ejemplo 004)------------------------------------------------------------------------------------ Módulos utilizados:---- Multiboard Pic Trainer -- (http://www.ucontrol.com.ar/forosmf/proyectos-con-pic/multiboard-pic-trainer-2-0/)---- Módulo 8 E/S -- (http://www.ucontrol.com.ar/forosmf/circuiteca-la-biblioteca-de-circuitos-y-proyectos-de-ucontrol/pic-trainer/msg103/#msg103)------------------------------------------------------------------------------------ Resumen uso E/S:-- -- #Pin | Puerto | Función-- ----------------------------------------------------------------------------- 33 | RB0-RB7| Ochos LEDs, cada uno de ellos con el anodo conectado a uno de-- a | | los pines del PIC y el cátodo a GND a través de una R de 220-- 40 | RB7 | ohms.-- | | -- ---------------------------------------------------------------------------- -- Oscilador con cristal de 20MHz---------------------------------------------------------------------------------- Configuración de módulos del chip y fuses-----------------------------------include 18f4550pragma target clock 48_000_000pragma target PLLDIV P5 -- divide por 5 - 20MHZ_INPUTpragma target CPUDIV P2 -- OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2pragma target OSC HS_PLLpragma target FCMEN DISABLEDpragma target IESO DISABLEDpragma target PWRTE DISABLED -- power up timerpragma target VREGEN ENABLED -- USB voltage regulatorpragma target VOLTAGE V20 -- brown out voltagepragma target BROWNOUT DISABLED -- no brownout detectionpragma target WDTPS P32K -- watch dog saler settingpragma target WDT DISABLED -- no watchdogpragma target CCP2MUX pin_C1 -- CCP2 pinpragma target PBADEN DIGITAL -- digital input port<0..4>pragma target LPT1OSC LOW_POWER -- low power timer 1pragma target MCLR EXTERNAL -- master reset on RE3pragma target STVR DISABLED -- reset on stack over/under flowpragma target LVP DISABLED -- no low-voltage programmingpragma target XINST ENABLED -- extended instruction setpragma target DEBUG DISABLED -- background debuggingpragma target CP0 DISABLED -- code block 0 not protectedpragma target CP1 DISABLED -- code block 1 not protectedpragma target CP2 DISABLED -- code block 2 not protectedpragma target CP3 DISABLED -- code block 3 not protectedpragma target CPB DISABLED -- bootblock code not write protectedpragma target CPD DISABLED -- eeprom code not write protectedpragma target WRT0 DISABLED -- table writeblock 0 not protectedpragma target WRT1 DISABLED -- table write block 1 not protectedpragma target WRT2 DISABLED -- table write block 2 not protectedpragma target WRT3 DISABLED -- table write block 3 not protectedpragma target WRTB DISABLED -- bootblock not write protectedpragma target WRTD DISABLED -- eeprom not write protectedpragma target WRTC DISABLED -- config not write protectedpragma target EBTR0 DISABLED -- table read block 0 not protectedpragma target EBTR1 DISABLED -- table read block 1 not protectedpragma target EBTR2 DISABLED -- table read block 2 not protectedpragma target EBTR3 DISABLED -- table read block 3 not protectedpragma target EBTRB DISABLED -- boot block not protected-- Incluyo la librería que contiene las rutinas de demoras:include delay-- Configuro los pines de E/S ------------------------------------------------enable_digital_io() -- Todos los pines configurados como E/Salias LED0 is pin_b0 -- LED0 será equivalente a RB0alias LED1 is pin_b1 -- LED1 será equivalente a RB1alias LED2 is pin_b2 -- LED2 será equivalente a RB2alias LED3 is pin_b3 -- LED3 será equivalente a RB3alias LED4 is pin_b4 -- LED4 será equivalente a RB4alias LED5 is pin_b5 -- LED5 será equivalente a RB5alias LED6 is pin_b6 -- LED6 será equivalente a RB6alias LED7 is pin_b7 -- LED7 será equivalente a RB7PORTB_direction = 0x00 -- Todo el puerto B como salidasLED0 = off -- Apago el LED0LED1 = off -- Apago el LED1LED2 = off -- Apago el LED2LED3 = off -- Apago el LED3LED4 = off -- Apago el LED4LED5 = off -- Apago el LED5LED6 = off -- Apago el LED6LED7 = off -- Apago el LED7-- Declaro las constantes y variables a utilizar en el programa -------------const word tiempo = 100 -- Milisegundos entre cambios.-- ---------------------------------------------------------------------------- Comienzo del bucle principal del programa -- --------------------------------------------------------------------------forever loop -- Bucle que se repite indefinidamente	LED0 = on --Enciendo el LED0...	delay_1ms(tiempo) --Espero el tiempo prefijado	LED0 = off --Apago el LED0...	LED1 = on --Enciendo el LED1...	delay_1ms(tiempo) --Espero el tiempo prefijado	LED1 = off --Apago el LED1...	LED2 = on --y enciendo el LED2.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED2 = off --Apago el LED2...	LED3 = on --y enciendo el LED3.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED3 = off --Apago el LED3...	LED4 = on --y enciendo el LED4.	delay_1ms(tiempo) --Espero el tiempo prefijado	LED4 = off --Apago el LED4...	LED5 = on --y enciendo el LED5.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED5 = off --Apago el LED5...	LED6 = on --y enciendo el LED6.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED6 = off --Apago el LED6...	LED7 = on --y enciendo el LED7.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED7 = off --Apago el LED7...	--Aqui comienza la vuelta....	LED6 = on --Enciendo el LED6...	delay_1ms(tiempo) --Espero el tiempo prefijado	LED6 = off --Apago el LED6...	LED5 = on --y enciendo el LED5.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED5 = off --Apago el LED5...	LED4 = on --y enciendo el LED4.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED4 = off --Apago el LED4...	LED3 = on --y enciendo el LED3.	delay_1ms(tiempo) --Espero el tiempo prefijado	LED3 = off --Apago el LED3...	LED2 = on --y enciendo el LED25.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED2 = off --Apago el LED2...	LED1 = on --y enciendo el LED1.	delay_1ms(tiempo) --Espero el tiempo prefijadojado	LED1 = off --Apago el LED1...end loop -- Fin del bucle.-- Fin del programaEste es el resultado:http://www.youtube.com/v/gq6GUxe5GzYNOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
SDC13199.JPG (84.11 KB - descargado 2373 veces.)
Pantallazo-1.png (144.21 KB - descargado 2965 veces.)
18F4550_003.jal (7.66 KB - descargado 225 veces.)
18F4550_003.hex (0.96 KB - descargado 201 veces.)
« Última modificación: Enero 31, 2011, 04:51:52 por Ariel »
Sexo: Mensajes: 5565
« Respuesta #4 : Enero 26, 2011, 11:50:38 »
004 - PWM con un Led. PIC16F877A (versión 1)Vamos aumentando un poco la dificultad con una aplicación interesante. El PWM se utiliza para muchas cosas, entre ellas controlar la velocidad de un motor de CC, dar efecto a luces de CC.Código de programa.Nota: Este programa, está en la carpeta de sample del JAL. Lo único que hice fue comentar, en castellano, el programa y doy una pequeña explicación.Código:------------------------------------------------------------------- PWM CON UN LED--------------------------------------------------------------------- El circuito está formado un cristal de 20Mhz-- y un led en RC2------------------------------------------------------------------- Incluimos la librería del pic 16F877Ainclude 16f877apragma target clock 20_000_000 -- xtal frequencypragma target OSC hspragma target LVP disabledpragma target WDT disabled-- COnfiguración de los pines.alias lcd_bl is pin_c2alias lcd_bl_direction is pin_c2_direction enable_digital_io()-- Configuracíon PWMpin_ccp1_direction = outputinclude pwm_hardwarepwm_max_resolution(1)pwm1_on()forever loop var word i i = 0 -- Resolución del PWM de 10 bit (duty < 1024) while i < 1020 loop	-- Mientras i es menor a 1020 pwm1_set_dutycycle_highres(i)	-- cargamos el duty con el contenido de i _usec_delay(50000)	-- Demora. Regulamos la velocidad del PWM	-- Si es muy chica la demora, no se apreciarán los cambios	-- Si es muy grande la demora, tardará mucho en ir de 0V a 5V i = i + 10	-- Incrementamos en 10 la variable i.	-- Modificando el incremento, también variamos la velocidad de barrido	-- del PWM end loop while i > 0 loop	-- Aquí pasa lo mismo que el while anterior, pero en sentido inverso. pwm1_set_dutycycle_highres(i) _usec_delay(50000) i = i - 10 end loop _usec_delay(50000)	-- Tiempo de permanencia apagado el led una vez que terminó el ciclo anterior pwm1_off() _usec_delay(50000)	-- Tiempo de permanencia encendido del led una vez que terminó el ciclo anterior pwm1_on() -- Si estos valores son chicos, o se anula esta parte del programa, el led variará	-- continuamente. Si es muy grande la demora, el led permanecera bastante tiempo	-- encendido y apagado hasta comenzar un nuevo ciclo del PWMend loop El resultado:http://www.youtube.com/v/4Kc299xl1qYVolver al índice
« Última modificación: Enero 31, 2011, 07:02:36 por Leon Pic »
« Respuesta #5 : Enero 26, 2011, 03:21:26 »
005 - 8 LEDs "Coche Fantástico" con PIC18F4550 (Versión 2)Este es el clásico efecto del punto luminoso que "va y viene", como el juego de luces que tenía el coche de la serie "El coche fantástico" en su frente. Se ha implementado de una forma diferente a nuestro ejemplo 003 - 8 LEDs "Coche Fantástico" con PIC18F4550 (Versión 1), controlando todo el puerto B a la vez. Utilizamos algunas instrucciones nuevas, cuyo comportamiento explicamos luego de presentar el código fuente.Este es el código fuente del programa:Código:---------------------------------------------------------------------------------- Ejemplos de programación con JALv2---- Ejemplo 004 c/PIC18F4550 y Multiboard PIC Trainer-- Más detalles en http://www.ucontrol.com.ar/forosmf/jal-y-jalv2/---------------------------------------------------------------------------------- Descripcion: -- 8 LEDs en el portB realizan el típico movimiento del "coche fantástico"-- sin sutilezas (ver ejemplo 003)------------------------------------------------------------------------------------ Módulos utilizados:---- Multiboard Pic Trainer -- (http://www.ucontrol.com.ar/forosmf/proyectos-con-pic/multiboard-pic-trainer-2-0/)---- Módulo 8 E/S -- (http://www.ucontrol.com.ar/forosmf/circuiteca-la-biblioteca-de-circuitos-y-proyectos-de-ucontrol/pic-trainer/msg103/#msg103)------------------------------------------------------------------------------------ Resumen uso E/S:-- -- #Pin | Puerto | Función-- ----------------------------------------------------------------------------- 33 | RB0-RB7| Ochos LEDs, cada uno de ellos con el anodo conectado a uno de-- a | | los pines del PIC y el cátodo a GND a través de una R de 220-- 40 | RB7 | ohms.-- | | -- ---------------------------------------------------------------------------- -- Oscilador con cristal de 20MHz---------------------------------------------------------------------------------- Configuración de módulos del chip y fuses-----------------------------------include 18f4550pragma target clock 48_000_000pragma target PLLDIV P5 -- divide por 5 - 20MHZ_INPUTpragma target CPUDIV P2 -- OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2pragma target OSC HS_PLLpragma target FCMEN DISABLEDpragma target IESO DISABLEDpragma target PWRTE DISABLED -- power up timerpragma target VREGEN ENABLED -- USB voltage regulatorpragma target VOLTAGE V20 -- brown out voltagepragma target BROWNOUT DISABLED -- no brownout detectionpragma target WDTPS P32K -- watch dog saler settingpragma target WDT DISABLED -- no watchdogpragma target CCP2MUX pin_C1 -- CCP2 pinpragma target PBADEN DIGITAL -- digital input port<0..4>pragma target LPT1OSC LOW_POWER -- low power timer 1pragma target MCLR EXTERNAL -- master reset on RE3pragma target STVR DISABLED -- reset on stack over/under flowpragma target LVP DISABLED -- no low-voltage programmingpragma target XINST ENABLED -- extended instruction setpragma target DEBUG DISABLED -- background debuggingpragma target CP0 DISABLED -- code block 0 not protectedpragma target CP1 DISABLED -- code block 1 not protectedpragma target CP2 DISABLED -- code block 2 not protectedpragma target CP3 DISABLED -- code block 3 not protectedpragma target CPB DISABLED -- bootblock code not write protectedpragma target CPD DISABLED -- eeprom code not write protectedpragma target WRT0 DISABLED -- table writeblock 0 not protectedpragma target WRT1 DISABLED -- table write block 1 not protectedpragma target WRT2 DISABLED -- table write block 2 not protectedpragma target WRT3 DISABLED -- table write block 3 not protectedpragma target WRTB DISABLED -- bootblock not write protectedpragma target WRTD DISABLED -- eeprom not write protectedpragma target WRTC DISABLED -- config not write protectedpragma target EBTR0 DISABLED -- table read block 0 not protectedpragma target EBTR1 DISABLED -- table read block 1 not protectedpragma target EBTR2 DISABLED -- table read block 2 not protectedpragma target EBTR3 DISABLED -- table read block 3 not protectedpragma target EBTRB DISABLED -- boot block not protected-- Incluyo la librería que contiene las rutinas de demoras:include delay-- Configuro los pines de E/S ------------------------------------------------enable_digital_io() -- Todos los pines configurados como E/Sportb_direction = 0x00 -- Todo el puerto B como salidasportb = 0x01 -- Apago todo el puerto menos el bit 1-- Declaro las constantes y variables a utilizar en el programa -------------const word tiempo = 60 -- Milisegundos entre cambios.var byte i = 0 -- Variable auxiliar para el bucle "for"-- ---------------------------------------------------------------------------- Comienzo del bucle principal del programa -- --------------------------------------------------------------------------forever loop -- Bucle que se repite indefinidamente	--delay_1ms(tiempo) --Espero el tiempo prefijado for 7 loop portb = portb * 2 delay_1ms(tiempo) --Espero el tiempo prefijado	end loop -- Ahora, la vuelta... for 7 loop portb = portb / 2 delay_1ms(tiempo) --Espero el tiempo prefijado	end loopend loop -- Fin del bucle.-- Fin del programaVeamos cuales son las instrucciones u ordenes nuevas que hemos utilizado esta vez, y cual es su utilidad dentro del programa:- portb_direction = 0x00 hace que todo el puerto B quede configurado como salidas. El valor "0x00" es el responsable de esto. Si se quiere configurar con alguna combinacion en particular de pines como entrada y como salida, solo debes recordar que "0" es salida y "1" es entrada. - portb = 0x01 pone todos los pines del puerto B en cero (leds apagados), menos el bit 1, por lo que ese led queda encendido.- var byte i = 0 declara la variable "i" como tipo "byte" y le asigna el valor 0.- for 7 loop ... end loop es similar a la estructura "forever loop....end loop", con la diferencia que en lugar de repetirse indefinidamente solo lo hace siete veces.- portb = portb * 2 simplimiente multiplica el valor del portb por dos. Dado que su valor inicial es 1 (00000001), va a ir tomando los valores 2 (00000010), 4 (00000100), 8 (00001000), etc, hasta 128 (10000000). Dado que tenemos un led en cada salida, el efecto es que los leds se van encendiendo en secuencia, de derecha a izquierda, tal como necesitabamos.- portb = portb / 2 hace lo opuesto a la sentencia anterior: divide el valor del puerto b por 2, siete veces. Eso hace que el "1" se desplace desde la izquierda hasta la derecha. Bueno, bonito y barato Este es el resultado:http://www.youtube.com/v/JiZruD2HMSoNOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
18F4550_004.jal (5.32 KB - descargado 219 veces.)
18F4550_004.hex (0.52 KB - descargado 200 veces.)
Pantallazo.jpg (95.07 KB - descargado 2825 veces.)
« Última modificación: Enero 31, 2011, 04:52:17 por Ariel »
« Respuesta #6 : Enero 30, 2011, 03:58:54 »
006 - PWM con dos efectos seleccionable con 2 pulsadores (PIC16F877A)Este programa, es una modificación del anterior (PWM). Se le agregaron dos pulsadores el cual, el pulsador 1 selecciona el efecto 1 y el pulsador 2, selecciona el efecto 2. Una segunda pulsación del mismo pulsador, apaga el LED.El código o firmware.Código:------------------------------------------------------------------- PWM CON UN LED Y 2 PULSADORES PARA CAMBIAR 2 DIFERENTES EFECTOS--------------------------------------------------------------------- El circuito está formado un cristal de 20Mhz-- y un led en RC2------------------------------------------------------------------- Incluimos la librería del pic 16F877Ainclude 16f877apragma target clock 20_000_000 -- xtal frequencypragma target OSC hspragma target LVP disabledpragma target WDT disabled-- COnfiguración de los pines.alias lcd_bl is pin_c2alias lcd_bl_direction is pin_c2_directionalias pulsador1 is pin_c0alias pulsador2 is pin_c1alias pulsador1_direction is pin_c0_directionalias pulsador2_direction is pin_c1_directionalias pulsador3_direction is pin_c3_direction enable_digital_io()-- Configuracíon PWMpin_ccp1_direction = outputpulsador1 = inputpulsador2 = inputinclude pwm_hardwarepwm_max_resolution(1)pwm1_on()var word pulsadorforever loop	var dword b	b = 0 while b < 0xFFFF loop	-- Realizamos una pequeña demora para escanear el teclado. Aproximadamente medio segundo	if pulsador1 != 0 then	-- Corriendo a 20Mhz	if pulsador == 1 then	-- Escaneamos el teclado. Si el pulsador en C0 es 1, y si la variable pulsador es igual a 1	pulsador = 0	-- Lo colocamos en 0	else	-- En cambio	pulsador = 1	-- Lo ponemos es 1.	end if	-- Lo que logramos aquí, es que con el mismo pulsador prendemos o apagamos el efecto elegido	end if	if pulsador2 != 0 then	-- Idem anterior pero con el pulsador conectado a C1.	if pulsador == 2 then	pulsador = 0	else	pulsador = 2	end if	end if	b = b + 1	end loop var word i i = 0	pwm1_on() ----------------------------------------------------------------------------------- Primer efecto. Se elige con el pulsador 1---------------------------------------------------------------------------------	if pulsador == 1 then -- Resolución del PWM de 10 bit (duty < 1024) while i < 1020 loop	-- Mientras i es menor a 1020 pwm1_set_dutycycle_highres(i)	-- cargamos el duty con el contenido de i _usec_delay(50000)	-- Demora. Regulamos la velocidad del PWM	-- Si es muy chica la demora, no se apreciarán los cambios	-- Si es muy grande la demora, tardará mucho en ir de 0V a 5V i = i + 10	-- Incrementamos en 10 la variable i.	-- Modificando el incremento, también variamos la velocidad de barrido	-- del PWM end loop	-- Sale del While cuando i = a 1020, mientras sea menor, se repite el while. while i > 0 loop	-- Aquí pasa lo mismo que el while anterior, pero en sentido inverso. pwm1_set_dutycycle_highres(i)	-- Recordemos que en este punto i = 1020 _usec_delay(50000) i = i - 10 end loop _usec_delay(50000)	-- Tiempo de permanencia apagado el led una vez que terminó el ciclo anterior pwm1_off() _usec_delay(50000)	-- Tiempo de permanencia encendido del led una vez que terminó el ciclo anterior pwm1_on() -- Si estos valores son chicos, o se anula esta parte del programa, el led variará	-- continuamente. Si es muy grande la demora, el led permanecera bastante tiempo	end if	-- encendido y apagado hasta comenzar un nuevo ciclo del PWM----------------------------------------------------------------------------------- Segundo efecto. Se elige con el pulsador 2---------------------------------------------------------------------------------	if pulsador == 2 then	while i < 1020 loop	pwm1_set_dutycycle_highres(i)	-- Noten que la única diferencia en esta rutina de PWM	_usec_delay(10000)	-- Cambia los valores de demora	i = i + 20	-- y la incrementación de los valores para el PWM	end loop	_usec_delay(1000)	pwm1_off()	end if	if pulsador == 0 then	pwm1_off()	end ifend loopVeamos las instrucciones nuevas que hemos utilizado aquí:if pulsador1 != 0 then if pulsador == 1 then -- Si el pulsador en C0 es 1, y si la variable pulsador es igual a 1 pulsador = 0 -- Lo colocamos en 0 else -- En cambio pulsador = 1 -- Lo ponemos es 1. end if -- Lo que logramos aquí, es que con el mismo pulsador prendemos o apagamos el efecto elegido end ifEste se lo conoce como Toggle. Lo que hace es, leer el estado del pulsador1 para ver si se pulsó. En caso negativo, sale del IF sin hacer nada, pero si es afirmativo (la pulsación) lee el valor en pulsador para cambiarle por el valor opuesto en el bit 0.La variable pulsador, al ser de tipo word, está compuesto por 8 bit enumerados del 0 al 7.1 en binario es 000000010 en binario es 00000000while b < 0xFFFF loopLo que hace, es permanecer dentro del while hasta que b sea igual o mayor a 0xFFFF. La condición dice que, mientras b sea menor a 0xFFFF te mantenés aquí. Como deducción, cuando b sea igual o mayor a 0xFFFF dejará de cumplir dicha condición y saldrá del while (mientras)El resultado:http://www.youtube.com/v/aGoqZ59SHz8Adjuntado está el hex y el programa.Volver al índice
pwm.jal (4.07 KB - descargado 264 veces.)
pwm.hex (2 KB - descargado 201 veces.)
« Última modificación: Enero 31, 2011, 07:04:18 por Leon Pic »
« Respuesta #7 : Enero 31, 2011, 04:37:34 »
LCD Alfanumérico - Ejemplo 01Utilizar con JALv2 un display alfanumérico -de cualquier tamaño- es muy fácil. Basta con elegir 6 pines cualesquiera del micro para conectar el LCD (RS, E, D4,D5,D6 y D7) -o 10 si queremos una conexión de 8 bits), configurarlos adecuadamente, y enviar el texto que se quiere mostrar.En este primer ejemplo veremos como incluir la librería correspondiente, declarar los pines involucrados (en modo 4 bits de datos) y mostrar cadenas de texto en el LCD. Este es el código fuente del programa:Código:-- Configuración de módulos del chip y fuses-----------------------------------include 18f4550pragma target clock 48_000_000pragma target PLLDIV P5 -- divide por 5 - 20MHZ_INPUTpragma target CPUDIV P2 -- OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2pragma target OSC HS_PLLpragma target FCMEN DISABLEDpragma target IESO DISABLEDpragma target PWRTE DISABLED -- power up timerpragma target VREGEN ENABLED -- USB voltage regulatorpragma target VOLTAGE V20 -- brown out voltagepragma target BROWNOUT DISABLED -- no brownout detectionpragma target WDTPS P32K -- watch dog saler settingpragma target WDT DISABLED -- no watchdogpragma target CCP2MUX pin_C1 -- CCP2 pinpragma target PBADEN DIGITAL -- digital input port<0..4>pragma target LPT1OSC LOW_POWER -- low power timer 1pragma target MCLR EXTERNAL -- master reset on RE3pragma target STVR DISABLED -- reset on stack over/under flowpragma target LVP DISABLED -- no low-voltage programmingpragma target XINST ENABLED -- extended instruction setpragma target DEBUG DISABLED -- background debuggingpragma target CP0 DISABLED -- code block 0 not protectedpragma target CP1 DISABLED -- code block 1 not protectedpragma target CP2 DISABLED -- code block 2 not protectedpragma target CP3 DISABLED -- code block 3 not protectedpragma target CPB DISABLED -- bootblock code not write protectedpragma target CPD DISABLED -- eeprom code not write protectedpragma target WRT0 DISABLED -- table writeblock 0 not protectedpragma target WRT1 DISABLED -- table write block 1 not protectedpragma target WRT2 DISABLED -- table write block 2 not protectedpragma target WRT3 DISABLED -- table write block 3 not protectedpragma target WRTB DISABLED -- bootblock not write protectedpragma target WRTD DISABLED -- eeprom not write protectedpragma target WRTC DISABLED -- config not write protectedpragma target EBTR0 DISABLED -- table read block 0 not protectedpragma target EBTR1 DISABLED -- table read block 1 not protectedpragma target EBTR2 DISABLED -- table read block 2 not protectedpragma target EBTR3 DISABLED -- table read block 3 not protectedpragma target EBTRB DISABLED -- boot block not protected-- Incluyo la librería que contiene las rutinas de demoras:include delay-- Configuro los pines de E/S ------------------------------------------------enable_digital_io() -- Todos los pines como I/O digitales-- Declaro las constantes y variables a utilizar en el programa -------------portb_direction = 0x00 -- Todo el puerto B como salidasportb = 0x01 -- Apago todo el puerto menos el bit 1 -- Pin usado como test - se puede obviar.var byte i = 0 -- Variable auxiliar para el bucle "for"-- Defino todo lo relacionado con el LCDconst byte LCD_ROWS = 4 -- LCD de 4 lineasconst byte LCD_CHARS = 20 -- y 20 caracteres por lineaalias lcd_en is pin_D2 -- Pin E del LCD alias lcd_rs is pin_D1 -- Pin RS del LCDalias lcd_dataport is portD_high -- 4 data pinsportD_direction = all_output -- Todo el puerto D como salidas-- Cadenas a mostrar:var byte line1[LCD_CHARS] = "PRACTICAS CON JAL v2"var byte line2[LCD_CHARS] = "LCD alfanum. de 4x20"var byte line3[LCD_CHARS] = "--------------------"var byte line4[LCD_CHARS] = "www.ucontrol.com.ar "-- ---------------------------------------------------------------------------- Incluyo librerias e inicializo LCD:-- --------------------------------------------------------------------------include lcd_hd44780_4 -- Incluyo la libreria del LCDlcd_init() -- e inicializo el controlador del LCD--------------------------------------------------------------------------------- Comienza el programa en si-------------------------------------------------------------------------------lcd_clear_screen() -- Limpio la pantallafor LCD_CHARS using i loop	lcd_cursor_position(0,i) --Coloco el cursor en su sitio...	lcd_write_char(line1[i]) --y muestro el caracter correspondiente	lcd_cursor_position(1,i) --Idem, segunda linea	lcd_write_char(line2[i]) lcd_cursor_position(2,i) --Idem, tercera linea	lcd_write_char(line3[i]) lcd_cursor_position(3,i) --Idem, cuarta linea	lcd_write_char(line4[i]) end loop	-- Fin del programaVeamos cuales son las instrucciones u ordenes nuevas que hemos utilizado esta vez, y cual es su utilidad dentro del programa:- Las lineasCódigo:const byte LCD_ROWS = 4 -- LCD de 4 lineasconst byte LCD_CHARS = 20 -- y 20 caracteres por lineadefinen las dimensiones de nuestro LCD alfanumérico. Puede ser de una a 4 lineas, de 8 a 40 columnas.- Las lineas siguientes:Código:alias lcd_en is pin_D2 -- Pin E del LCD alias lcd_rs is pin_D1 -- Pin RS del LCDalias lcd_dataport is portD_high -- 4 data pinsportD_direction = all_output -- Todo el puerto D como salidasdefinen que pines controlan el LCD. En este caso, todos pertenecen al puerto D, que ha sido definido completamente como salidas. Los cuatro pines de datos son D4,D5,D6 y D7, que como representan la mitad superior del puerto, se declara con "lcd_dataport is portD_high". Después veremos que pueden utilizarse 4 pines cualquiera para ello, definiéndolos uno por uno.- include lcd_hd44780_4 incluye en nuestro proyecto la libreria correspondiente al control del LCd en modo 4 bits.- Asi asignamos las cadenas de cada linea:Código:var byte line1[LCD_CHARS] = "PRACTICAS CON JAL v2"var byte line2[LCD_CHARS] = "LCD alfanum. de 4x20"var byte line3[LCD_CHARS] = "--------------------"var byte line4[LCD_CHARS] = "www.ucontrol.com.ar "- lcd_init() inicializa el LCD.- lcd_clear_screen() borra completamente la plantalla.- Finalmente, el bucle siguiente muestra los caracteres en la pantalla. Notesé la instrucción lcd_cursor_position(x,y) que mueve el cursos a la posición deseada, y lcd_write_char(x) que escribe un caracter en la posición que se encuentra el cursor.Código:for LCD_CHARS using i loop	lcd_cursor_position(0,i) --Coloco el cursor en su sitio...	lcd_write_char(line1[i]) --y muestro el caracter correspondiente	lcd_cursor_position(1,i) --Idem, segunda linea	lcd_write_char(line2[i]) lcd_cursor_position(2,i) --Idem, tercera linea	lcd_write_char(line3[i]) lcd_cursor_position(3,i) --Idem, cuarta linea	lcd_write_char(line4[i]) end loop	Este es el resultado:NOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
SDC13216.JPG (91.2 KB - descargado 2099 veces.)
SDC13218.JPG (78.52 KB - descargado 2016 veces.)
18F4550_005.jal (4.84 KB - descargado 229 veces.)
18F4550_005.hex (3.11 KB - descargado 202 veces.)
« Última modificación: Enero 31, 2011, 04:49:36 por Ariel »
« Respuesta #8 : Febrero 04, 2011, 04:00:46 »
LCD Alfanumérico - Ejemplo 02Utilizar con JALv2 un display alfanumérico -de cualquier tamaño- es muy fácil. Ya vimos como hacerlo en un ejemplo anterior, pero ahora, vamos a ver como utilizar la librería "print.jal" para mostrar valores numéricos en cualquier base y cadenas de texto. En este segundo ejemplo incluir la librería correspondiente, declarar los pines involucrados (en modo 4 bits de datos) y mostrar cadenas de texto en el LCD. Este es el código fuente del programa:Código:-- Configuración de módulos del chip y fuses-----------------------------------include 18f4550pragma target clock 48_000_000pragma target PLLDIV P5 -- divide por 5 - 20MHZ_INPUTpragma target CPUDIV P2 -- OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2pragma target OSC HS_PLLpragma target FCMEN DISABLEDpragma target IESO DISABLEDpragma target PWRTE DISABLED -- power up timerpragma target VREGEN ENABLED -- USB voltage regulatorpragma target VOLTAGE V20 -- brown out voltagepragma target BROWNOUT DISABLED -- no brownout detectionpragma target WDTPS P32K -- watch dog saler settingpragma target WDT DISABLED -- no watchdogpragma target CCP2MUX pin_C1 -- CCP2 pinpragma target PBADEN DIGITAL -- digital input port<0..4>pragma target LPT1OSC LOW_POWER -- low power timer 1pragma target MCLR EXTERNAL -- master reset on RE3pragma target STVR DISABLED -- reset on stack over/under flowpragma target LVP DISABLED -- no low-voltage programmingpragma target XINST ENABLED -- extended instruction setpragma target DEBUG DISABLED -- background debuggingpragma target CP0 DISABLED -- code block 0 not protectedpragma target CP1 DISABLED -- code block 1 not protectedpragma target CP2 DISABLED -- code block 2 not protectedpragma target CP3 DISABLED -- code block 3 not protectedpragma target CPB DISABLED -- bootblock code not write protectedpragma target CPD DISABLED -- eeprom code not write protectedpragma target WRT0 DISABLED -- table writeblock 0 not protectedpragma target WRT1 DISABLED -- table write block 1 not protectedpragma target WRT2 DISABLED -- table write block 2 not protectedpragma target WRT3 DISABLED -- table write block 3 not protectedpragma target WRTB DISABLED -- bootblock not write protectedpragma target WRTD DISABLED -- eeprom not write protectedpragma target WRTC DISABLED -- config not write protectedpragma target EBTR0 DISABLED -- table read block 0 not protectedpragma target EBTR1 DISABLED -- table read block 1 not protectedpragma target EBTR2 DISABLED -- table read block 2 not protectedpragma target EBTR3 DISABLED -- table read block 3 not protectedpragma target EBTRB DISABLED -- boot block not protected-- Configuro los pines de E/S --------------------------------------------------enable_digital_io() -- Todos los pines como I/O digitales--Constantes a utilizar en el programa -----------------------------------------const byte LCD_ROWS = 4 -- LCD de 4 lineasconst byte LCD_CHARS = 20 -- y 20 caracteres por linea-- Variables a utilizar en el programa -----------------------------------------var byte i = 0 -- Variables auxiliares para bucles -- Defino E/S relacionadas con el LCDalias lcd_en is pin_D2 -- Pin E del LCD alias lcd_rs is pin_D1 -- Pin RS del LCDalias lcd_dataport is portD_high -- 4 data pinsportD_direction = all_output -- Todo el puerto D como salidas-- ...y lo inicializo:include lcd_hd44780_4 -- Incluyo la libreria del LCDlcd_init() -- e inicializo su controlador-- Cadenas a mostrar: var byte line1[LCD_CHARS] = "Probando libreria de"var byte line2[LCD_CHARS] = "JALv2 ( print.jal )"var byte line3[LCD_CHARS] = "www.ucontrol.com.ar "var byte line4[LCD_CHARS] = "Visualiza numeros en"var byte line5[LCD_CHARS] = " Decimal: "var byte line6[LCD_CHARS] = "Hexadecimal: "var byte line7[LCD_CHARS] = " Binario: "var byte line8[LCD_CHARS] = "Eso a sido todo. :)"---------------------------------------------------------------------------------- Incluyo librerías:--------------------------------------------------------------------------------include delay -- Rutinas de demoras:include print -- Rutinas para mostrar valores en LCD--------------------------------------------------------------------------------- Comienza el programa en si-------------------------------------------------------------------------------forever loop --Bucle principal ------------------------------------------------- lcd_clear_screen() -- Borro la pantalla ------------------------ Pantalla de bienvenida -------------------- lcd_cursor_position(0,0) --Coloco el cursor en su sitio... print_string(lcd, line1) --y linea correspondiente lcd_cursor_position(1,0) --Coloco el cursor en su sitio... print_string(lcd, line2) --y linea correspondiente lcd_cursor_position(3,0) --Coloco el cursor en su sitio... print_string(lcd, line3) --y linea correspondiente delay_100ms(50) --Espero cinco segundos... ------------------------ Pantalla de "trabajo" -------------------- lcd_clear_screen() -- Borro la pantalla lcd_cursor_position(0,0) --Coloco el cursor en su sitio... print_string(lcd, line4) --y linea correspondiente lcd_cursor_position(1,0) --Coloco el cursor en su sitio... print_string(lcd, line5) --y linea correspondiente lcd_cursor_position(2,0) --Coloco el cursor en su sitio... print_string(lcd, line6) --y linea correspondiente lcd_cursor_position(3,0) --Coloco el cursor en su sitio... print_string(lcd, line7) --y linea correspondiente -- y recorro un bucle de 0 a 255, mostrando los valores en tres -- bases diferentes (decimal, hexadecimal y binario). for 255 using i loop lcd_cursor_position(1,12) --Coloco el cursor en su sitio... print_word_dec(lcd, i) --y muestro el valor en decimal. lcd_cursor_position(2,12) --Coloco el cursor en su sitio... print_byte_hex(lcd, i) --y muestro el valor en hexadecimal. lcd_cursor_position(3,12) --Coloco el cursor en su sitio... print_byte_binary(lcd, i) --y muestro el valor en binario. delay_100ms(10-(i/30)) --Espero antes de pasar al siguiente.... end loop	delay_100ms(20) --Espero dos segundos... ------------------------ Pantalla final ------------------------- lcd_clear_screen() -- Borro la pantalla lcd_cursor_position(0,0) --Coloco el cursor en su sitio... print_string(lcd, line1) --y linea correspondiente lcd_cursor_position(1,0) --Coloco el cursor en su sitio... print_string(lcd, line2) --y linea correspondiente lcd_cursor_position(2,0) --Coloco el cursor en su sitio... print_string(lcd, line3) --y linea correspondiente lcd_cursor_position(3,0) --Coloco el cursor en su sitio... print_string(lcd, line8) --y linea correspondiente delay_100ms(50) --Espero cinco segundos...end loopVeamos cuales son las instrucciones u ordenes nuevas que hemos utilizado esta vez, y cual es su utilidad dentro del programa:- Definimos las cadenas que queremos mostrar:Código:-- Cadenas a mostrar: var byte line1[LCD_CHARS] = "Probando libreria de"var byte line2[LCD_CHARS] = "JALv2 ( print.jal )"var byte line3[LCD_CHARS] = "www.ucontrol.com.ar "var byte line4[LCD_CHARS] = "Visualiza numeros en"var byte line5[LCD_CHARS] = " Decimal: "var byte line6[LCD_CHARS] = "Hexadecimal: "var byte line7[LCD_CHARS] = " Binario: "var byte line8[LCD_CHARS] = "Eso a sido todo. :)"- Incluimos las librerias necesarias. La segunda es la que gestiona la impresion en el LCD (y tambien en el puerto serie, como vermos más adelante)Código:---------------------------------------------------------------------------------- Incluyo librerías:--------------------------------------------------------------------------------include delay -- Rutinas de demoras:include print -- Rutinas para mostrar valores en LCD- print_string(lcd, line1) muestra el contenido del arreglo line1 a partir de la posición actual del cursor.- print_word_dec(lcd, i) imprime el valor de la variable i en formato decimal, partir de la posición actual del cursor.- print_byte_hex(lcd, i) imprime el valor de la variable i en formato hexadecimal, partir de la posición actual del cursor.- print_byte_binary(lcd, i) imprime el valor de la variable i en formato binario, partir de la posición actual del cursor.No hay más que eso. Con un puñado de instrucciones nuevas podemos gestionar perfectamente la impresion de variables y cadenas en un display LCD alfanumérico. Este es el resultado:http://www.youtube.com/v/WLWahfZJfzANOTA: Adjunto el programa fuente completo y el HEX listo para grabar.Volver al índice
SDC13233.JPG (94.07 KB - descargado 1945 veces.)
SDC13234.JPG (70.04 KB - descargado 1952 veces.)
18F4550_006.jal (7.19 KB - descargado 376 veces.)
18F4550_006.hex (8.8 KB - descargado 367 veces.)
« Última modificación: Junio 12, 2011, 03:09:31 por Leon Pic »
« Respuesta #9 : Julio 22, 2011, 09:21:02 »
010 - Conexión USB - Serial - Ejemplo 1En esta oportunidad, vamos a ver como realizar una comunicación entre la PC y el PIC por el puerto USB.JALv2 dispone de una rutina para emular un puerto serial. ¿Cómo es esto? pues la PC cree que se le conectó un dispositivo serial y no un dispositivo USB. Cabe aclarar que esto ocurre, no solo por la librería de JALv2 que vamos a utilizar, sino que también los drivers utilizados. Estos drivers se pueden descargar del presente mensaje que está adjunto.La utilización es muy sencilla y fácil de implementar, pero hay que tener cuidado con los fuses del PIC ya que sino, el módulo USB del PIC no funcionará correctamente y causará más de un dolor de cabeza buscando la causa.La configuración que aquí utilizamos, puede ser modificada pero seguramente habrá que adaptar el hardware y/o el software con el que trabajaremos.A modo explicativo, diré que, el PIC trabaja con una frecuencia de 20Mhz. Como el USB necesita 96Mhz para trabajar, se utiliza una configuración determinada para multiplicar y dividir la frecuencia principal para llegar a los 96Mhz. Vemos como llegamos al valor indicado.Primero tenemos:pragma target PLLDIV P5 -- divide by 5 - 20MHZ_INPUTAquí le indicamos al PIC, que tenemos una entrada de 20Mhz, para ello ajustamos PLLDIV con el valor 5 (P5). Ver en el data sheet Special Features of the CPULuego tenemos:pragma target CPUDIV P2 -- OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2Con la configuración anterior (pragma target PLLDIV P5) el PLL interno, llega a 96Mhz, pero el módulo USB necesita trabajar a 48Mhz, es por eso que se lo divide por dos y que se ve reflejado en la siguiente configuración:pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2Y al final le indicamos al PIC que habilite el regulador 3,3V del USB:pragma target VREGEN ENABLED -- USB voltage regulatorCon esta configuración, me ha andado de maravilla en una PC con UBUNTU, Win XP y Win 7. Vuelvo a aclarar que estoy utilizando el entrenador de Felixls y que al principio de este tema, se puede acceder al esquemático para utilizarlo y armarlo en forma gratuita.Pero vamos a los que más nos interesa, el ejemplo propiamente dicho.En el software, verán más configuraciones de los fuses que no vienen al cabo explicar, pero hay que prestar atención si se desea modificar este programa para otro uso.Luego de configurar los fuses, en varias constantes guardo unos mensajes que voy a mostrar en la comsatanásdora. La forma que lo hago es la siguiente:-- Constantes ------------------------------------------------------------------const byte mensaje_1[] = "Hola a todos los usuarios de\n"const byte mensaje_2[] = "Foro de Meteorologia Facil\n"const byte mensaje_3[] = "Foro de Ucontrol\n"const byte mensaje_4[] = "Foro de Todopic\n"const byte mensaje_5[] = "Ejemplo para encender y apagar un led\n"const byte mensaje_6[] = "en el puerto b\n"const byte mensaje_7[] = "y lectura de los mismo bit\n"const byte mensaje_8[] = "Ademas, el control de envio de los diferentes mensajes\n"const byte dir_url_1[] = "www.meteorologiafacil.com.ar\n"const byte dir_url_2[] = "www.ucontrol.com.ar\n"const byte dir_url_3[] = "www.todopic.com.ar\n"Si prestan atención, verán que tiene un patrón en su utilización de las constantes, por lo que voy a explicar el primero:const byte mensaje_1[] = "Hola a todos los usuarios de\n"const indica que lo que se va a guardar es una constante y como dice el nombre, no va a cambiar durante el funcionamiento del PIC. Cuando se intenta cambiar el valor de una constante, el compilador nos avisará con un warning o precaución.byte ya conocemos que significa y quiere decir que el tamaño es de 8 bit.mensaje_1 es el nombre de la constante[] define una constante de array (serie) y como lo dejamos en blanco, el compilador lo asigna automáticamente dependiendo del contenido que le daremos.= Le asigna el valor correspondiente. No confundir == que significa "es igual a""" Entre las comillas se escribe el valor que queremos guardar en la constante. En este caso Hola a todos los usuario de/n Significa salto de línea.Noten algo muy importante. Si le indicamos al compilador que la constante es del tipo byte y que guardamos la frase Hola a todos los usuario de, es evidente que no entra en un byte, ¿Qué es lo que está pasando? Al indicar un Array o serie, el compilador lo que hace es tomar tantas posiciones de memoria como caracteres haya. Por lo tanto, la frase que guardamos necesita 26 posiciones de memoria en forma consecutiva. Estas 26 posiciones de memoria, el compilador las identifica con el nombre mensaje_1 y cada posición de memoria el compilador le da el tamaño de 8 bit.Para que se entienda un poco mejor, cuando asignamos una variable o constante de tamaño WORD (por dar un ejemplo) el compilador toma dos posiciones de memoria como si fuera una sola.Una vez que asignamos las constante, inicializamos el módulo USB, para ello ejecutamos la función usb_serial_init() una sola vez. Es por eso que se encuentra fuera del bucle principal.Dentro del bucle principal, o sea, todo lo que está dentro del forever loop, vemos una función. Esta función lo que hace es mantener viva la comunicación entre el PIC y la PC. usb_serial_flush() Para mantener viva la comunicación, esta función debe ser ejecutada entre 2 a 3 ms. Si está fuera de este tiempo, la PC no reconocerá el dispositivo conectado. Por lo tanto, si tu PC no reconoce al PIC, chequea que esta función se ejecute en menos de ese tiempo.La función usb_cdc_line_status() nos devuelve el valor si la PC enumeró al PIC en forma correspondiente. Para saber eso, utilizamos la instrucción IF THEN.Dentro de este IF, tenemos otro IF que chequea si se recibió algún dato por el puerto USB. La función que nos dice si se recibió algún dato y que nos da ese valor es usb_serial_read(). Notarán que está escrito así: usb_serial_read(ch) ch es una variable byte y lo que hace la función es guardarnos, en esa variable, el dato recibido.Como es de esperar, si se recibió algún dato, queda adentro del IF y dentro de este IF, está el CASE OF. Este CASE, lo que hace es analizar el dato guardado en la variable ch y dirigirse al igual valor dentro del CASE. Me explico mejor, verán que está "A": "B": etc. Estas comillas indican que se debe leer como un valor ASCII, y si por ejemplo en ch se recibió "A", se va a ejecutar esta línea:"A": pin_b0 = on -- Encendemos Led en b0Por lo tanto, si nosotros enviamos desde la PC el código ASCII de la A, cuando el pic reciba dicho dato, pondrá un 1 lógico en el bit 0 del puerto b encendiendo el led que está conectado ahí. Pero si luego se envía "B", se ejecutará la siguiente línea:"B": pin_b0 = off -- Apagamos Led en b0Por lo que apagará el led ya que el pic pondrá un 0 lógico en el bit 0 del puerto b.Otra parte interesante, es la posibilidad de que el PIC envíe datos a la PC y esto se hace con dos funciones parecidas:usb_serial_write() y usb_serial_data()El primero, está creado para enviar un dato de 8 bit, mientras que el segundo está creado para enviar un array.La forma en que la utilizamos aquí es sencilla. Si enviamos los números del 0 al 7, nos enviará el código ASCII según el estado del puerto pedido. Por ejemplo:"0": -- Mostrar el estado de b0. block if pin_b0 == 1 then usb_serial_write("A") else usb_serial_write("B") end if end blockCuando el CASE analice y ejecute el código anterior, el PC del pic analizará el estado del bit 0 del puerto b. Si el mismo está encendido (1 lógico) enviará el código ASCII A, por el contrario, si es 0 lógico, enviará el código ASCII B. Noten que del 1 al 7 se repite lo mismo pero que cambia la letra a enviar.Antes de seguir con la última parte del programa, me gustaría aclarar porqué se utilizó el block. En "A", como era una sola línea de instrucción, no era necesario, pero aquí tenemos más de una línea y que encima tenemos un if para analizar el estado del bit correspondiente, entonces se hace imprescindible la utilización del block. Esto hace que JALv2 solo ejecute estas líneas de programación dentro del block cuando se ejecuta la línea "0".Para finalizar, vemos como enviamos las frases. Se ha echo de una manera muy sencilla. Se le pide al pic que envíe ciertos mensajes cuando se envía el código ASCII de las letras en minúsculas y que van de la "a" hasta la "k".En este caso se lo ha utilizado de la siguiente manera:"a": print_string(usb_serial_data, mensaje_1) -- Si se recibió "a", entregamos el primer mensaje. print_string ejecuta la función usb_serial_data y envía caracter por caracter del mensaje_1. ¡Facil! ¿Verdad?Del lado de la comsatanásdora, utilicé el programa Tera TERM PRO. En windows 7, se puede cambiar el com a utilizar y yo he utilizado el com2 conectado al PIC.La configuración del Tera TERM PRO es a 9600 baudios, 1 bit de parada, sin paridad. 8 bit de datos.Esto es el resultado:http://www.youtube.com/v/dPvstVqKEccAdjuntado está el archivo fuente utilizado en este ejemplo, más los drivers para windows 7Volver al índice
usb1.jal (7.88 KB - descargado 172 veces.)
Drivers PIC USB.rar (6.3 KB - descargado 166 veces.)
« Última modificación: Julio 23, 2011, 06:08:58 por Leon Pic »
« Respuesta #10 : Julio 23, 2011, 07:36:51 »
012 - Conexión USB - Serial - Ejemplo 2En esta oportunidad, hemos modificado el ejemplo anterior y hemos agregado otra librería, ADC.jal. Esta librería, más a las que acompaña dicha librería, nos permite manejar el ADC del pic de una forma muy sencilla y rápida.Para trabajar con esta librería, primero tenemos que configurar algunas constantes y variables para luego incluir la librería, inicializarla y por último, leer las entradas analógicas en el momento que se desee.La manera en que se configura el módulo ADC es la siguiente:const bit ADC_HIGH_RESOLUTION = low -- Elegimos una resolución baja (8 bit)Creamos una constante llamado ADC_HIGH_RESOLUTION y le damos el valor LOW, como es del tipo bit, solo alojará un 1 o un 0 lógico. Al colocarlo en LOW, elegimos una resolución de 8 bit, pero si lo configuramos en HIGH, la resolución será de 10 bit.const byte ADC_NCHANNEL = 2 -- AN0 y AN1En esta constante, especificamos la cantidad de canales que vamos a utilizar, en este caso son 2 AN0 y AN1. La librería está preparada para que se utilicen los canales en forma ascendente. Con esto quiero decir que, si deseamos usar un canal solo, tenemos que conectarlo a AN0, si deseamos utilizar otro canal, hay que modificar la librería. Al elegir dos canales, estoy obligado a utilizar AN0 y AN1.const byte ADC_NVREF = ADC_NO_EXT_VREF -- Sin tensión de referencia externa.Y aquí lo que hacemos es indicarle a la librería, para no utilizar la tensión de referencia externa.Luego de estas tres constante, podrán ver que inicializo el módulo ADC con la función adc_init()Lo bueno de esta librería, que leer una entrada analógica es tan fácil que solo hay que hacerlo de la siguiente manera:med_promedio_temp = adc_read(0)med_promedio_temp es una variable que yo cree del tipo word. Recordemos que la resolución elegida, es de 8 bit, así que la manera en que escribí la instrucción, nos dará un warning el compilador a la hora de compilarlo debido a que tenemos una variable del tipo word y un registro del tipo byte. En el siguiente ejemplo, veremos como hacer para que no nos aparezca el warning y garantizar que el compilador haga la operación que nosotros queramos.adc_read(0) es la función que nos permite leer la entrada analógica elegida con el número entre paréntesis, en este caso AN0. Cabe mencionar que esta función, toma en cuenta los tiempos necesarios entre una conversión y otra de acuerdo a nuestro crystal, en otras palabras, esta función nos devuelve el valor del ADC del PIC censado.Veamos ahora, como hago el promedio del canal AN0: Código: promedio = 8	med_promedio = 0	while promedio != 0 loop	usb_serial_flush()	-- Mantenemos viva la conección usb	med_promedio_temp = adc_read(0)	-- Pasamos el valor del ADC AN0 a la variable med_promedio.	usb_serial_flush()	med_promedio = med_promedio + med_promedio_temp	usb_serial_flush()	promedio = promedio - 1	end loop	med_promedio = med_promedio / 8Primero, vemos que a la variable promedio, le asignamos el valor decimal 8, esto nos dará la cantidad de veces que se repetirá el while. Dicho while analiza la siguiente operación lógica promedio != 0 esto es, mientras (while) promedio sea distinto de 0, ejecutamos todo lo que está dentro del loop. Sabiendo que promedio vale 8, las instrucciones que están dentro del loop se repetirá 8 veces.Vemos que se repite la función usb_serial_flush(), como recordarán es para mantener viva la comunicación USB. En el siguiente ejemplo, gracias a Felixls (usuario de ucontrol) podremos evitar repetir tanta veces esta función.El promedio es la sumatoria de la información de la cantidad de los datos obtenidos, dividido por esa misma cantidad. En este caso, tomamos 8 muestras que las sumamos entre si para luego dividirlas por 8. El valor máximo que podemos obtener por cada muestra, es de 255 y si a esto lo sumamos 8 veces, 255 * 8 = 2040 (7F8 en hexadecimal), como excede del tamaño byte, hemos configurado la variable como word (16 bit)Antes de salir del loop, vemos que hay una instrucción promedio = promedio - 1, esto lo hacemos para decrementar en 1 dicha variable. Es muy importante que esté dentro del loop, porque sino, el while se ejecutará en forma infinita al nunca cumplir la condición dada.Afuera del while, tenemos la división. Aquí también es importante que la división esté afuera del while, ya que si está adentro, la división se hará 8 veces dándonos un resultado erróneo.Vale aclarar que, una vez echo la división, tendremos un número de 8 bit ((255 * 8) / 8 = 255Al momento de enviar el dato por la función usb_serial_write(med_promedio), el compilador nos dará otro segundo warning ya que, la función trabaja hasta 8 bit (byte) y la variable med_promedio es word.Por lo demás, ya se ha explicado en el ejemplo anterior.Aquí está el video de como se comporta el programa:http://www.youtube.com/v/kZYqFEbEpHoAdjuntado está el archivo usb2.jal y el HEX listo para grabar al PIC.Volver al índice.
usb2.jal (6.89 KB - descargado 178 veces.)
usb2.hex (11.55 KB - descargado 161 veces.)
« Última modificación: Julio 23, 2011, 05:52:52 por Leon Pic »
« Respuesta #11 : Mayo 31, 2012, 08:40:49 »
Hola gente como están??Consulta... en este momento me encuentro en un momento de transición de picbasic a CCS, pero... leyendo por acá se dice que este lenguaje es mejor que C para pic?, esto es así?... ya que parece más sencillo...y el entorno gráfico me hace acordar a los programas que se utilizan para los basic stamp.bueno espero me saquen esta duda... ya que al estar iniciandome en un lenguaje nuevo podría optar por este!Un abrazo!!
« Respuesta #12 : Mayo 31, 2012, 09:14:34 »
Cita de: remramon2007 en Mayo 31, 2012, 08:40:49 Hola gente como están??Consulta... en este momento me encuentro en un momento de transición de picbasic a CCS, pero... leyendo por acá se dice que este lenguaje es mejor que C para pic?, esto es así?... ya que parece más sencillo...y el entorno gráfico me hace acordar a los programas que se utilizan para los basic stamp.bueno espero me saquen esta duda... ya que al estar iniciandome en un lenguaje nuevo podría optar por este!Un abrazo!!Hola Ramon, te comento mi experiencia por si te sirve, yo comence con Basic, luego me pase a Jal ya que es bastante similar, y hace un tiempo empece con CCS y realmente nada que ver personalmente me quedo con CCS, claro que Jal es Free, pero para realizar algunas tareas no muy complejas en jal habia que dar vueltas y vueltas cosa que no paso con CCS, pero bueno todo es cuestion de gustos y necesidades...Saludos...Luciano En línea
« Respuesta #13 : Junio 01, 2012, 11:06:47 »
Hola Ramon.Yo no te puedo comentar esa pregunta, porque del ASM pasé al JAL. Yo estoy muy cómodo con el.
« Respuesta #14 : Junio 01, 2012, 11:11:13 »
Cita de: remramon2007 en Mayo 31, 2012, 08:40:49 Hola gente como están??Consulta... en este momento me encuentro en un momento de transición de picbasic a CCS, pero... leyendo por acá se dice que este lenguaje es mejor que C para pic?, esto es así?... ya que parece más sencillo...y el entorno gráfico me hace acordar a los programas que se utilizan para los basic stamp.bueno espero me saquen esta duda... ya que al estar iniciandome en un lenguaje nuevo podría optar por este!Un abrazo!!No se si es mejor que CCS. Probablemente no.Pero a mi, que estaba muy acostumbrado al BASIC por haberlo usado durante casi 30 años en diferentes plataformas (home computers, calculadoras, PC, PICs) JAL me resultó espectacular.Saludos!
Página creada en 0.215 segundos con 24 consultas. (Pretty URLs adds 0.035s, 2q)

References: Resolución 
 Resolución 
 resolución 
 resolución 
 resolución 
 resolución