PIC PAL Video Library

De Ucontrol
Saltar a: navegación, buscar

<keywords content="TTL 74Ls164N, electronica, circuito, pic, NE555, PIC BASIC, PIC SIMULATOR IDE, esquema, circuito impreso, proyecto, gratis, download, programa, CMOS, pin, e/s, i/o, ucontrol, PIC, 16F628a, 16f84a" /> <center>


Inicio Foro Revista uControl Circuiteca Microcontroladores Electrónica Básica Herramientas y Software Tutoriales Colaboradores Enlaces
¿Ya descargaste los ejemplares GRATUITOS de la Revista uControl? ¡No te los pierdas!.
<linkedimage>

wikipage=Dado electrónico con PIC tooltip=Dado electrónico con PIC img_src=Image:dado100.jpg img_width=150px img_alt=Dado electrónico con PIC </linkedimage>

Dado electrónico
<linkedimage>

wikipage=Como trucar un servo tooltip=Como trucar un servo img_src=Image:trucaservo150.jpg img_width=150px img_alt=Como trucar un servo </linkedimage>

¿Como trucar un servo?
<linkedimage>

wikipage=Comunicación inalámbrica entre PICs tooltip=Comunicación inalámbrica entre PICs img_src=Image:TXRX150.jpg img_width=150px img_alt=Comunicación inalámbrica entre PICs </linkedimage>

Comunicación inalámbrica
<linkedimage>

wikipage=CCS - Libreria de gráficos para GLCD K0108 tooltip=CCS - Libreria de gráficos para GLCD K0108 img_src=Image:GLCD-100.gif img_width=150px img_alt=CCS - Libreria de gráficos para GLCD K0108 </linkedimage>

Gráficos con CCS
<linkedimage>

wikipage=Funcionamiento de una matriz de LEDs tooltip=Funcionamiento de una matriz de LEDs img_src=Image:GNUxx.jpg img_width=150px img_alt=Funcionamiento de una matriz de LEDs </linkedimage>

Carteles de LEDs
Foroizq.jpg
Todos los articulos y proyectos de uControl tienen su lugar en el foro. Si tienes dudas o comentarios, busca o crea el hilo correspondiente, y tendrás una rapida respuesta.
Foroder.jpg
PIC PAL Video Library, para usar un TV como pantalla en tus proyectos.

Introducción

Un TV como pantalla en tus proyectos.

¿Alguna vez, como parte de alguno de tus proyectos, has necesitado mostrar alguna información en la pantalla de un televisor? Es posible que si. Pero el hardware y el software necesarios para este tipo de proyecto no es fácil de desarrollar.

Sin ambargo, ahora podrás hacerlo. Este artículo te mostrará cómo convertir un PIC18 en un generador PAL de graficos y textos (en blanco y negro) con un número muy reducido de componentes de bajo costo, con un mínimo de esfuerzo de programación.

Contenido


¿Por que una biblioteca PAL para PICs?

Si estás utilizando PICs, posiblemente algun diá intentaste construir un dispositivo procesador de vídeo, ya sea para divertirse o como parte de un proyecto más grande. Si intentaste generar señales de vídeo, posiblemente hayas visto alguna de estas paginas web:



Estos proyectos son divertidos, pero dificiles de utilizar como un generador de video de carácter general, que permita utilizar un TV como si fuese una pantalla GLCD.

He tenido la idea de utilizar una escalera de resistores como una forma rápida y barata cde crear un convertidor digital a analógico, y comenzado a trabajar en el software.


La librería PIC PAL

Como la pantalla de vídeo que se ha mapeado en memoria, sólo un PIC con suficiente memoria RAM puede utilizar esta librería. Es por ello que la PIC PAL Video Library sólo funciona con la familia PIC18.

El PIC debe funcionar a 32 MHz, con un cristal de 8 MHz, para poder obtener los 64 μs necesarios para la sincronización horizontal del sistema PAL.

La libreria genera una señal PAL de 625 lineas interlazadas, y puede mostrar hasta 248 lineas verticales de 128 pixeles. Cualquier dispositivo con una entrada PAL de video compuesto puede emplearse para mostrar las imagenes generadas por el PIC.

Dado que el manejo de los tiempos es crítico, el software se ha escrito en C con algunas rutinas en ensamblador. El C utilizado es el mikroC, y puedes descargar el proyecto completo (incluido el codigo fuente).



Manual del usuario

Esta es una guía que explica como usar cada una de las funciones contenidas en la librería.


Inicialización

Esta función prepara la librería PIC PAL. Cuanto mayor sea la cantidad de lineas verticales que desees mostrar en el TV, menor será la cantidad de memoria y de recursos que el PIC tenga para el resto del programa.

Importante: Esta librería toma el control del TIMER0 y sus interrupciones asociadas. También utiliza el PORTD.

Prototipo: void PAL_init(unsigned char y)
Parametros: y : número de lineas verticales, hasta 128.
Devuelve: Nada
Requiere: El fichero PAL_library.h debe ser incluido en el codigo fuente del usuario. El PIC18 debe funcionar a 32MHz.
Ejemplo: PAL_init(128);


Control de video

Esta función controla la generación de la señal de video. Cuando comienza la sincronización PAL, la variable PAL_frameCtr (unsigned long global) se incrementa 25 veces por segundo.

Prototipo: void PAL_control(unsigned char st, unsigned char rd)
Parametros: st : Control de la sincronización PAL

PAL_CNTL_START : Comienza sincronización PAL

PAL_CNTL_STOP : Detiene la sincronización PAL (libera los recursos del PIC)

rd : Control de render PAL_CNTL_BLANK : Solo se muestran los bordes (libera parte de los recursos del PIC))

PAL_CNTL_RENDER : Muestra todo el video, con bordes e imagen (consume más recursos del PIC)

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER);


Pintar pantalla

Esta función llena la pantalla con un patrón determinado. Utiliza 0x00 para limpiar la pantalla y 0xFF para pintarla completamente de blanco.

Prototipo: void PAL_fill(unsigned char c))
Parametros: c : Patrón de relleno
Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PALL_fill(0);


Seleccionar el color del borde

Esta función cambia el color del borde que rodea la imagen.

Prototipo: void PAL_setBorder(unsigned char border)
Parametros: border : PAL_COLOR_BLACK o PAL_COLOR_WHITE
Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_border(PAL_COLOR_BLACK);


Dibujar puntos

Esta es la función que permite dibujar un punto en una posición determinada de la pantalla.

Prototipo: void PAL_setPixel(char x, char y, unsigned char mode)
Parametros: x : columna del pixel, de 0 a 127

y : Fila del pixel, de 0 a numero de lineas -1

mode : color del pixel, PAL_COLOR_BLACK, PAL_COLOR_WHITE o PAL_COLOR_REVERSE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_setPixel(10, 20, PAL_COLOR_REVERSE);


Dibujar lineas

Esta función dibuja una linea desde (x0, y0) a (x1, y1).

Prototipo: void PAL_line(char x0, char y0, char x1, char y1, unsigned char mode)
Parametros: x0, y0 : Coordenadas (fila y columna) del comienzo de la linea.

x1, y1 : Coordenadas (fila y columna) del final de la linea.

mode : color del pixel, PAL_COLOR_BLACK, PAL_COLOR_WHITE o PAL_COLOR_REVERSE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_line(0, 0, 127, 127, PAL_COLOR_WHITE);


Dibujar circulos

Esta función dibuja un circulo con centro en (x,y) y radio z.

Prototipo: void PAL_circle(char x, char y, char r, unsigned char mode)
Parametros: x : Columna del centro del circulo.

y : Fila del centro del circulo.

r : Radio del circulo.

mode : color del pixel, PAL_COLOR_BLACK, PAL_COLOR_WHITE o PAL_COLOR_REVERSE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_circle(30, 30, 5, PAL_COLOR_WHITE);


Dibujar rectangulos rellenos

Esta función dibuja (y pinta) un rectangulo.

Prototipo: void PAL_box(char x0, char y0, char x1, char y1, unsigned char mode)
Parametros: x0, y0 :Coordenadas de la esquina superior izquierda.

x1, y1 :Coordenadas de la esquina inferior derecha.

mode : color del pixel, PAL_COLOR_BLACK, PAL_COLOR_WHITE o PAL_COLOR_REVERSE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_box(10, 10, 30, 30, PAL_COLOR_WHITE);


Dibujar rectangulos vacíos

Esta función dibuja un rectangulo vacío.

Prototipo: void PAL_rectangle(char x0, char y0, char x1, char y1, unsigned char mode)
Parametros: x0, y0 :Coordenadas de la esquina superior izquierda.

x1, y1 :Coordenadas de la esquina inferior derecha.

mode : color del pixel, PAL_COLOR_BLACK, PAL_COLOR_WHITE o PAL_COLOR_REVERSE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_rectangle(10, 10, 30, 30, PAL_COLOR_WHITE);


Escribir un caracter de texto

Esta función escribe un caracter de texto en la fila y columna deseada. Puedes usar PAL_box() para escribir en video invertido.

Prototipo: void PAL_char(unsigned char x, unsigned char y, unsigned char c, unsigned char size)
Parametros: x : Columna del pixel superior izquierdo del caracter, de 0 to 127

y : Fila del caracter, de 0 a numero de lineas -1

c : Código ASCII del caracter.

size : El nibble alto es el multiplicador de la altura, el bajo multiplica el ancho.

Tamaños predefinidos: PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_char(3, 5, 'A', PAL_CHAR_DSIZE);


Escribir una cadena de texto

Esta función escribe una cadena de texto a partir de la fila y columna deseada.

Prototipo: void PAL_write(unsigned char lig, unsigned char col, unsigned char *s, unsigned char size)
Parametros: lig : Linea del texto

col : Columna del texto

s : Puntero a la cadena de texto (terminado en NULL)

size : El nibble alto es el multiplicador de la altura, el bajo multiplica el ancho.

Tamaños predefinidos: PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_write(0, 5, myString, PAL_CHAR_STANDARD);


Escribir una cadena de textom almacenada en la ROM

Esta función escribe una cadena de texto a partir de la fila y columna deseada. Es igual a la funcion anterior, pero para textos almacenados en ROM.

Prototipo: void PAL_constWrite(unsigned char lig, unsigned char col, const unsigned char *s, unsigned char size)
Parametros: lig : Linea del texto

col : Columna del texto

s : Puntero a la cadena de texto (terminado en NULL)

size : El nibble alto es el multiplicador de la altura, el bajo multiplica el ancho.

Tamaños predefinidos: PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_write(0, 5, myConstantString, PAL_CHAR_STANDARD);


Mostrar un BitMap almacenado en ROM

Dibuja una imagen (BitMap) previamente almacenado en la ROM y apuntado por bm, en la posición (x, y). La imagen será monocroma, y puede utilizarse la herramienta para generar mapas de bits para GLCD T6963 de mikroElektronika para convertir las imagenes.

Prototipo: void PAL_picture(unsigned char x, unsigned char y, const unsigned char *bm, unsigned char sx, unsigned char sy)
Parametros: x : columna del pixel superior izquierdo de la imagen.

y : fila del pixel superior izquierdo de la imagen.

bm : Puntero al bitmap en ROM

sx : Ancho de la imagen.

sy : Alto de la imagen.

Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo: PAL_picture(0, 0, pict, 128, 128);


Rutina de video

Esta función no puede ser llamada directamente por el usuario, perodebe ser colocada dentro de la función interrupt().

Atención: Si están habilitadas, otras interrupciones puede ocasionar problemas de sincronismo en el video.

Prototipo: void PAL_ISR()
Parametros:
Devuelve: Nada
Requiere: La ejecución previa de PAL_init();
Ejemplo:
void interrupt(void)
{
  PAL_ISR();
}



Hardware

La imagen siguiente muestra el esquema electrico del hardware propuesto. Puedes hacer click sobre la imagen para ver una ampliación.


PICPALVideo1.jpg


El corazón del circuito es un PIC18F4620. C1, C3 y C4 son condensadores de desacople. El PIC funciona con un cristal de 8 MHz. D1 se utiliza como un sensor de temperatura conectado al conversor analogico digital del PIC. La señal de video se obtiene de los resistores R8 y R9. Los pulsadores se emplean para configurar el soft.

La señal de salida puede aplicarse directamente a la entrada de video compuesto de un aparato de TV.


Software

El siguiente programa sirve de ejemplo de como puedes utilizar las funciones incluidas en la PIC PAL Library.

En un PIC18F4620 utiliza solamente el 25% de la ROM y el 55% de la RAM!

La primer pantalla del programa muestra una imagen de 128x128 pixeles, con un borde parpadeante. El programa espera a que se pulse la tecla conectada a RB7 para mostrar la segunda pantalla.


PICPALVideo2.jpg
Primer pantalla del ejemplo.


La segunda pantalla muestra un reloj-calendario y la temperatura. La hora se muestra simultaneamente en forma digital y analógica.


PICPALVideo3.jpg
Segunda pantalla del ejemplo.


RB0 cambia los minutos, RB1 las horas, RB2 el día, RB3 el mes y RB4 el año. RB5 permite ajustar la temperatura. Presionando RB7 junto a las anteriores opciones, los valores decrementan en lugar de incrementarse.

Código fuente del ejemplo

/*
 * file         : PALdemo.c
 * project      : PIC PAL SOFTWARE VIDEO GENERATOR DEMO
 * author       : Bruno Gavand
 * compiler     : mikroC V6.2
 * date         : January 17, 2006
 *
 * description  :
 * 	This program displays a clock, a calendar and the temperature on a TV screen
 *      and shows how to use the PIC PAL library.
 *              press RB7 to skip the welcome screen
 *              to adjust clock and calendar, press :
 *                      RB0 to adjust minute
 *                      RB1 to adjust hour
 *                      RB2 to adjust day
 *                      RB3 to adjust month
 *                      RB4 to adjust year
 *                      RB5 to adjust temperature
 *              press RB7 at the same time to decrement.
 *
 * target device :
 *      PIC18F4620 @ 32 Mhz (8 Mhz crystal + HS PLL)
 *
 * Licence :
 *      Feel free to use this source code at your own risks.
 *
 * history :
 *      created january 2007
 *
 * see more details on http://www.micro-examples.com/
 */

#include        "PAL_Library.h"
#include        "pictures.h"

/*************
 * DEFINITIONS
 *************/
 
/*
 * graphic clock
 */
#define CLK_CENTER_X    90      // center
#define CLK_CENTER_Y    60
#define CLK_RADIUS_PSS  28      // clock radius
#define CLK_RADIUS_SS   25      // seconds
#define CLK_RADIUS_MN   20      // minutes
#define CLK_RADIUS_HH   15      // hours

#define DEG_NBHISTO     16      // number of temperature samples

/*
 * number of vertical pixels
 * from 1 to 128 included
 * the more pixels you have :
 * - the less RAM you have
 * - the less MCU time you have
 */
#define PAL_Y      128

/*
 * simple time structure definition
 */
typedef struct
        {
        unsigned char   ss ;    // seconds
        unsigned char   mn ;    // minutes
        unsigned char   hh ;    // hours
        unsigned char   md ;    // day in month, from 1 to 31
        unsigned char   wd ;    // day in week, monday=0, tuesday=1, .... sunday=6
        unsigned char   mo ;    // month number, from 1 to 12 
                                //(and not from 0 to 11 as with unix C time !)
        unsigned int    yy ;    // year Y2K compliant, from 1892 to 2038
        } TimeStruct ;

/********************
 * ROM CONSTANTS
 ********************/
 
/*
 * month names
 */
const unsigned char monthStr[13][4] =
	{
	"???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	} ;

/*
 * day of week names
 */
const unsigned char wDaystr[7][4] =
	{
	"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
	} ;

/********************
 * RAM VARIABLES
 ********************/
 
/*
 * screen memory map
 * do not change this line !
 */
unsigned char   PAL_screen[PAL_X * PAL_Y / 8] ;

/*
 * general purpose string
 */
unsigned char   str[20] ;

char    degRef ;                        // DAC temperature reference
char    degHisto[DEG_NBHISTO] ;         // temperature samples buffer
char    tIdx = 0 ;                      // temperature samples index

unsigned long   secOffset = 0 ;         // reference timestamp
unsigned long   oldCtr = 0 ;            // frame counter backup
TimeStruct      ts ;                    // time struct

/*************************
 * FUNCTIONS
 *************************/

/*
 * adjust time struct member
 */
void    adjust(unsigned char *v, unsigned char min, unsigned char max)
	{
	if(PORTB.F7)
	        {
	        if(*v == min) *v = max ;
	        else (*v)-- ;
	        }
	else
	        {
	        if(*v == max) *v = min ;
	        else (*v)++ ;
	        }
	}

/*
 * convert value v into string pointed to by p, leading zero blanks if blk is set
 */
void    char2str(unsigned char *p, unsigned char v, unsigned char blk)
        {
        *p = v / 10 + '0' ;
        if(blk && (*p == '0'))
                {
                *p = ' ' ;
                }
        p++ ;
        *p = v % 10 + '0' ;
        p++ ;
        *p = 0 ;
        }

/*
 * draw screen with decoration if full is set, using video mode mode
 */
void    drawScreen(unsigned char full, unsigned char mode)
        {
        static unsigned char    osx = CLK_CENTER_X, osy = CLK_CENTER_Y,
		omx = CLK_CENTER_X, omy = CLK_CENTER_Y,
		ohx = CLK_CENTER_X, ohy = CLK_CENTER_Y ;
        unsigned int    i ;
	int		t ;
        unsigned char   ss ;
        unsigned char   sx, sy, mx, my, hx, hy ;

        PAL_control(PAL_CNTL_START, mode) ;

        if(full)                // draw full screen with decoration
                {
                PAL_fill(0) ;
                PAL_constWrite( 0,  0, "\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
                          xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 1,  0, "\xBA PAL LIBRARY DEMO  \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 2,  0, "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
                            xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC", PAL_CHAR_STANDARD) ;

                PAL_box(0, 0, 127, 21, PAL_COLOR_REVERSE) ;

                PAL_constWrite( 3,  0, "\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCB\xCD\xCD\
                                   xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 4,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 5,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 6,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 7,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 8,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite( 9,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite(10,  0, "\xBA        \xBA          \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite(11,  0, "\xCC\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCA\xCD\xCD\
                                   xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xB9", PAL_CHAR_STANDARD) ;
                PAL_constWrite(12,  0, "\xBA                   \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite(13,  0, "\xBA                   \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite(14,  0, "\xBA                   \xBA", PAL_CHAR_STANDARD) ;
                PAL_constWrite(15,  0, "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
                                    xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC", PAL_CHAR_STANDARD) ;

                PAL_write(4, 3, "H  :", PAL_CHAR_DHEIGHT) ;

                PAL_constWrite(12, 3, "TEMP. : ", 0x31) ;
                PAL_constWrite(12, 17, "\xf8C", 0x31) ;

                for(ss = 0 ; ss < 60 ; ss++)
                        {
                        sx = CLK_CENTER_X - (cosE3(90 + 6 * ss) * CLK_RADIUS_PSS) / 1000 ;
                        sy = CLK_CENTER_Y - (sinE3(90 + 6 * ss) * CLK_RADIUS_PSS) / 1000 ;
                        
                        PAL_setPixel(sx, sy, PAL_COLOR_WHITE) ;
                        
                        if((ss % 5) == 0)
                                {
                                PAL_setPixel(sx + 1, sy, PAL_COLOR_WHITE) ;
                                PAL_setPixel(sx - 1, sy, PAL_COLOR_WHITE) ;
                                PAL_setPixel(sx, sy + 1, PAL_COLOR_WHITE) ;
                                PAL_setPixel(sx, sy - 1, PAL_COLOR_WHITE) ;
                                }
                        }
                }

	if(PAL_frameCtr > OldCtr)       // it's time to update the clock & calendar
		{
		unsigned char   h ;
		
	        oldCtr = PAL_frameCtr + 24 ;    // prepare oldCtr for next update time
                
                // convert timestamp to date and time
		Time_EpochToDate(secOffset + PAL_frameCtr / 25, &ts) ;  


		/*
		 * draw analog clock
		 */
	        sx = CLK_CENTER_X - (cosE3(90 + 6 * ts.ss) * CLK_RADIUS_SS) / 1000 ;
	        sy = CLK_CENTER_Y - (sinE3(90 + 6 * ts.ss) * CLK_RADIUS_SS) / 1000 ;

	        mx = CLK_CENTER_X - (cosE3(90 + 6 * ts.mn) * CLK_RADIUS_MN) / 1000 ;
	        my = CLK_CENTER_Y - (sinE3(90 + 6 * ts.mn) * CLK_RADIUS_MN) / 1000 ;

		h = (ts.hh % 12) * 5 + (ts.mn / 8) ;
	        hx = CLK_CENTER_X - (cosE3(90 + 6 * h) * CLK_RADIUS_HH) / 1000 ;
	        hy = CLK_CENTER_Y - (sinE3(90 + 6 * h) * CLK_RADIUS_HH) / 1000 ;

	        if((hx != ohx) || (hy != ohy))
	                {
	                PAL_line(CLK_CENTER_X, CLK_CENTER_Y, ohx, ohy, PAL_COLOR_BLACK) ;
	                }
	        if((mx != omx) || (my != omy))
	                {
	                PAL_line(CLK_CENTER_X, CLK_CENTER_Y, omx, omy, PAL_COLOR_BLACK) ;
	                }
	        if((sx != osx) || (sy != osy))
	                {
	                PAL_line(CLK_CENTER_X, CLK_CENTER_Y, osx, osy, PAL_COLOR_BLACK) ;
	                }
	        PAL_line(CLK_CENTER_X, CLK_CENTER_Y, hx, hy, PAL_COLOR_WHITE) ;
	        PAL_line(CLK_CENTER_X, CLK_CENTER_Y, mx, my, PAL_COLOR_WHITE) ;
	        PAL_line(CLK_CENTER_X, CLK_CENTER_Y, sx, sy, PAL_COLOR_WHITE) ;

		/*
		 * print date and time
		 */
	        char2str(str, ts.ss, 0) ;
	        PAL_write(4, 7, str, PAL_CHAR_DHEIGHT) ;

	        char2str(str, ts.mn, 0) ;
	        PAL_write(4, 4, str, PAL_CHAR_DHEIGHT) ;

	        char2str(str, ts.hh, 1) ;
	        PAL_write(4, 1, str, PAL_CHAR_DHEIGHT) ;

	        PAL_constWrite(6, 2, wdayStr[ts.wd], PAL_CHAR_STANDARD) ;
	        PAL_constWrite(7, 2, monthStr[ts.mo], PAL_CHAR_DHEIGHT) ;

	        char2str(str, ts.md, 1) ;
	        PAL_write(6, 5, str, 0x32) ;

	        wordToStr(ts.yy, str) ;
	        PAL_write(9, 1, str + 1, PAL_CHAR_DSIZE) ;

		/*
		 * save old value for fast analog clock cleaning at next update
		 */
	        osx = sx ;
	        osy = sy ;
	        omx = mx ;
	        omy = my ;
	        ohx = hx ;
	        ohy = hy ;

                t = degRef - Adc_Read(4) ;      // read temperature sensor

                t *= 221 ;           // temperature coefficient of the silicon junction
                t /= 102 ;
                t = 25 + t ;      // get the result in celcius

		/*
		 * adjust limits
		 */
                if(t < -99)
                        {
                        t = -99 ;
                        }
		if(t > 99)
		        {
		        t = 99 ;
		        }

		/*
		 * average values
		 */
                degHisto[tIdx] = t ;
                tIdx++ ;
                if(tIdx == DEG_NBHISTO)
                        {
                        tIdx = 0 ;
                        }
                t = 0 ;
                for(i = 0 ; i < DEG_NBHISTO ; i++)
                        {
                        t += degHisto[i] ;
                        }
		t /= DEG_NBHISTO ;

		/*
		 * print temperature
		 */
	        if(t < 0)
	                {
	                i = -t ;
	                PAL_constWrite(12, 11, "-", 0x31) ;
	                }
	        else
	                {
	                i = t ;
	                PAL_constWrite(12, 11, " ", 0x31) ;
	                }
	        char2str(str, i, 1) ;
	        PAL_write(12, 12, str, 0x32) ;
	        }
        // restore video rendering if it was stopped
        PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER) ;          
        }

/*
 * interrupt service routine
 */
void    interrupt(void)
        {
        /*
         * do PAL stuff
         */
        PAL_ISR() ;             // library call
        }

/*
 * main program
 */
void main(void)
        {
        unsigned char i ;
        
	/*
	 * I/O configuration
	 */
        ADCON1 = 0x0f ;
        TRISA = 0xff ;
        PORTA = 0 ;
        
        TRISB = 0xff ;
        PORTB = 0 ;
        
        TRISC = 0xff ;
        PORTC = 0 ;
        
        TRISD = 0 ;
        PORTD = 0 ;
        
        TRISE = 0 ;
        PORTE = 0 ;
        
        degRef = EEPROM_read(0) ;  // get temperature calibration from EEPROM

	/*
	 * default time and date
	 */
        ts.ss = 0 ;
        ts.mn = 0 ;
        ts.hh = 12 ;
        ts.md = 1 ;
        ts.mo = 1 ;
        ts.yy = 2007 ;

        secOffset = Time_dateToEpoch(&ts) ;

	/*
	 * start video and display first screen
	 */
        PAL_init(PAL_Y) ;       // init PAL library
        PAL_fill(0) ;           // clear screen
        PAL_picture(0, 0, logo_bmp, 128, 128) ;         // paint picture
        PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER) ;  // start video and rendering

	i = 0 ;
        while(PORTB == 0)	// wait for a key to be pressed
                {
                /*
		 * change border color two times per second
		 */
                if(PAL_frameCtr > 12)
                        {
			PAL_setBorder(i) ;
			i = !i ;
			PAL_frameCtr = 0 ;
			}
		}
	PAL_setBorder(PAL_COLOR_BLACK) ;// clear border

        drawScreen(1, PAL_CNTL_BLANK) ;// draw full screen in blank mode (faster)

        for(;;)
                {
                if(PORTB & 0b1111111)   // a key is pressed
                        {
			Time_EpochToDate(secOffset + PAL_frameCtr / 25, &ts) ;

			/*
			 * calendar settings
			 */
                        if(PORTB.F0)
                                {
                                adjust(&ts.mn, 0, 59) ;
				ts.ss = 0 ;
                                }
                        if(PORTB.F1)
                                {
                                adjust(&ts.hh, 0, 59) ;
				ts.ss = 0 ;
                                }
                        if(PORTB.F2)
                                {
                                adjust(&ts.md, 1, 31) ;
                                }
                        if(PORTB.F3)
                                {
                                adjust(&ts.mo, 1, 12) ;
                                }
                        if(PORTB.F4)
                                {
                                if(PORTB.F7) ts.yy-- ; else ts.yy++ ;
                                }

		        secOffset = Time_dateToEpoch(&ts) ;   // new timestamp

			/*
			 * temperature calibration
			 */
                        if(PORTB.F5)
                                {
                                if(PORTB.F7)
                                        {
	                                degRef-- ;
	                                EEPROM_write(0, degref) ;
                                        }
				else
				        {
	                                degRef++ ;
	                                EEPROM_write(0, degref) ;
	                                }
                                }

			while(PORTB & 0b1111111) ; // wait for the key to be released
			
		        PAL_frameCtr = 0 ;      // reset counters
			oldCtr = 0 ;
                        }

                drawScreen(0, PAL_CNTL_RENDER) ;  // update screen
                }
        }



Descargas

Puedes descargar el proyecto completo, incluido el codigo fuente del ejemplo desde aqui:

Dentro del archivo ZIP encontrarás:

  • PAL_library.c, 37 Kb : Código fuente de la libreria
  • PAL_library.h, 2 Kb : Definiciones de la libreria
  • PALdemo.c, 15 Kb : Código del ejemplo
  • PALdemo.eed, 1 Kb : Definición de la EEPROM
  • PALdemo.hex, 46 Kb : Archivo HEX fpara el PIC18F4620
  • PALdemo.ppc, 2 Kb : mikroC project
  • pictures.h, 9 Kb : bitmap de ejemplo


Puedes conseguir el compilador mikroC desde aqui: mikroC

Autor

Noavatar.jpg Datos del Autor
Nombre: Bruno Gavand
email: bruno.gavand@ad-valorem.fr
Ver los artículos de este autor. Página web del autor.

El artículo original (en inglés) puede encontrarse en la página de Bruno: www.micro-examples.com

</center>
Cclicence.png

Este contenido se rige por la licencia de Creative Commons "Licencia Creative Commons Atribución-No Comercial-Sin Obras Derivadas 3.0". Para más información, véase la licencia en su forma reducida y completa.

Herramientas personales