;******************************************************************************
LIST P=18F2550 ;directive to define processor
#include <P18F2550.INC> ;processor specific variable definitions
ERRORLEVEL -306, -302 ; Apaga mensages del Cruse de pagina.
;******************************************************************************
;Configuration bits
;Microchip has changed the format for defining the configuration bits, please
;see the .inc file for futher details on notation. Below are a few examples.
CONFIG PLLDIV = 5
CONFIG CPUDIV = OSC1_PLL2
CONFIG USBDIV = 1
CONFIG FOSC = HSPLL_HS
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = OFF
CONFIG BOR = OFF
CONFIG BORV = 0
CONFIG VREGEN = ON
CONFIG WDT = OFF
CONFIG WDTPS = 32768
CONFIG MCLRE = OFF
CONFIG LPT1OSC = OFF
CONFIG PBADEN = OFF
CONFIG CCP2MX = ON
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTB = OFF
CONFIG WRTC = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
;******************************************************************************
;Variables Tenemos disponibles desde 0x20 hasta 0x7F en el Banco 0
;Mirar Datasheet para los otros bancos de memoria.
CBLOCK 0x000
LINEA ;Contador de línea interlazada como son 253 líneas nos alcanza con 1 byte
d1 ;Variable para delay
ENDC
;*** Constantes
;Asignación de Pines PORTA
SINC equ H'0004' ;Señal de Sincronismo
BLK_LEV equ H'0001' ;Nivel de Negro
BLANKING equ H'0000' ;Nivel de Blanking
;Asignación de Pines PORTB
ORG 0x0000
goto Rst ;go to start of main code
;******************************************************************************
;Start of main program
; The main program code is placed here.
;Sector de Inicio del Block de Programa
ORG 0x0020
Tabla_Col
;Esta es una tabla de colores, cada byte contiene 1 pixel, los tres primeros bits conforman el color,
;El cuarto corresponde a si el pixel es a color o escala de grises y los 4 últimos bytes nos dan el nivel de brillo del pixel.
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
data 0x8090, 0xA0B0, 0XC0D0, 0xE0F0
Rst
clrf LATA ;Inicializamos el Puerto A
movlw 0x0F ;Configuramos A/D
movwf ADCON1 ;Como entradas digitales
movlw 0x07 ;Configuramos los comparadores
movwf CMCON ;Como entradas Digitales
clrf TRISA ;Pines 0,1 y 2 como salidas
clrf LATB ;Ponemos las salidas del Puerto B en 0
clrf TRISB ;Todo el puerto B como salidas
clrf LATC ;Ponemos las salidas del Puerto B en 0
clrf TRISC ;Todo el puerto B como salidas
;---------------------------------------------------------------------------------
;*** Rutina principal
Inicio
; Tenemos entoces que hacer lo siguiente:
; 6 Pulsos de Pre-ecualización
; 6 Pulsos de Sincronismo
; 6 Pulsos de Post-ecualización
; Todo esto lo realiza la Rutina VSincro
call VSincro
; Luego hacemos
; 252 Cuadros Normales
movlw 0xFC
movwf LINEA ;Cargo la Variable línea con 252 (Que son los cuadros normales)
;*** Cuadros Normales
;*************************************************************************************************************************************
;*** La rutina deberá ser capáz de generar una señal de la forma siguiente
;***
;*** 100% _
;*** _ / \
;*** | / \ __ /\___/\ / \/\
;*** | /\/ \ __/ \_/ \/ |
;*** | | \/ |
;*** 30% |_____ _BB__| |_____ _____
;*** | | | |
;*** | | | |
;*** 0% |_______| |_______|
;***
;*** |<-A->|<--B-->|<-C->|<--------------E--------------->|<-A->|<--B-->|
;*** |<--------------------- 63.5 us -------------------->|
;***
;*** A: 1.5 us Llamado Portal Anterior (Front Porsh) previo a la Señal de Sincronismo vertical
;*** B: 4.7 us Sincronismo Horizontal
;*** C: 4.7 us Portal Posterior (Back Porsh) Posterior a la Señal de Sincronismo Ver Detalle de Burst (BB)
;*** E: 52.6 us Que corresponden al tiempo donde se envía la señal de video propiamente
;*** La señal de sincronismo entonces ocupa los tiempos A+B+C y representan un total de 10.9 us
;***
;*** Detalle de Burst (BB)
;***
;*** /
;*** |
;*** 30% ______ /\ /\ /\ /\_______|
;*** | \/ \/ \/ \/
;*** |
;*** 0% ______________|
;***
;*** -----B------->|<-F->|<------G------>|<--H-->|
;*** F: 0.6 us Llamado Breezeway
;*** G: 2.5 us Señal de Burst, dura entre 8 y 10 Ciclos de la Señal de Portadora (3,5794 Mhz) y 30% del Voltaje PP
;*** H: 1.6 us
;*************************************************************************************************************************************
Campo_0
;Se genera ahora la imagen de Video
;*** Portal Anterior, Parte A de la Señal
movlw 0x01 ;Apagamos Nivel de Negro, Nivel de Brillo y Encendemos nivel de Blanking
movwf LATA
call Wait_A ;Llamamos a la rutina de delay para el tramo A de la señal
;*** Sincronismo Vertical propiamente, parte B de la Señal
bcf LATA,BLANKING ; Apagamos todo nivel de señal
call Wait_B ;Llamamos a la rutina de delay para el tramo B de la señal
;*** portal posterior, Parte C de la Señal
bsf LATA,BLANKING ; Llevamos a la señal hasta el nivel de Blanking
call Wait_F ;Llamamos a la rutina de delay para el tramo F de la señal
movlw 0x80 ; Llevo a la salida la señal de Burst...
movwf LATB ; ...Sincronizada con desfase 0º
call Wait_G ; Llamamos a la rutina de delay de 2.5 us correspondiente al Burst (Tramo G)
clrf LATB ; Apagamos la señal de Burst
call Wait_H ;Llamamos a la rutina de delay para el tramo G de la señal
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla (Parte E de la Señal)
movlw 0x03 ; Activamos los niveles para lograr brillo mínimo
movwf LATA
call Video_Signal ;Esta rutina muestra los pixeles en pantalla (56.2 uS)
clrf LATB ;Apagamos todo nivel de señal de color
decfsz LINEA,f ;Me fijo si se completaron las 252 líneas...
goto Campo_0 ;Aún no, repetimos esta parte
; 1/2 Cuadro Correspondiente a la línea 253
;*************************************************************************************************************************************
;*** La rutina deberá ser capáz de generar una señal de la forma siguiente
;***
;*** 100%
;*** _
;*** | / \ __
;*** | /\/ \ __/ \
;*** | | \/ |
;*** 30% |_____ _____| |_____
;*** | | | |
;*** | | | |
;*** 0% |_______| |_______|
;***
;*** |<-A->|<--B-->|<-C->|<--- 1/2 E --->|<-A->|<--B-->|
;*** |<--------------- 37.9 us --------------->|
;***
;*** A: 1.5 us Llamado Portal Anterior (Front Porsh) previo a la Señal de Sincronismo vertical
;*** B: 4.7 us Sincronismo Horizontal
;*** C: 4.7 us Portal Posterior (Back Porsh) Posterior a la Señal de Sincronismo
;*** 1/2 E: 27 us Que corresponden al tiempo donde se envía la señal de video propiamente
;*** La señal de sincronismo entonces ocupa los tiempos A+B+C y representan un total de 10.9 us
;*************************************************************************************************************************************
;*** Ahora debo generar el sincronismo horizontal y media línea, correspondiente a la 253
;*** Portal Anterior, Parte A de la Señal
movlw 0x01 ;Apagamos Nivel de Negro, Nivel de Brillo y Encendemos nivel de Blanking
movwf LATA
call Wait_A ;Llamamos a la rutina de delay para el tramo A de la señal
;*** Sincronismo Vertical propiamente, parte B de la Señal
bcf LATA,BLANKING ; Apagamos todo nivel de señal
call Wait_B ;Llamamos a la rutina de delay para el tramo B de la señal
;*** portal posterior, Parte C de la Señal
bsf LATA,BLANKING ; Llevamos a la señal hasta el nivel de Blanking
call Wait_F ;Llamamos a la rutina de delay para el tramo C de la señal)
movlw 0x80 ; Llevo a la salida la señal de Burst...
movwf LATB ; ...Sincronizada con desfase 0º
call Wait_G ; Llamamos a la rutina de delay de 2.5 us correspondiente al Burst (Tramo G)
clrf LATB ; Apagamos la señal de Burst
call Wait_H ;Llamamos a la rutina de delay para el tramo H de la señal
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla (Parte E de la Señal)
;*** Esta línea no la pintaremos con pixeles, ya que la pérdida es mínima y la implementación requeriría de mucha programación
movlw 0x03 ; Activamos los niveles para lograr brillo mínimo
movwf LATA
call Wait_E2 ;Llamamos a la rutina de delay para el tramo 1/2 E de la señal
;*** De ahora en más entramos en el segundo campo, de las líneas pares
; Debemos hacer:
; 6 Pulsos de Pre-ecualización
; 6 Pulsos de Sincronismo
; 6 Pulsos de Post-ecualización
; esto lo realiza la rutina VSincro
call VSincro
;*** Ahora debo esperar el tiempo faltante correspondiente a 1/2 línea
movlw 0x03 ; Activamos los niveles para lograr brillo mínimo
movwf LATA
call Wait_E2 ;Llamamos a la rutina de delay para el tramo 1/2 E de la señal
;*** Finalmente dibujo las 252 Líneas del Campo 1
;*** Cuadros Normales
movlw 0xFC
movwf LINEA ;Cargo la Variable línea con 252 (Que son los cuadros normales)
Campo_1
;*** Portal Anterior, Parte A de la Señal
movlw 0x01 ;Apagamos Nivel de Negro, Nivel de Brillo y Encendemos nivel de Blanking
movwf LATA
call Wait_A ;Llamamos a la rutina de delay para el tramo A de la señal
;*** Sincronismo Vertical propiamente, parte B de la Señal
bcf LATA,BLANKING ; Apagamos todo nivel de señal
call Wait_B ;Llamamos a la rutina de delay para el tramo B de la señal
;*** portal posterior, Parte C de la Señal
bsf LATA,BLANKING ; Llevamos a la señal hasta el nivel de Blanking
call Wait_F ;Llamamos a la rutina de delay para el tramo F de la señal
movlw 0x80 ; Llevo a la salida la señal de Burst...
movwf LATB ; ...Sincronizada con desfase 0º
call Wait_G ; Llamamos a la rutina de delay de 2.5 us correspondiente al Burst (Tramo G)
clrf LATB ; Apagamos la señal de Burst
call Wait_H ;Llamamos a la rutina de delay para el tramo H de la señal
;*** Aquí debe implementarse la rutina para presentar los pixeles en pantalla (Parte E de la Señal)
;*** por ahora solo esperaremos el tiempo de imagen (52.6 us)
movlw 0x03 ; Activamos los niveles para lograr brillo mínimo
movwf LATA
call Video_Signal ;Esta rutina muestra los pixeles en pantalla (52.6 uS)
clrf LATB ;Apagamos todo nivel de señal de color
decfsz LINEA,f ;Me fijo si se completaron las 252 líneas...
goto Campo_1 ;Aún no, repetimos esta parte
goto Inicio ;Finalmente Repetimos la rutina
VSincro
;*** Sincronismo Vertical
;*** La parte dificil viene en los sincronismos verticales
;*** La "National Television Systems Committee" describe la señal de video textualmente así:
;*************************************************************************************************************************************
;*** Field 0 contains 262.5 lines, as follows.
;***
;*** 3 lines: 6 pre-eq pulses
;*** 3 lines: 6 vertical sync pulses
;*** 3 lines: 6 post-eq pulses
;*** 253 lines: normal scan lines (many of these are invisible and some are reserved
;*** for closed-caption data, cable tv scrambler data, etc...
;*** but so far as sync is concerned, these lines are all "normal" scan lines)
;*** 0.5 lines: the last line of the field quits right in the middle!
;***
;*** Field 1 contains 262.5 lines, as follows.
;***
;*** 3 lines: 6 pre-eq pulses
;*** 3 lines: 6 vertical sync pulses
;*** 3.5 lines: 7 post-eq pulses
;*** 253 lines: normal scan lines
;***
;*** Con esta información el sincronismo vertical del Campo 1 correspondiente a las líneas Pares puede verse así:
;***
;*** 100%
;***
;***
;*** |\ /|
;*** | \| |
;*** 30% _/ |_ ___ ___ ___ ___ ___ ___ _ _ _ _ _ _ ___ ___ ___ ___ ___ ___
;*** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
;*** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
;*** 0% |_| |_| |_| |_| |_| |_| |_| |___| |___| |___| |___| |___| |___| |_| |_| |_| |_| |_| |_| |
;***
;*** <1> <2> <3> <4> <5> <6> <1-> <2-> <3-> <4-> <5-> <6-> <1> <2> <3> <4> <5> <6>
;*** |<Línea 253>|<-Línea 1->|<-Línea 2->|<-Línea 3->|<-Línea 4->|<-Línea 5->|<-Línea 6->|<-Línea 7->|<-Línea 8->|<-Línea 9->|
;*** |<------- Pre Ecualización ------->|<------ Sincronismo Vertical------>|<------- Post Ecualización ------->|
;*** | Tiempo en Bajo 2.5 us | Tiempo en Bajo 27 us | Tiempo en Bajo 2.5 us
;*** | Tiempo en Alto 29 us | Tiempo en Alto 5 us | Tiempo en Alto 29 us
;***
;*** Mientras que el sincronismo del Campo 0 correspondiente a las líneas Pares puede verse así:
;***
;*** 100%
;***
;***
;*** |\
;*** | \
;*** 30% _/ | ___ ___ ___ ___ ___ ___ _ _ _ _ _ _ ___ ___ ___ ___ ___ ________
;*** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
;*** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
;*** 0% |_| |_| |_| |_| |_| |_| |_| |___| |___| |___| |___| |___| |___| |_| |_| |_| |_| |_| |_| |
;***
;*** <1> <2> <3> <4> <5> <6> <1-> <2-> <3-> <4-> <5-> <6-> <1> <2> <3> <4> <5> <6>
;*** |<-M1->|<-Línea 1->|<-Línea 2->|<-Línea 3->|<-Línea 4->|<-Línea 5->|<-Línea 6->|<-Línea 7->|<-Línea 8->|<-Línea 9->|<M2>|
;*** |<------- Pre Ecualización ------->|<------ Sincronismo Vertical------>|<------- Post Ecualización ------->|
;*** | Tiempo en Bajo 2.5 us | Tiempo en Bajo 27 us | Tiempo en Bajo 2.5 us
;*** | Tiempo en Alto 29 us | Tiempo en Alto 5 us | Tiempo en Alto 29 us
;***
;*** Siendo M1: La línea 253 (Media Línea) y M2: La línea 10 de las Pares (Media Línea)
;*************************************************************************************************************************************
;*** Pre Ecualización
movlw 0x06
movwf LINEA ;Cargo la Variable línea con 6
clrf LATB ;Apago todo nivel de color a la salida
bcf LATA,BLK_LEV
Pre_EQ
bcf LATA,BLANKING
call Wait_C ;(2.4 us)
bsf LATA,BLANKING
call Wait_D ;(29 us)
decfsz LINEA,f
goto Pre_EQ
movlw 0x06
movwf LINEA ;Cargo la Variable línea con 6
Vert_Sinc
bcf LATA,BLANKING
call Wait_E2 ;(27 us)
bsf LATA,BLANKING
call Wait_B ;(4.6 us) Casi los 5 us que necesitamos
nop ; Agregamos un par de nop para completar el tiempo
nop
decfsz LINEA,f
goto Vert_Sinc
;*** Post Ecualización
movlw 0x06
movwf LINEA ;Cargo la Variable línea con 6
Post_EQ
bcf LATA,BLANKING
call Wait_C ;(2.4 us)
bsf LATA,BLANKING
call Wait_D ;(29 us)
decfsz LINEA,f
goto Post_EQ
return
;Esta Rutina efectua una demora de 1.5 us
Wait_A
movlw 0x03
movwf d1
Delay_A
decfsz d1, f
goto Delay_A
return
;Esta Rutina efectua una demora de 4.7 us
Wait_B
movlw 0x0C
movwf d1
Delay_B
decfsz d1, f
goto Delay_B
return
;Esta Rutina efectua una demora de 2.5 us
Wait_C
movlw 0x06
movwf d1
Delay_C
decfsz d1, f
goto Delay_C
return
;Esta Rutina efectua una demora de 29 us
Wait_D
movlw 0x73
movwf d1
Delay_D
decfsz d1, f
goto Delay_D
nop
nop
return
;Esta Rutina efectua una demora de 52.6 us
Wait_E
movlw 0xD2
movwf d1
Delay_E
decfsz d1, f
goto Delay_E
return
;Esta Rutina efectua una demora de 27 us
Wait_E2
movlw 0x6B
movwf d1
Delay_E2
decfsz d1, f
goto Delay_E2
nop
nop
return
;Esta Rutina efectua una demora de 0.6 us
Wait_F
goto $+2
return
;Esta Rutina efectua una demora de 2.5 us
Wait_G
movlw 0x06
movwf d1
Delay_G
decfsz d1, f
goto Delay_G
return
;Esta Rutina efectua una demora de 1.6 us
Wait_H
movlw 0x03
movwf d1
Delay_H
decfsz d1, f
goto Delay_H
return
Video_Signal
;52.6 us
movlw 0x20 ; Cargo la dirección inicial donde tengo los pixeles a mostrar
movwf TBLPTRL
movlw 0x10 ; En este caso hago un bucle que leerá 16 colores base y solo incrementaremos su brillo
; esto formará 16 barras de colores en pantalla, cada barra mostrará elmismo color con
; 16 niveles de brillo.
movwf d1
Muestra_Pixeles
tblrd*+ ; Leo la tabla e incremento
movf TABLAT, W ; Paso el dato a W
movwf LATB ; Pongo el pixel en pantalla
nop ; espero un ciclo con el mismo pixel
incf LATB ; Incremento el brillo
nop ; espero un ciclo con el mismo color y nivel de brillo
; Este proceso se repite hasta llegar al máximo brillo
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
incf LATB
nop
decfsz d1,f
goto Muestra_Pixeles
return
end ;Fin del Programa