Вы находитесь на странице: 1из 12

'********************************** PIC Entrenadora BASIC *************************************** 'NOMBRE: 16F88_Pic_EBasic_LCD_RS232_Menu_10 'VERSION: 1.

0 'MICRO: PIC16F88 'Fecha/Autor: 4/07 By COS 'DESCRIPCION: Control de los led de la EBasic por medio de un menu en el Hyperterminal 'programar el hyperterminal del Windows: 'Bits por segundo: 4800 'Bits de datos: 8 'Paridad: Ninguno 'Control de flujo: Ninguno 'LCD a 4 bit, sin bit de RW '************************************************************************* *********************** '-------------------------------------PUERTOS DEFINIDOS POR EL SISTEMA--------------------------'-------------------------------------Puertos del LCD--------------------------------------------Define LCD_BITS = 4 'indicamos que el bus de datos del lcd sera de 4bit Define LCD_DREG = PORTA 'el bus de datos sera el puerto A Define LCD_DBIT = 0 'el bus de datos seran los 4 bit menos significativos del puerto A Define LCD_RSREG = PORTB 'el bit de control RS sera del puerto B Define LCD_RSBIT = 7 'se usara el RB7 como RS Define LCD_EREG = PORTB 'el bit de control E sera del puerto B Define LCD_EBIT = 6 'se usara el RB6 como E 'Define LCD_RWREG = PORTA 'el bit de control RW sera del puerto A (si se suprime el compilador no protesta) 'Define LCD_RWBIT = 5 'se usara el RA5 como RW (si se suprime el compilador no protesta) Define LCD_COMMANDUS = 2000 'Tiempo de espera despues de ejecutar un comand del lcd en uSeg. Define LCD_DATAUS = 50 'Tiempo de espera despues de enviar un dato al LCD en uSeg. Define LCD_INITMS = 5 '50 'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg. '--------------------------------Reasignacion de nombres--------------------------------------Symbol led_amarillo = PORTA.7 'led amarillo Symbol led_verde = PORTB.0 'led verde '--------------------------------Definicion de caracteres de control del Hyperterminal-------Const ff = 0x0c 'FF, Avance de pagina

Const bell = 0x07 'BELL, Seal sonora Const sp = 0x20 'SP, Espacio Const bksp = 0x08 'BKSP, Retroceso '--------------------------------------Declaracion DE VARIABLES-----------------------------------'-------------------------------------Variables sub_rutinas del puerto serie--------------------Dim assi As Byte 'Contiene el valor de lectura del puerto serie Dim n_usart As Byte 'Numero de datos del USART y del bufer IMAGEN de control Dim usart As Byte 'Variable indice que apunta al ultimo dato adquirido por la USART Dim aux_usart As Byte 'Auxiliar de la variable indice usart del USART Dim c_serial As Byte 'Como USART pero para la lectura de control del bufer IMAGEN Dim bufer As Byte 'Indica si hay datos por leer en el bufer USART Dim n_aux As Byte 'contador para borrar el bufer_soft '************************************variables de los timer**************************************** Dim pause As Word 'contiene el valor para simular el comando Waitms Dim timer_1ms As Word 'base de tiempos se incrementa cada 1mSeg, timer del PAUSE '------------------------------------Variables tipo array puerto serie--------------------------------Dim usart_imagen(91) As Byte 'Componen el bufer IMAGEN para control del bufer USART Dim usart_bufer(91) As Byte 'Componen el bufer de la USART de bajo nivel '-----------------------------------------------ASIGNACIONES--------------------------------------'-------------------------------------Asignacion de valores del TIMER1---------------------------pause = 0 'genera una pausa en MSeg timer_1ms = 0 'en mSeg '-------------------------------------Asigna valores a las variables de la rutina del puerto serieusart = 0 aux_usart = 0 c_serial = 0 bufer = 0 n_usart = 90 assi = 0 n_aux = 0 '**************************************DEFINICION DE PUERTOS************************************* '----------------------ASIGNACION DE I/O y valores de inicio de las salidas---------------------

ANSEL = 0x00 'los pin I/O digitales 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) 'TRISB.5 = 0 'RB5(Tx, RS232) TRISB.2 = 1 'RB2 (Rx, RS232) PORTB.3 = 1 'luz lcd a on (RB3) PORTA.7 = 1 'led amarillo a off PORTB.0 = 1 'led verde a off '------------------------------------INICIO DEL PUERTO SERIE, TIMER E INTERRUPCIONES----------------Hseropen 4800 'Velocidad del puerto serie e inicializa los comandos de bajo nivel que controlan la USART Gosub clear_bufer 'Borra el BUFFER IMAGEN y por lo tanto tambien al USART, OBLIGATORIO POR LO MENOS UNA VEZ T1CON.TMR1CS = 0 'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion T1CON.T1CKPS0 = 0 'factor del preescales del timer1, 0 T1CON.T1CKPS1 = 0 'factor del preescales del timer1, 0 TMR1H = 0xf8 'carga el registro del contador para que desborde cada 1mSeg, byte alto TMR1L = 0x2f 'carga el registro del contador para que desborde cada 1mSeg, byte bajo T1CON.TMR1ON = 1 'habilitacion del TMR1, comienza a incrementarce 'PIE1.TMR1IE = 1 'activa las interrupciones del timer1 'PIE1.RCIE = 1 'Activa la interrupcion de la USART en modo rx INTCON.PEIE = 1 'bit de habilitacion de interrupciones de perifericos Enable 'INTCON.GIE habilita todas las interrupciones globales '--------------------------------------Inicio Programa------------------------------------------------Lcdinit 'inicializa el LCD sin cursor PIE1.TMR1IE = 1 'activa las interrupciones del timer1 PIE1.RCIE = 1 'Activa la interrupcion de la USART en modo rx pause = 0 '1000 'prepara una pausa de 1Seg Gosub pause_ms 'espera el tiempo que indica pause Lcdout "16F88_RS232_MENU" 'imprime en el LCD el literal

Lcdcmdout LcdLine2Home 'selecciona linea y cursor al principio Lcdout "4800 Baud.--1.0" 'escribe la cadena de literales en el lcd Hserout ff, CrLf, CrLf, "VER. 1.0 - TX/RX", CrLf, "TX -> MENU POR RS232", CrLf, "By COS", CrLf, CrLf 'envia presentacion al RS232 Gosub clear_bufer 'Borra el BUFFER IMAGEN y por lo tanto tambien al USART, OBLIGATORIO POR LO MENOS UNA VEZ pause = 0 '3000 'prepara una pausa de 3Seg Gosub pause_ms 'hace una pausa de tiempo indicado por pause 'Lcdcmdout LcdClear 'borra el display '--------------------------------------Main Programa--------------------------------------------------Gosub print_menu 'envia el menu principal al hyperterminal main: Gosub readserial 'lee un caracter del puerto serie, salto con retorno If assi >= 0x30 And assi <= 0x31 Then 'filtro de caracteres, "0" y el "1" Hserout bell 'seal sonora Hserout assi 'envia al hyperterminal pause = 0 '1000 'carga la base de tiempos Gosub pause_ms 'espera el tiempo indicado por pause If assi = "0" Then Gosub control_led_amarillo 'salta a la rutina de control del led amarillo If assi = "1" Then Gosub control_led_verde 'salta a la rutina de control del led verde Endif Goto main End '--------------------------------------FIN DEL MAIN------------------------------------------'--------------------------------------Rutinas Programa---------------------------------------------print_menu: Hserout ff 'Paguina en blanco Hserout " Menu de Control de los Led de la Pic EBasic ", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "------------------------------------------------", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "0 - Para menu Led amarillo", CrLf 'implime la cadena literal y salta a la siguiente linea Hserout "1 - Para menu Led verde", CrLf 'implime la cadena literal y salta siguiente linea Hserout "------------------------------------------------", CrLf 'implime la cadena literal y

salta siguiente linea Hserout "->" 'cursor Hserout bell 'seal sonora Return control_led_verde: Hserout ff 'pagina en blanco Hserout " nueva linea Hserout "---------------------------------", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "0 - Led verde a Off", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "1 - Led verde a On", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "2 - Para Salir", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "---------------------------------", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "->" 'cursor assi = 0 'borra el ultimo caracter leido del bufer serie While assi <> "2" 'controla el menu Gosub readserial 'lee caracter del bufer serial (retorna en assi) If assi >= 0x30 And assi <= 0x32 Then 'filtro de opciones o teclas Hserout bell 'seal sonora Hserout assi 'caracter leido del bufer serie pause = 0 '1000 'prepara una pausa de 1Seg. Gosub pause_ms 'pausa indicada por pause Hserout bell 'seal sonora Gosub retrocede_caracter 'salto a la rutina de borra caracter If assi = "0" Then led_verde = 1 'led verde a off If assi = "1" Then led_verde = 0 'led verde a on If assi = "2" Then Gosub print_menu 'reimprime el menu principal Endif Wend Return control_led_amarillo: Hserout ff 'pantalla en blanco Hserout " nueva linea Hserout "------------------------------------", CrLf 'implime la cadena literal y salta a una nueva linea Menu control del Led Amarillo ", CrLf 'implime la cadena literal y salta a una Menu control del Led Verde ", CrLf 'implime la cadena literal y salta a una

Hserout "0 - Led Amarillo a Off", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "1 - Led Amarillo a On", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "2 - Para Salir", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "------------------------------------", CrLf 'implime la cadena literal y salta a una nueva linea Hserout "->" 'cursor assi = 0 'borra el ultimo caracter leido del bufer serie While assi <> "2" 'controla el menu Gosub readserial 'lee caracter del bufer serial (retorna en assi) If assi >= 0x30 And assi <= 0x32 Then 'filtro de opciones o teclas Hserout bell 'seal sonora Hserout assi 'caracter leido del bufer serie pause = 0 '1000 'prepara una pausa de 1Seg. Gosub pause_ms 'pausa indicada por pause Hserout bell 'seal sonora Gosub retrocede_caracter 'salto a la rutina de borra caracter If assi = "0" Then led_amarillo = 1 'led amarillo a off If assi = "1" Then led_amarillo = 0 'led amarillo a on If assi = "2" Then Gosub print_menu 'reimprime el menu principal Endif Wend Return retrocede_caracter: 'borra caracter Hserout bksp, sp, bksp Return pause_ms: 'rutina de espera, rutina tipo Waitms, pause establese el tiempo total en mSeg timer_1ms = 0 'al borrar el contador se activa y comienza la cuenta de mSeg While timer_1ms < pause 'tiempo en mSeg maximos a contar Wend Return '------------------------------ rutinas para el control del bufer del puerto serie------------readserial: 'RUTINA DE LECTURA DEL BUFFER DEL PUERTO SERIE (ASSI) If bufer = 1 Then 'si bufer tiene datos assi = usart_bufer(c_serial) 'se lee el valor del bufer y se asigna assi usart_imagen(c_serial) = 0 'se marca como leida para que pueda ser llenada de nuevo c_serial = c_serial + 1 'se incrementa el indice del bufer If c_serial >= n_usart Then c_serial = 0 'se verifica si se llego al final del bufer

If usart_imagen(c_serial) = 0 Then bufer = 0 'si no quedan mas datos en el bufer se marca como vacio Else assi = 0 Endif Return clear_bufer: 'inicializa el bufer imagen y borra error del puerto fisico en modo Rx '_________________________Borra e inicializa el bufer imagan del puerto serie c_serial = 0 While c_serial <= n_usart 'se ejecuta tantas veces como variables tiene el bufer usart_imagen(c_serial) = 0 'borra el indicador de variable del bufer con datos c_serial = c_serial + 1 Wend c_serial = 0 'variables de control del bufer usart = 0 bufer = 0 assi = 0 '_________________________Borra el error del puerto serie en Rx RCSTA.OERR = 0 RCSTA.CREN = 0 RCSTA.CREN = 1 Return '--------------------------------------SIBRUTINAS ESPECIALES-------------------------------------------On Interrupt 'desactiva las interrupciones Save System 'Guarda los valores del sistema '*****************************base de tiempos******************************************** If PIR1.TMR1IF = 1 Then 'comprueba que la interrupcion la proboco el timer1 If timer_1ms < pause Then timer_1ms = timer_1ms + 1 'contador para control del timer_1ms TMR1H = 0xf8 'recarga el contador del timer1 para que desborde pasado 1mSeg, byte alto TMR1L = 0x2f 'recarga el contador del timer1 para que desborde pasado 1mSeg, byte bajo PIR1.TMR1IF = 0 'borra el bit de salto del timer1 Endif '*****************************BUFFER PUERTO

SERIE**************************************** If PIR1.RCIF = 1 Then 'comprueba que es esta la interrupcion activa del modulo USAR If usart < n_usart Then 'comprueba que el bufer de entrada no esta lleno If usart_imagen(usart) = 0 Then 'comprueba que la posicion esta vacia aux_usart = usart 'retiene la posicion antigua del bufer usart = usart + 1 'indica cual sera la posicion siguiente del bufer usart_imagen(aux_usart) = 1 'indica que hay dato en el bufer de entrada bufer = 1 'indica que el bufer tine datos Hserget usart_bufer(aux_usart) 'carga el dato en el bufer Else Hserget usart_bufer(n_usart) 'descarga la usart para que no se bloquee porque el bufer de entrada esta lleno Endif Else If usart_imagen(0) = 0 Then 'comprueba que esta vacia la primera posicion del bufer usart_imagen(0) = 1 'marca que hay dato en esa posicion del bufer bufer = 1 'marca que el bufer tiene datos usart = 1 'establece la proxima posicion del bufer Hserget usart_bufer(0) 'lee la usart y guarda el dato en el bufer Else Hserget usart_bufer(n_usart) 'descarga la usart porque el bufer esta lleno Endif Endif PIR1.RCIF = 0 'borra el bit de salto del Rx Endif '_________________________Borra el error del puerto serie en Rx If RCSTA.OERR = 1 Then RCSTA.OERR = 0 RCSTA.CREN = 0 RCSTA.CREN = 1 Endif Resume 'activa las interrupciones y retorna al curso normal del programa antes del salto End

;******************************************************************* ; INTERFAZ SERIE RS232 - ECO Y DISPLAY EN LEDS ; CONVERTIDOR SERIE RS232 - PARALELO 8 BITS ;******************************************************************* LIST P=16F628, R=DEC #include "P16F628.INC" __CONFIG ; Usar el PIC16F628 y sistema decimal ; Incluye datos de PIC16F628A

_CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF

;******************************************************************* ; CONFIGURACION ;******************************************************************* ; ; ; ; ; El PIC es configurado para usar todas las entradas y salidas posibles = 16. Por eso no se usa el oscilador con cristal externo, lo que deja libres las patas 15 y 16 para usar como bits de puerto. Se define el clock interno a 4 MHz. No se usa el master reset (pata 4), que queda convertida en el puerto A, bit 5 (entrada).

;******************************************************************* ; VARIABLES ;******************************************************************* contador EQU 0x28 ; variable dato_serie EQU 0x29 ; dato serie desde la PC ;******************************************************************* ORG 0x000 ; El programa empieza en 0x000

;******************************************************************* ; Inhibe comparadores ;******************************************************************* movlw movwf 7 CMCON

; CMCON=7 inhibir los comparadores

;******************************************************************* ; Inicializar Ports ;******************************************************************* movlw b'00000000' ; valor inicial portA movwf PORTA movlw b'00000000' ; valor inicial portB movwf PORTB bsf STATUS, RP0 ; Pg 1 RAM

movlw b'00000000' movwf TRISA ; salidas (para mostrar el dato en LEDS) ; de estas salidas, no usaremos ; PORTA 4, que tiene salida open drain, y ; PORTA 5, que slo puede ser entrada

movlw ; RB1 ; RB2 ; RB3 ; RB2 ; RB5 ; RB6 movwf

b'11001011' ; RB0 entrada (RX) = entrada (TX) = salida = entrada = salida del bit 4 del dato a LEDS = salida del bit 5 del dato a LEDS y RB7 = entradas TRISB

;******************************************************************* ; BAUD RATE para la comunicacin RS232 ; y otras definiciones para USART ;******************************************************************* ; Baud Rate = 9600, Sin Paridad, 1 Bit parada ; movlw movwf movlw movwf bcf 0x19 ; 0x19=9600 bps (0x0C=19200 bps) SPBRG b'00100100' ; TXSTA ; habilita la transmisin Async RP0 ; RAM PAGE 0 ; habilita de recepcin Async

STATUS,

movlw movwf

b'10010000' RCSTA

;******************************************************************* ; TIEMPO DE ESTABILIZACION ;******************************************************************* clrf contador decfsz contador,F goto estab movf movf movf call RCREG, RCREG, RCREG, W W W

estab

; vaca el buffer de recepcin

Bienvenida

; enva mensaje de bienvenida

;******************************************************************* ; LAZO PRINCIPAL ;******************************************************************* loop clrw btfss PIR1, RCIF ; (5) se fija si hay dato RS232 goto loop ; no, no lleg call recibeRS232 ; s, hay movwf dato_serie ; guarda dato (para uso de cualquier rutina) call enviaRS232 ; enva el eco a la PC call muestra ; muestra el caracter recibido en LEDS goto loop ;*********************************************************************************** ; RECIBE CARACTER SERIE - RS232 - DESDE LA PC ;***********************************************************************************

recibeRS232 movf RCREG, return

; guarda dato recibido en acumulador

;*********************************************************************************** ; ENVIA CARACTER SERIE - RS232 - A LA PC Y ESPERA A QUE HAYA SALIDO ;*********************************************************************************** enviaRS232 movwf TXREG ; envo el dato en acunulador w bsf STATUS, RP0 ; Pg 1 RAM Espere btfss TXSTA, TRMT ; transmision completa si es alto goto Espere bcf STATUS, RP0 ; Pg 0 RAM return ;*********************************************************************************** ; MUESTRA DATO ;*********************************************************************************** muestra movf dato_serie,w ; recupera el dato guardado movwf PORTA ; exhibe el dato en LEDS en PORTA btfss dato_serie,4 ; pero, como el PORTA tiene el bit 4 que es bcf PORTB, 4 ; open drain, nos conviene poner btfsc dato_serie,4 ; el bit 4 del dato en otra salida; bsf PORTB, 4 ; lo hacemos en el bit 4 del PORTB. btfss dato_serie,5 ; y , como el PORTA tiene el bit 5 que es bcf PORTB, 5 ; slo usable como entrada, tenemos que poner btfsc dato_serie,5 ; el bit 5 del dato en alguna salida; bsf PORTB, 5 ; lo hacemos en el bit 5 del PORTB. return ;*********************************************************************************** ; MENSAJES ;*********************************************************************************** Bienvenida ; los primeros caracteres 0x00 son ; para estabilizacin del circuito movlw 0x00 call enviaRS232 movlw 0x00 call enviaRS232 movlw 0x00 call enviaRS232 movlw 0x00 call enviaRS232 movlw 0x00 call enviaRS232 call msgCR movlw 'H' call enviaRS232 movlw 'o' call enviaRS232 movlw 'l' call enviaRS232

movlw 'a' call enviaRS232 movlw ' ' call enviaRS232 movlw 'a' call enviaRS232 movlw 'm' call enviaRS232 movlw 'i' call enviaRS232 movlw 'g' call enviaRS232 movlw 'o' call enviaRS232 msgCR movlw 0x0D call enviaRS232 movlw 0x0A goto enviaRS232 END

Вам также может понравиться