El programa:
'***************** Placa Entrenadora (PIC EBadic) ***************************************
'NOMBRE: 16F88_Pic_EBasic_LCD_CCP1_Timer1_ADC_01
'MICRO: PIC16F88/8Mhz reloj interno
'Fecha/Autor: 3/08, By COS, PSI v7.41
'Version: 1.0
'Uso del modulo CCP1 configurado en especial mode.
'Se crean bases de tiempos usando el modulo CCP1 configurado en modo comparador
'y generando el mismo modulo una lectura del ADC cada 1mSeg.
'*********************************************************************************
Define CONF_WORD = 0x2f50 'Configuración de bits (fuses)
Define CONF_WORD_2 = 0x3ffc 'Configuración de bits (fuses)
Define CLOCK_FREQUENCY = 8 'Frecuencia del reloj en Mhz
'Define SIMULATION_WAITMS_VALUE = 1 'Hace que se ignoren los tiempos de los WaitMs
'-------------------------------------Puertos del LCD-------------------------------------
Define LCD_BITS = 4 'Indicamos que el bus de datos del lcd sera de 4bit
Define LCD_DREG = PORTA 'Bus de datos sera el puerto A
Define LCD_DBIT = 0 'Bus de datos seran los 4 bit menos significativos del puerto A
Define LCD_RSREG = PORTB 'Bit de control RS sera del puerto B
Define LCD_RSBIT = 7 'RB7 como RS
Define LCD_EREG = PORTB 'Bit de control E sera del puerto B
Define LCD_EBIT = 6 'RB6 como E
Define LCD_COMMANDUS = 2000 'Tiempo de espera despues de ejecutar un comando del lcd en uSeg.
Define LCD_DATAUS = 50 'Tiempo de espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 50 'Tiempo de espera despues de inicializar el Display.
'------------------------------------Definicion de puertos y modulos--------------------------------------
ANSEL = %00010000 'Los pin I/O digitales y RA4 analogico
ADCON0 = %01100000 'Fosc/16 a 8Mhz (ADCON1.ADCS2=1) =2uSeg (minimo 1.uSeg), channel RA4
ADCON1 = %01000000 '8Bit, voltage reference (AVdd/AVss) y seleccion de escala division clock/2 ADCON1.ADCS2=1
'ADCON1.ADFM = 1 'ADC con 10Bit de resolucion.
ADCON0.ADON = 1 'Modulo ADC a ON
'_______________________________________________________________________________
CMCON = 0x07 'Comparador a off
OSCCON = 0x7e 'Set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0x00 'Puerto A como salidas
TRISB = 0x00 'Puerto B como salidas
TRISA.4 = 1 'Como entrada (RA4, adc)
TRISA.6 = 1 'Como entrada (RA6, tecla S1)
TRISA.5 = 1 'Como entrada (RA5, tecla S2)
PORTB.3 = 1 'Luz lcd a on (RB3)
PORTA.7 = 1 'Led amarillo a off (RA7), negado
PORTB.0 = 1 'Led verde a off (RB0), negado
'--------------Inicializacion de Interrupciones y configuracion del CCP1 en modo comparador----------
T1CON.TMR1CS = 0 'Asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
T1CON.T1CKPS0 = 0 'Factor del preescaler del timer1, 0
T1CON.T1CKPS1 = 0 'Factor del preescaler del timer1, 0
T1CON.TMR1ON = 1 'Habilitación del TMR1, comienza a incrementarse
CCPR1H = 0x07 'Registro mas significativo del comparador CCP1, 1mSeg.
CCPR1L = 0xd0 'Registro menos significativo del comparador CCP1, 1mSeg.
CCP1CON.CCP1M3 = 1 'Compare mode, trigger special event (CCP1M3...0).
CCP1CON.CCP1M2 = 0
CCP1CON.CCP1M1 = 1
CCP1CON.CCP1M0 = 1
PIE1.CCP1IE = 1 'Habilita las interrupciones del modulo ccp1
INTCON.PEIE = 1 'Bit de habilitacion de interrupciones de perifericos
'Reasignacion de nombres--------------------------------
Symbol led_amarillo = PORTA.7 'Led amarillo
Symbol led_verde = PORTB.0 'Led verde
Symbol luz_lcd = PORTB.3 'Iluminacion del lcd
'Declaracion de variables---------------------------------
'Variables de los timer -----------------------------------
Dim timer_base As Byte 'Tiempo referencia para los timer_100ms por soft del programa
Dim timer_base_tiempo As Byte 'Contiene el valor del tiempo del timer_base
Dim timer1_ms As Byte 'Base de tiempos en ms
Dim timer1_10ms As Byte 'Base de tiempos msx10
Dim timer2_10ms As Byte 'Base de tiempos msx10
Dim timer3_10ms As Byte 'Base de tiempos en msx10
Dim timer4_10ms As Byte 'Base de tiempos en msx10
Dim timer1_ms_tiempo As Byte 'Contiene el valor del tiempo del timer1_ms
Dim timer1_10ms_tiempo As Byte 'Contiene el valor del tiempo del timer1_10ms
Dim timer2_10ms_tiempo As Byte 'Contiene el valor del tiempo del timer2_10ms
Dim timer3_10ms_tiempo As Byte 'Contiene el valor del tiempo del timer3_10ms
Dim timer4_10ms_tiempo As Byte 'Contiene el valor del tiempo del timer4_10ms
'Variables generales------------------------------------
Dim adc_4 As Byte 'Contendra el valor de la entrada ADC trabajando a 8bit
Dim flag As Bit 'Controla parpadeo display
Dim flag_1 As Bit 'Controla parpadeo display
'Asignacion de valores a las variables------------------
timer_base = 0
timer1_ms = 0
timer1_10ms = 0
timer2_10ms = 0
timer3_10ms = 0
timer4_10ms = 0
timer_base_tiempo = 10 'Divide entre 10, solo afecta a los timerX_10ms.
timer1_ms_tiempo = 100 'Temporiza 100mSeg.
timer1_10ms_tiempo = 100 'Temporiza 1 Seg.
timer2_10ms_tiempo = 200 'Temporiza 2Seg
timer3_10ms_tiempo = 60 'Temporiza 0.6Seg
timer4_10ms_tiempo = 200 'Temporiza 2Seg
adc_4 = 0
flag = 1
flag_1 = 1
'-------------------------------------------------------
Lcdinit 'Inicializa el lcd sin cursor
WaitMs 1000 'Espera 1Seg, las interrupciones alargan este tiempo
Lcdout "COMPARE MODE" 'Escribe en el lcd
Lcdcmdout LcdLine2Home 'Seleciona la linea dos como proxima para escritura
Lcdout "Pruebas con CCP1" 'Escribe en el lcd
WaitMs 3000 'Espera 3Seg, las iterrupciones hacen este tiempo mas largo
Lcdcmdout LcdLine1Clear 'Borra el display,linea 1
Enable 'INTCON.GIE habilita todas las interrupciones globales
'------------------------------------rutinas del Programa----------------------------------------
main: 'comienza el programa principal
If timer1_10ms >= timer1_10ms_tiempo Then 'cambio de estado el pin RA7 cada timer1_100ms_tiempo
Toggle led_amarillo 'invierte el valor del pin
timer1_10ms = 0 'reinicio el timer1_100ms
Endif
If timer2_10ms >= timer2_10ms_tiempo Then 'cambio de estado el pin RB0 cada timer2_100ms_tiempo
Toggle led_verde 'invierte el valor del pin
timer2_10ms = 0 'reinicio el timer2_100ms
Endif
If timer1_ms >= timer1_ms_tiempo Then 'permite que se ejecute las rutinas solo una vez cada timer1_ms_tiempo
Gosub print_lcd 'salto con retorno, rutina que imprime los valores en el lcd
timer1_ms = 0 'reset a la base de tiempos
Endif
Goto main 'impide que termine el programa principal
End
'--------------------------------------Subrutinas------------------------------------------------
print_lcd: '_______________________Imprime la entrada analogica
Lcdcmdout LcdLine1Home 'Cursor al principio de linea
If timer3_10ms >= timer3_10ms_tiempo Then 'Control parpadeo, condicionado por timer3_10ms
timer3_10ms = 0 'Reinicializa el timer3_10ms
Toggle flag 'Invierte el valor contenido en flag
Endif
If timer4_10ms >= timer4_10ms_tiempo Then 'Control parpadeo, condicionado por timer4_10ms
timer4_10ms = 0 'Reinicializa el timer4_10ms
Toggle flag_1 'Invierte el valor contenido en flag_1
Endif
If flag = 1 Then Lcdout " ADC: " 'Imprime en el LCD, condicionado por el valor de flag
If flag = 0 Then Lcdout " " 'Imprime en el LCD, condicionado por el valor de flag
Lcdout #adc_4, " " 'Imprime en el LCD
Lcdcmdout LcdLine2Home 'Cursor al principio de linea
If flag_1 = 1 Then Lcdout "Pruebas con CCP1" 'Imprime en el LCD, condicionado por el valor de flag_1
If flag_1 = 0 Then Lcdout "en Especial Modo" 'Imprime en el LCD, condicionado por el valor de flag_1
Return
'--------------------------------Interrupciones---------------------------------------------------
On Interrupt 'Comienzan las rutinas de las interrupciones, desactiva las interrupciones
'Save System 'Guarda valores del sistema y valores intermedios.
adc_4 = ADRESH 'Valor mas significativo de la lectura del ADC
'___Base de tiempos
timer_base = timer_base + 1 'Contador general
If timer1_ms < timer1_ms_tiempo Then timer1_ms = timer1_ms + 1 'Contador
If timer_base >= timer_base_tiempo Then 'Limita el tiempo de ejecucion, cada timer_base_tiempo
If timer1_10ms < timer1_10ms_tiempo Then timer1_10ms = timer1_10ms + 1 'Contador
If timer2_10ms < timer2_10ms_tiempo Then timer2_10ms = timer2_10ms + 1 'Contador
If timer3_10ms < timer3_10ms_tiempo Then timer3_10ms = timer3_10ms + 1 'Contador
If timer4_10ms < timer4_10ms_tiempo Then timer4_10ms = timer4_10ms + 1 'Contador
timer_base = 0 'Reset a la base de tiempos
Endif
'__Fin base de tiempos
PIR1.CCP1IF = 0 'borra el flag de salto del CCP1
Resume 'Activa las interrupciones y retorna al curso normal del programa antes del salto