Autor Tema: [PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB  (Leído 10412 veces)

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

coco

  • Administrador
  • Terabyte
  • *****
  • Mensajes: 548
  • Reputación: +63/-3
    • Ver Perfil
[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« en: Noviembre 07, 2009, 07:20:43 pm »
Las 2 memorias que presente son EPROMs, osea, Ereasable Programable Read Only Memory. Yo las profane de una PC 386 ACER.
Ambas son de 28 pines, de la marca STMicroelectronics, pero presentan distintas entradas de direccion de memoria. La M27C256 es de 256Kbits de memoria, y por cada direccion de memoria, se lee un Byte (8 Bits). Sacando cuentas, tenemos 32Kbytes de memoria en total. Para la M27C512 es lo mismo, solamente que son 512Kbits y en resumen 64Kbytes.

ModeloPines de direccion de memoriaMemoria
M27C256
15
32Kbytes = 256Kbits
M27C512
16
64Kbytes = 512Kbits

Con esa tablita mas o menos te guias en cuantos pines (o bits) son necesarios para direccionar la cantidad de memoria que traen.

Si tengo 15 bits, el maximo va a ser 111111111111111 (15 bits 1) significan 32767 en decimal, que a su vez es logico, ya que 32Kbytes son 32768 Bits.

Ahora, si tengo 16 pines (o bits) para posicionar la memoria, el maximo va a ser 1111111111111111 que son 65535, y tambien es logico ya que 64Kbytes son 65536 Bits.

Destaco que hay una diferencia entre ambos numeros de 1; bueno esto pasa porque el binario arranca en 0, y el decimal arranca en 1. Ahi tenes la diferencia.

Bueno hasta aca tenemos mas o menos entendido como funcionan. Te explico mas o menos como son por dentro.

Aca hice un esquema en base a otra memoria que tambien tengo (pero que esta vacia, por eso no hable de esta). Es de National Semiconductors. 32Kbits = 4Kbytes. Con lo que explique arriba, nos da una cantidad de 12 pines para direccionar la memoria.


Basicamente es asi, al seleccionarle la memoria estas seleccionando 8 bits del matrix de celdas, pasa por un buffer de salida (que en realidad habilita las salidas o no segun el pin OutputEnable tenga un estado logico 1). Normalmente los pines de ChipEnable u OutputEnable estan negados.

Dentro de esos diagramas de bloques, hay millones de transistores, y de FETs (transistores de efecto de campo). Hay un tipo de FETs que cumplen la funcion de guardar la informacion, que tienen el nombre de FAMOS (Floating Gate Avalanche-Injection Metal Oxide Semiconductor). La carga electrica que esta almacenada en la puerta aislada o flotante determina que el bit de la celda contenga un 1 o un 0. Aunque parezca extraño, las celdas cargadas son leidas como un 0, y las que no estan son leidas como un 1. Es asi que cuando una EPROM esta limpia o virgen, todos sus valores son 255 (11111111 o FF en hexadecimal).

Ya que estas celdas estan aisladas, para poder programarlos, es necesario una tension mayor a la comun TTL o CMOS para que los electrones pasen por la puerta. Normalmente 12,75V o en algunos casos 25V.


Bueno, ya se sabe mas o menos como funcan los bichos estos.

Ahora pasamos al circuito y la logica de como hacerlo funcionar.

Bien, como en mi otro post habia comentado, el paralelo tiene 4 bits de entrada (en realidad 5, pero igual no alcanzan). Es por eso que decidi usar el selector de datos CD4512. Este es un integrado de la familia logica 4000. Su funcion es simple; tenes 3 bits de seleccion de salida, 8 bits de entrada y 1 solo de salida. Con esto logramos multiplexar 8 bits paralelos en 1 bit en modo serie (es decir, un bit atras del otro hasta llegar a los 8 bits).
Aca te dejo el esquema del diagrama de conexiones y la tabla de verdad. Con esto te das cuenta como es el asunto:



Es decir, yo al tener 3 bits, estoy seleccionando 1 bit de los 8 bits de entrada.

Con eso podemos leer los 8 bits de salida de la EPROM y enviarlo a una sola entrada de las 4 que posee el paralelo. Pero ademas, necesitamos enviar los 3 bits de direcciones. Mas adelante explico como funciona. A este integrado yo lo llamo Encoder.

Ahora ya sabemos como leer los 8 bits de la EPROM, pero necesitamos expandir los 8 bits de salida del paralelo a minimamente 15 bits (vamos a hacerlo de 16 para leer tambien la de 512).

Para eso vamos a usar un Buffer con Latch: 74HC373. Pertenece a la familia logica 74HC y "retiene 8 bits en su memoria temporalmente". Un pin del integrado, la llamada Latch es la encargada de "guardar" esta informacion. Cuando tiene el estado logico 1, todos los datos que reciba, los va a repetir en su salida. Al cambiar al estado 0, la salida se mantiene constante; es decir, "quedaron guradados" los 8 bits. Ahora, podemos joder con la entrada y la salida va a seguir siendo lo mismo, mientras que el pin de Latch siga con estado logico 0.

Aca te dejo un esquemita de como seria logicamente:


Es decir, podemos usar los 8 bits principales del puerto paralelo como bus principal entre dos integrados y manejarle los Latches por separado con uno de los 4 bits sobrantes del paralelo (los que estan negados).

Con esto podemos lograr desmultiplexar 10 bits en 16 bits (8 bits de datos principales + 2 bits de ambos Latches). Al setearle los datos a ambos integrados, el canal de datos lo podemos usar para otros fines, ya que los latches estan activados. Justamente, cuando se termina de setearle la memoria a ambos integrados, se puede usar el canal para enviar los 3 bits necesarios en el Encoder que mencione antes; y de esta manera leer los 8 bits de salida de la EPROM.

Si me seguiste hasta aca, entonces mirate este esquema de conexiones entre todos los integrados. Es necesario que lo interpretes, ya que ahi estan los pines del paralelo, los cuales luego vamos a usar en VB.



EDIT1: en el esquematico no estan las conexiones de voltaje. si van a hacer el circuito, usen 5V en comun para todo, es decir, para ambos buffers, para el encoder y para la memoria. usen una fuente aparte, no usen los 5v que entrega el paralelo y conecten ambas masas en comun (fuente externa y paralelo).


(remarco que los ultimos 4 pines de la salida del paralelo estan invertidos, ya que asi fue como lo hice en la plaqueta, ustedes lo pueden hacer como dios manda, pero tendrian que cambiar un poquito el codigo de VB)


Interpretemos un poquito el circuito. El pin 14 maneja el latch del buffer 1; el pin 17 maneja el buffer 2. El pin 13 es una entrada, por donde va a pasar el byte leido.

Basicamente esta todo explicado, solo falta un poquito de imaginacion para idear que es lo que va a pasar cuando hay un bit en cada salida.

Ahora, pasamos al code. Antes que nada declaramos solo lo que vamos a usar, 2 funciones en comun (decTObin y binTOdec) y la direccion del puerto:
Código: [Seleccionar]
Public Declare Function PortIn Lib "IO.DLL" (ByVal Port As Integer) As Byte
Public Declare Sub SetPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Public Declare Sub ClrPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)

Private Const Out_Port As Integer = &H378 '0x378 o 888
Private Const In_Port As Integer = Out_Port + 1

Function decTObin(a As Long) As String
If Int(a / 2) = 0 Then decTObin = decTObin & a Mod 2 Else: decTObin = decTObin(Int(a / 2)) & a Mod 2
End Function

Function binTOdec(a As String) As Long
If Len(a) = 1 Then binTOdec = Val(a) Else: binTOdec = Val(Left(a, 1)) * 2 ^ (Len(a) - 1) + binTOdec(Right(a, Len(a) - 1))
End Function

Ahora, una funcion muy simple para setear los 8 bits de salida de cada buffer estado logico 0; es decir, hacer un Clear.
Código: [Seleccionar]
Private Function ClearBuffer(ByVal intBuffer As Integer)

    Select Case intBuffer
        Case 1 'Buffer 1
            ClrPortBit Out_Port + 2, 1 'Desactivo Latch del buffer1
            SetPortBit Out_Port + 2, 3 'Activo Latch del buffer2
        Case 2 'Buffer 2
            SetPortBit Out_Port + 2, 1 'Activo Latch del buffer1
            ClrPortBit Out_Port + 2, 3 'Desactivo Latch del buffer2
    End Select
   
    'Limpio el Bus de 8 bits
    ClrPortBit Out_Port, 0
    ClrPortBit Out_Port, 1
    ClrPortBit Out_Port, 2
    ClrPortBit Out_Port, 3
    ClrPortBit Out_Port, 4
    ClrPortBit Out_Port, 5
    ClrPortBit Out_Port, 6
    ClrPortBit Out_Port, 7

    'DoEvents 'No hace falta
   
    'Dejo ambos Latches habilitados
    SetPortBit Out_Port + 2, 1
    SetPortBit Out_Port + 2, 3
End Function

Es un codigo muy simple, que lo unico que hace es deshabilitarle el latch al buffer seleccionado, vaciar el bus de 8 bits y habilitar de nuevo el latch.

Ahora, vamos con 3 funciones que seleccionan la memoria: SelectMemory (que selecciona el byte a leer), Send2Bytes (que envia los 16 bits a la EPROM) y LoadBuffer (se encarga de enviar los 8 bits al buffer elegido).
Código: [Seleccionar]
Private Function LoadBuffer(ByVal intBuffer As Integer, ByRef blnBits() As Boolean) 'Envio un array de booleans a un determinado buffer
    Dim intIndex As Integer

    Select Case intBuffer
        Case 1 'Buffer 1
            ClrPortBit Out_Port + 2, 1 'Desactivo Latch del buffer1
            SetPortBit Out_Port + 2, 3 'Activo Latch del buffer2
        Case 2 'Buffer 2
            SetPortBit Out_Port + 2, 1 'Activo Latch del buffer1
            ClrPortBit Out_Port + 2, 3 'Desactivo Latch del buffer2
    End Select
   
    'Recorro todo el array y seteo el bus con sus valores
    For intIndex = LBound(blnBits) To UBound(blnBits)
        If blnBits(intIndex) Then 'aca hay un 1
            SetPortBit Out_Port, intIndex 'seteo el bit intIndex (que a su vez es correlativo con el bucle) con 1
        Else
            ClrPortBit Out_Port, intIndex 'aca lo seteo con 0
        End If
    Next intIndex
   
   
    DoEvents
   
    'Dejo ambos Latches habilitados
    SetPortBit Out_Port + 2, 1
    SetPortBit Out_Port + 2, 3

    'Limpio el bus de 8 bits   
    ClrPortBit Out_Port, 0
    ClrPortBit Out_Port, 1
    ClrPortBit Out_Port, 2
    ClrPortBit Out_Port, 3
    ClrPortBit Out_Port, 4
    ClrPortBit Out_Port, 5
    ClrPortBit Out_Port, 6
    ClrPortBit Out_Port, 7
End Function

Private Function Send2Bytes(ByRef blnArr() As Boolean) 'Parte en 2 un array de Booleans para enviar 8 bits a un buffer y 8 bits al otro buffer
    Dim blnArr1(7) As Boolean
    Dim intIndex As Integer
   
    For intIndex = 0 To 7 'Paso el array tal cual desde el 0 hasta el 7 (8)
        blnArr1(intIndex) = blnArr(intIndex)
    Next intIndex
   
    Call LoadBuffer(1, blnArr1) 'Lo cargo en buffer1
   
    For intIndex = 0 To 7 'Paso el array desde el index 8 a 15 (8)
        blnArr1(intIndex) = blnArr(intIndex + 8)
    Next intIndex
   
    Call LoadBuffer(2, blnArr1) 'Lo cargo en buffer2
End Function

Private Function SelectMemory(ByVal lngPosition As Long) 'Selecciono la posicion en memoria que quiero leer

    Dim strBin As String
    Dim intIndex As Integer
    Dim blnArr(15) As Boolean
   
   
    strBin = decTObin(lngPosition) 'Paso la posicion a binario
   
    strBin = String$(16 - Len(strBin), "0") & strBin 'Hago que el len siempre sea de 16 (rellenar lo que falta con 0)
   
    'Cargo el array de 16 items a partir del string en binario
    blnArr(12) = IIf(Mid$(strBin, 1, 1) = "1", True, False) 'estos son los que estan cruzados
    blnArr(13) = IIf(Mid$(strBin, 2, 1) = "1", True, False) ' *
    blnArr(14) = IIf(Mid$(strBin, 3, 1) = "1", True, False) ' *
    blnArr(15) = IIf(Mid$(strBin, 4, 1) = "1", True, False) ' *
   
    blnArr(11) = IIf(Mid$(strBin, 5, 1) = "1", True, False)
    blnArr(10) = IIf(Mid$(strBin, 6, 1) = "1", True, False)
    blnArr(9) = IIf(Mid$(strBin, 7, 1) = "1", True, False)
    blnArr(8) = IIf(Mid$(strBin, 8, 1) = "1", True, False)
   
    blnArr(4) = IIf(Mid$(strBin, 9, 1) = "1", True, False) 'estos tambien estan cruzados
    blnArr(5) = IIf(Mid$(strBin, 10, 1) = "1", True, False) ' *
    blnArr(6) = IIf(Mid$(strBin, 11, 1) = "1", True, False) ' *
    blnArr(7) = IIf(Mid$(strBin, 12, 1) = "1", True, False) ' *
   
    blnArr(3) = IIf(Mid$(strBin, 13, 1) = "1", True, False)
    blnArr(2) = IIf(Mid$(strBin, 14, 1) = "1", True, False)
    blnArr(1) = IIf(Mid$(strBin, 15, 1) = "1", True, False)
    blnArr(0) = IIf(Mid$(strBin, 16, 1) = "1", True, False)

    Call Send2Bytes(blnArr)

End Function


Con eso ya estamos en condiciones de leer un byte. Para tal motivo, esta la siguiente funcion, que hace uso del bus de 8 bits sin molestar a los buffers, para seleccionar que bit leer de la EPROM. Esto esta en base a la tabla de verdad que esta mas arriba. Ademas, hay otra funcion que se encarga de obtener el estado logico de un pin la entrada del paralelo (que es justamente la salida del encoder).
Código: [Seleccionar]
Private Function ReadByteASCII() As String
'Direccion en 4512 | Bit
'          A             |  6
'          B             |  5
'          C             |  4

    Dim strBin As String
    Dim blnOut(7) As Boolean

    ClrPortBit Out_Port, 6
    ClrPortBit Out_Port, 5
    ClrPortBit Out_Port, 4
    strBin = IIf(ReadPin(1), "1", "0")
   
    SetPortBit Out_Port, 6
    ClrPortBit Out_Port, 5
    ClrPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    ClrPortBit Out_Port, 6
    SetPortBit Out_Port, 5
    ClrPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    SetPortBit Out_Port, 6
    SetPortBit Out_Port, 5
    ClrPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    ClrPortBit Out_Port, 6
    ClrPortBit Out_Port, 5
    SetPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    SetPortBit Out_Port, 6
    ClrPortBit Out_Port, 5
    SetPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    ClrPortBit Out_Port, 6
    SetPortBit Out_Port, 5
    SetPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")
   
    SetPortBit Out_Port, 6
    SetPortBit Out_Port, 5
    SetPortBit Out_Port, 4
    strBin = strBin & IIf(ReadPin(1), "1", "0")

    ReadByteASCII = Chr$(binTOdec(strBin))
End Function


'by TodoRobot
Private Function ReadPin(ByVal intPin As Integer) As Boolean
    Dim Lectura As Byte
    Dim Estado(3) As Byte
    Dim Estado_Str(3) As String
    Dim Bucle As Byte
   
    Lectura = PortIn(In_Port)          'leo el puerto de entrada
   
'filtro solo los bit's que necesito conocer
    Estado(0) = Lectura And &H8             '= 00001000 en Binario
    Estado(1) = Lectura And &H10            '= 00010000 en Binario
    Estado(2) = Lectura And &H20            '= 00100000 en Binario
    Estado(3) = Lectura And &H40            '= 01000000 en Binario

    ReadPin = Estado(intPin) <> 0
End Function

Ahora si, ya podemos seleccionar que parte de la memoria leer y leerla. Entonces vamos a leerla completa:
Código: [Seleccionar]
Sub Main()
    Dim lngIndex As Long

    Open App.Path & "\dump.rom" For Binary Access Write As #1
        'Nota aca: si vas a leer la memoria M27C512, el numero que tenes que poner es 65535
        '              si vas a leer la memoria M27C256, el numero que tenes que poner es 32767
        For lngIndex = 0 To 65535
            Call SelectMemory(lngIndex)
            Put #1, , ReadByteASCII
        Next lngIndex
    Close #1
End Sub

En ese caso, el programita te va a comer todo el micro. Al cabo de un rato, va a terminar y listo. En el directorio del proyecto vas a tener un archivito con el dump de la memoria.

Ya que estaba al pedo, attacheo ambos dumpeos de las EPROMs que tenia yo:
dump256.rom
dump512.rom


EDIT2: Paginas de referncia:
http://en.wikipedia.org/wiki/Parallel_port
http://perso.wanadoo.es/pictob/eprom.htm (informacion interesante)
http://www.datasheetcatalog.com/ (datasheets de los integrados)

EDIT3: Ambas memorias se pueden usar en el mismo socket, con las mismas conexiones, solamente cambien el valor de lectura.

EDIT4: Texto, imagenes, idea y circuito bajo licencia:

EDIT5: Attacheo 2 fotos de como quedo el aparato hecho en una plaqueta universal:



En fin, espero que les haya sido de utilidad. Cualquier consulta haganla aca.
« última modificación: Noviembre 15, 2009, 04:14:35 am por coco »
'-     coco
(No me cabe: Java, Python ni Pascal)
SQLite - PIC 16F y 18F - ARM STM32 - ESP32 - Linux Embebido - VB6 - Electronica - Sonido y Ambientacion

cobein

  • Moderador Global
  • Gigabyte
  • *****
  • Mensajes: 348
  • Reputación: +63/-0
  • Más Argentino que el morcipan
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #1 en: Noviembre 07, 2009, 08:52:14 pm »
=D por fin funco! la verdad muy buena onda todo esto. Se que fue un dolor de cabeza poner todo junto y depurarlo pero valio la pena, ahora gente como yo se entretiene mirando los diagramas y todo =D

coco

  • Administrador
  • Terabyte
  • *****
  • Mensajes: 548
  • Reputación: +63/-3
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #2 en: Noviembre 07, 2009, 08:56:20 pm »
=D por fin funco! la verdad muy buena onda todo esto. Se que fue un dolor de cabeza poner todo junto y depurarlo pero valio la pena, ahora gente como yo se entretiene mirando los diagramas y todo =D

hahah fue un dolor de garcha, ya estaba prendiendo el lanzallamas :D pero we, funco en el ultimo instante.

PD: se vienen mas forradas con el LPT. proximo (si es que sale) un ejemplo con un display de un estereo (que usa el protocolo I2C) o sino el programador de EPROMs.

saludos
'-     coco
(No me cabe: Java, Python ni Pascal)
SQLite - PIC 16F y 18F - ARM STM32 - ESP32 - Linux Embebido - VB6 - Electronica - Sonido y Ambientacion

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #3 en: Noviembre 08, 2009, 10:49:10 pm »
Muy buenos tutos coco , segui asi!!!

10537

  • Bytes
  • *
  • Mensajes: 10
  • Reputación: +0/-0
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #4 en: Noviembre 30, 2009, 12:38:12 pm »
Cuco Excelente Aporte, por Casualidad no tendras un esquema para la grabar y borrar Chips SIM, que vaya por el puerto USB???

coco

  • Administrador
  • Terabyte
  • *****
  • Mensajes: 548
  • Reputación: +63/-3
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #5 en: Noviembre 30, 2009, 01:18:49 pm »
Cuco Excelente Aporte, por Casualidad no tendras un esquema para la grabar y borrar Chips SIM, que vaya por el puerto USB???

nope, habria que indagar como funcionan esos bichos. ahora estoy desculando los PICs. muy bueno.

saludos
'-     coco
(No me cabe: Java, Python ni Pascal)
SQLite - PIC 16F y 18F - ARM STM32 - ESP32 - Linux Embebido - VB6 - Electronica - Sonido y Ambientacion

EL_CHANGO_v4

  • Bit
  • Mensajes: 1
  • Reputación: +0/-0
    • Ver Perfil
Re:[PP] Lector de EPROMs M27C256 y M27C512 con el paralelo y VB
« Respuesta #6 en: Enero 30, 2012, 08:15:53 pm »
Hola, muy bueno el proyecto, me gustaria poder ver las imagenes del circuito asi lo implemento, o por favor si pueden enviarme el diagrama del circuito estaria muy agradecido. Saludos.