Autor Tema: Decodificador Decimal a 14 segmentos con PIC 16F876  (Leído 5811 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado JohnMacklo

  • PIC10
  • *
  • Mensajes: 5
Decodificador Decimal a 14 segmentos con PIC 16F876
« en: 21 de Diciembre de 2010, 17:12:01 »
Saludos amigos del foro:

Aqui les traigo un pequeño programa que hice para decodificar lo que tuviera en binario a 14 segmentos. Sé que lo comun es tener 7 segmentos, pero yo tenía a la mano estos displays de ANODO COMUN y fueron los que utilice.
En este programa no solo viene la decodificación en si. Tambien se pueden dar cuenta que, al contrario de los que muchos dicen de PIC Basic Pro, si se pueden indexar los bits, e incluso, generar "puertos virtuales" utilizando los bits que tengas a la mano para crear un solo puerto que te sirva a tus propositos.
Este indexado se puede aplicar a las entradas y a las salidas y yo lo he venido utilizando desde hace ya varios meses con bastantes buenos resultados. En este ejemplo se aprecia perfectamente la indexación para las salidas que conforman los segmentos del display. Más adelante, publicaré un ejemplo para indexar las entradas.

Aqui les dejo el codigo; esta perfectamente comentado para que se den una idea de como trabaja el programa. Tambien les dejo el circuito que utilize para dicha decodificación.

Por si no lo he dicho antes, yo trabajo en MicroCode Studio 3.0.0.5 y mi compilador es PICBASIC PRO 2.50a. Se programar en ensamblador, pero luego de que trabaje en PICBASIC, me di cuenta de que en emsamblador no se podian conseguir programas tan complejos con la facilidad que se puede con un lenguaje de alto nivel. Para aquellos detractores de este lenguaje, puedo decirles que con un poco de tezón y razonamiento, se pueden conseguir muy buenos, por no decir excelentes resultads, que no tienen que pedirle nada al "C" o a "linux".

El programa es el siguiente:

'**************************************************************************
'*  Name    : Prueba_Marquesina.pbp                                       *
'*  Author  : JohnMacklo                                    *
'*  Notice  : Copyright (c) 2010                                          *
'*          : All Rights Reserved                                         *
'*          : JohnMacklo                                    *
'*  Date    : 18/Diciembre/2010                                           *
'*  Version : 1.0                                                         *
'*  Notes   : Desarrollado para PIC16F876 @ 20Mhz                         *
'*          : Decodificación binaria a 14 segmentos.                      *
'**************************************************************************
;----[Configuración del cristal de la PIC]---------------------------------
DEFINE OSC 20              ' Resonador de 20MHz.
;----[Configuración de puerto serial de la PIC]----------------------------
DEFINE SER2_BITS 8          ' 8 bits de datos para transmisión serial.
;----[Configuración de los canales analógicos de la PIC]-------------------
DEFINE ADC_BITS      10     ' Voltaje analógico con resolución de 10 bits.
DEFINE ADC_CLOCK     3       ' Tipo de oscilador (3 = Resonador)
DEFINE ADC_SAMPLEUS 100     ' Tiempo de muestreo del ADC en microsegundos.
;----[Configuración de registros de entradas y salidas de la PIC]----------
ADCON1   = $87 ' 5 Canales digitales en A.
TRISA   = $1F ' Todos los bits del puerto A, excepto PORTA.5, son entradas.
TRISB   = $00 ' Todos los bits del puerto B son salidas.
TRISC   = $00 ' Todos los bits del puerto C son salidas.
;----[Bits usados para la asignación del nodo]-----------------------------
symbol NodoBit0 = PORTA.4  ' Bit0 del registro usado para armar el nodo.
symbol NodoBit1 = PORTA.3  ' Bit1 del registro usado para armar el nodo.
symbol NodoBit2 = PORTA.2  ' Bit2 del registro usado para armar el nodo.
symbol NodoBit3 = PORTA.1  ' Bit3 del registro usado para armar el nodo.
symbol NodoBit4 = PORTA.0  ' Bit4 del registro usado para armar el nodo.
;----[Salidas Digitales]---------------------------------------------------
symbol DisplaySelect0 = PORTC.0 ' Salida 0 para habilitar las unidades. 
symbol DisplaySelect1 = PORTA.5 ' Salida 1 para habilitar las decenas. 
symbol DisplayOutputA = PORTC.2 ' Segmento "A" del display de 14 segmentos.
symbol DisplayOutputB = PORTC.1 ' Segmento "B" del display de 14 segmentos.
symbol DisplayOutputC = PORTB.0 ' Segmento "C" del display de 14 segmentos.
symbol DisplayOutputD = PORTB.1 ' Segmento "D" del display de 14 segmentos.
symbol DisplayOutputE = PORTB.6 ' Segmento "E" del display de 14 segmentos.
symbol DisplayOutputF = PORTC.7 ' Segmento "F" del display de 14 segmentos.
symbol DisplayOutputG = PORTC.3 ' Segmento "G" del display de 14 segmentos.
symbol DisplayOutputH = PORTC.6 ' Segmento "H" del display de 14 segmentos.
symbol DisplayOutputI = PORTC.5 ' Segmento "I" del display de 14 segmentos.
symbol DisplayOutputJ = PORTC.4 ' Segmento "J" del display de 14 segmentos.
symbol DisplayOutputK = PORTB.2 ' Segmento "K" del display de 14 segmentos.
symbol DisplayOutputL = PORTB.3 ' Segmento "L" del display de 14 segmentos.
symbol DisplayOutputM = PORTB.4 ' Segmento "M" del display de 14 segmentos.
symbol DisplayOutputN = PORTB.5 ' Segmento "N" del display de 14 segmentos.
symbol SrlOutput      = PORTA.5 ' Salida para enviar el numero de nodo.
;----[Configuración de constantes del programa]----------------------------
Lapso         con 10      ' Pausa mínima entre despliegue de caracteres.
IniTrans      con "["     ' Caracter indicador de inicio de comando.
FinTrans      con "]"     ' Caracter indicador de final de comando.
;----[Configuración de variables del programa]-----------------------------
Digito        var word[11]' Arreglo para guardar decodificaciones a 14 seg.
DigitoASCII   var byte[4] ' Arreglo para guardar los digitos ASCII.
Respuesta     var byte[4] ' Arreglo para guardar la respuesta a enviar.
NodoASCII     var byte[2] ' Arreglo para guardar el valor del nodo (ASCII).
PuertoDisplay var word    ' Word usada para indexar los bits de salida.
ModMllrs      var word    ' Word usada para guardar el modulo de millares.
ModCntns      var word    ' Word usada para guardar el modulo de centenas.
ModDcns       var word    ' Word usada para guardar el modulo de decenas.
ValToASCII    var word    ' Word usada para la conversión DECIMAL-ASCII.
NodoPIC       VAR BYTE    ' Numero de nodo asignado por el dipswitch.
NodoBitAux    var byte    ' Byte auxiliar para la conversion BIN-HEX.
PuertoNodo    var byte    ' Byte usado para indexar los bits del nodo.
LoopNodo      var byte    ' Byte usado para el ciclo FOR del nodo.
J3            var byte    ' Byte para el ciclo FOR de conversión DEC-ASCII.
;----[Inicio de programa principal]----------------------------------------
Principal: 
DisplaySelect0 = 1        ' Limpia el bit para seleccionar las unidades.
DisplaySelect1 = 1        ' Limpia el bit para seleccionar las decenas.
PAUSE Lapso * 50
;----[Lazo principal]------------------------------------------------------
Lazo:
gosub TablasDisplay         ' Llama a subrutina "TablasDisplay".
gosub NumeroNodo            ' Llama a subrutina "NumeroNodo".
DisplaySelect1 = 0          ' Selecciona las decenas.
DisplaySelect0 = 1          ' Limpia el bit para seleccionar las unidades.
PuertoDisplay = Digito[DigitoASCII[2]] ' Muestra el valor de las decenas.
gosub DriveDisplayOutputs   ' Llama a subrutina "DriveDisplayOutputs".
pause Lapso                 ' Pausa necesaria entre caracteres.
DisplaySelect1 = 1          ' Limpia el bit para seleccionar las decenas.
DisplaySelect0 = 0          ' Selecciona las unidades.
PuertoDisplay = Digito[DigitoASCII[3]] ' Muestra el valor de las unidades.
gosub DriveDisplayOutputs   ' Llama a subrutina "DriveDisplayOutputs".
pause Lapso                 ' Pausa necesaria entre caracteres.
PuertoDisplay = Digito[10]  ' Limpia ambos displays.
gosub DriveDisplayOutputs   ' Llama a subrutina "DriveDisplayOutputs".
Respuesta[0] = IniTrans     ' Byte con el caracter de inicio de comando.
Respuesta[1] = NodoASCII[0] ' Byte con las decenas del nodo.
Respuesta[2] = NodoASCII[1] ' Byte con las unidades del nodo.
Respuesta[3] = FinTrans     ' Byte con el caracter de fin de comando.
SEROUT2 SrlOutput,84,[str Respuesta \4] ' Envia el nodo via serial.
goto Lazo
end
           
;----[Subrutinas]----------------------------------------------------------
'**************************************************************************
' Subrutina:           NumeroNodo
' Precondición:        Ninguna.
' Entradas:            PuertoNodo.0[0].
'                      PuertoNodo.0[1].
'                      PuertoNodo.0[2].
'                      PuertoNodo.0[3].
'                      PuertoNodo.0[4].
' Salidas:             Nodo - La suma total de los registros de entrada.
' Efectos secundarios: Si se asigna un numero prohibido de nodo, la PIC se
'                      mantendrá en pausa, esperando a que el usuario
'                      modifique el numero del nodo.
' Comentarios:         Suma los bits binarios para ensamblar un solo
'                      caracter hexadecimal.
' Nota:               
'**************************************************************************
NumeroNodo:
NodoBitAux   = %00000000
NodoPIC      = %00000000
for LoopNodo = 0 to 4
    PuertoNodo.0 = NodoBit0
    PuertoNodo.1 = NodoBit1
    PuertoNodo.2 = NodoBit2
    PuertoNodo.3 = NodoBit3
    PuertoNodo.4 = NodoBit4
    NodoBitAux = PuertoNodo.0[LoopNodo]
    NodoBitAux = ((NodoBitAux & %00000001)<< (LoopNodo))
    NodoPIC    = NodoPIC + NodobitAux
next LoopNodo
ValToASCII  =  NodoPIC         ' Asigna el valor del nodo a una variable decimal para ser convertido a valores ASCII.
gosub DecimalToASCII           ' Llama a subrutina "DecimalToASCII".
NodoASCII[0] = DigitoASCII[2]  ' Decenas del nodo , convertidas a ASCII, guardadas en el registro "NodoASCII[0]".
NodoASCII[1] = DigitoASCII[3]  ' Unidades del nodo , convertidas a ASCII, guardadas en el registro "NodoASCII[1]".
Return

'**************************************************************************
' Subrutina:           TablasDisplay
' Precondición:        Ninguna.
' Entradas:            Ninguna.
' Salidas:             Digito - En este arreglo se guardan los datos a
'                      ser desplegados en los displays.
' Efectos secundarios: Ninguno.
' Comentarios:         Se guardan los digitos del 0 al 9 en su respectivo
'                      elemento del arreglo, de manera que al llamar a
'                      dicho elemento, el numero a desplegar en 14
'                      segmentos este implicito. El elemento 10 del arreglo
'                      sirve para limpiar lo mostrado en los displays.
' Nota:                Si se quisieran utilizar displays de 7 segmentos,
'                      se utiliza esta misma subrutina sin necesidad de
'                      modificar el contenido de cada elemento.
'**************************************************************************
TablasDisplay:
             'XPnmlkjihgfedcba
Digito[0]  = %1101110111000000
Digito[1]  = %1111110111111001
Digito[2]  = %1111101110100100
Digito[3]  = %1111101111110000
Digito[4]  = %1110101010011111
Digito[5]  = %1111101110010010
Digito[6]  = %1111101110000010
Digito[7]  = %1110110111111110
Digito[8]  = %1111101110000000
Digito[9]  = %1111101110010000           
Digito[10] = %1111111111111111           
return

'**************************************************************************
' Subrutina:           DriveDisplayOutputs
' Precondición:        Ninguna.
' Entradas:            Ninguna.
' Salidas:             PuertoDisplay.0 - PuertoDisplay.13.
' Efectos secundarios: Ninguno.
' Comentarios:         Pasa por una word auxiliar los bits de los puertos
'                      asignados para ensamblar el numero de salida
'                      digital, para poder indexarlos despues en otra
'                      subrutina.
' Nota:               
'**************************************************************************
DriveDisplayOutputs:
DisplayOutputA = PuertoDisplay.0
DisplayOutputB = PuertoDisplay.1
DisplayOutputC = PuertoDisplay.2
DisplayOutputD = PuertoDisplay.3
DisplayOutputE = PuertoDisplay.4
DisplayOutputF = PuertoDisplay.5
DisplayOutputG = PuertoDisplay.6
DisplayOutputH = PuertoDisplay.7
DisplayOutputI = PuertoDisplay.8
DisplayOutputJ = PuertoDisplay.9
DisplayOutputK = PuertoDisplay.10
DisplayOutputL = PuertoDisplay.11
DisplayOutputM = PuertoDisplay.12
DisplayOutputN = PuertoDisplay.13
return

'**************************************************************************
' Subrutina:           DecimalToASCII
' Precondición:        Ninguna.
' Entrada:             ValToASCII - El numero decimal que será convertido a
'                                   4 digitos ASCII.
' Salidas:             DigitoASCII[0] - Carácter ASCII que representa los
'                                       millares del número decimal.
'                      DigitoASCII[1] - Caracter ASCII que representa las
'                                       centenas del número decimal.
'                      DigitoASCII[2] - Caracter ASCII que representa las
'                                       decenas del número decimal.
'                      DigitoASCII[3] - Caracter ASCII que representa las
'                                       unidades del número decimal.
' Efectos secundarios: Ninguno.
' Comentarios:         Convierte un número decimal (hasta 9999) a cuatro
'                      caracteres ASCII. Se utiliza el método de divisiones
'                      sucesivas.
' Nota:                Cualquier valor decimal menor o igual que 65535,
'                      puede ser convertido a ASCII, solamente hay que
'                      agregar un digito mas, teniendo en cuenta que el
'                      dígito más significativo seria el DigitoASCII[0] y
'                      el ménos significativo sería el DigitoASCII[n].
' Nota2:               Si se descomenta el "+48" dentro del ciclo FOR, se
'                      convierte a verdadero ASCII. Esta comentado en esta
'                      subrutina por necesitarse caracteres decimales. 
'**************************************************************************
DecimalToASCII:
ModMllrs       = 0
ModCntns       = 0
ModDcns        = 0
DigitoASCII[0] = 0
DigitoASCII[1] = 0
DigitoASCII[2] = 0
DigitoASCII[3] = 0
DigitoASCII[0] = (ValToASCII/1000)  ' 1023 /1000=1   "Millares".
ModMllrs       = (ValToASCII//1000) ' 1023//1000=023 "Modulo de Millares".
DigitoASCII[1] = (ModMllrs/100)     '  023 /100 =0   "Centenas".
ModCntns       = (ModMllrs//100)    '  023//100 =23  "Modulo de Centenas".
DigitoASCII[2] = (ModCntns/10)      '   23 /10  =2   "Decenas".
ModDcns        = (ModCntns//10)     '   23//10  =3   "Modulo de Decenas".
DigitoASCII[3] = (ModDcns/1)        '    3 /1   =3   "Unidades".
for J3 = 0 to 3
    If (DigitoASCII[J3] >= 0) Then  ' El valor encontrado esta entre 0 y 9.
       if (DigitoASCII[J3] <= 9) then                   '
          DigitoASCII[J3] = DigitoASCII[J3]' + 48
       endif
    EndIf
next J3   
ValToASCII = 0
Return

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: Decodificador Decimal a 14 segmentos con PIC 16F876
« Respuesta #1 en: 21 de Diciembre de 2010, 20:03:06 »
Hace años que no sabia de esos displays, enhorabuena por llevarlo a buen puerto.
Saludos desde Granada, España.


 

anything