Fórum témák

» Több friss téma
Cikkek » 28C16 EEPROM Programozó PIC16F887 mikrokontrollerrel
28C16 EEPROM Programozó PIC16F887 mikrokontrollerrel
Szerző: tomcii, idő: Kedd, 20:02, Olvasva: 115, Oldal olvasási idő: kb. 7 perc
Lapozás: OK   4 / 6

 A firmware: Kissé terjengős egy oldal lett, de szerettem volna mindent bemutatni a firmware-val kapcsolatosan.

A programozó lelke egy PIC16F887 mikrokontroller, amely közvetlenül kezeli a 28C16 EEPROM teljes párhuzamos buszát. A firmware mikroC PRO for PIC környezetben készült, 16 MHz-es külső kvarccal, 9600 baud sebességű UART kommunikációval.

A firmware fő feladatai:

  • EEPROM címvonalak kezelése
  • adatbusz irányának váltása
  • CE, OE, WE vezérlőjelek előállítása
  • byte olvasás
  • byte írás
  • teljes memória törlés
  • visszaellenőrzés
  • soros parancsok feldolgozása
  • státusz LED-ek vezérlése

Alap paraméterek

A 28C16 memória mérete 2048 byte, ezért a firmware-ben ez fixen definiálva van:

#define EEPROM_SIZE 2048

#define RXBUF_SZ    48

Az EEPROM_SIZE határozza meg a kezelhető címtartományt. Mivel a 28C16 memória 2K x 8 szervezésű, az érvényes címek:

0x0000 - 0x07FF

A soros parancsok fogadására egy 48 byte-os puffer szolgál. Ez bőven elegendő az egyszerű parancsformátumokhoz, például:

R 0x0000

W 0x0000 0xAA

D 0x0000 64

Valós PCB lábkiosztás

A firmware már a kész NYÁK lábkiosztásához igazodik. Ez azért fontos, mert nem elméleti, breadboardos verzióról van szó, hanem a ténylegesen legyártott panel portkiosztásáról.

D0-D5

RA0-RA5

D6-D7

RB0-RB1

A0-A7

RD0-RD7
A8-A10

RE0-RE2

/WE RB2
/OE RB4
/CE RB5

Státusz LED-ek:

WRITE    -> RC0
READ     -> RC1
ERROR    -> RC2
ABORT    -> RC3
CMD_PROC -> RC4
STBY     -> RC5

Ez a kiosztás jól illeszkedik a 28C16 működéséhez, mert a címbusz alsó 8 bitje egy teljes porton, a PORTD-n jelenik meg, így az alsó címbyte nagyon egyszerűen kiírható.

Inicializálás:

A gpio_init() függvény készíti elő a mikrokontrollert.
Első lépésként minden analóg funkció le van tiltva:

ANSEL = 0x00;
ANSELH = 0x00;
ADCON0.ADON = 0;

Ez nagyon fontos PIC16F887 esetén, mert több láb alapból analóg bemenetként is működhet. Ha ezeket nem tiltjuk le, akkor a digitális portkezelés furcsa hibákat okozhat.

A komparátorok is letiltásra kerülnek:
C1ON_bit = 0;
C2ON_bit = 0;

Ezután a portok nullázódnak:
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

A címbusz kimenet lesz:
ADDR_LO_TRIS = 0x00;
ADDR_HI_TRIS = 0x00;

A vezérlőjelek szintén kimenetek:
WE_TRIS = 0;
OE_TRIS = 0;
CE_TRIS = 0;

Az adatbusz viszont alaphelyzetben bemenet:
data_dir_input();

Ez biztonsági szempontból fontos. Bekapcsoláskor nem jó, ha a PIC és az EEPROM egyszerre próbálja hajtani az adatbuszt.


EEPROM alapállapot
Az eeprom_idle() függvény biztonságos nyugalmi állapotba teszi a memóriát:
CE_LAT = 1;
OE_LAT = 1;
WE_LAT = 1;

Mivel ezek aktív alacsony jelek, az 1-es állapot azt jelenti, hogy:
/CE inaktív
/OE inaktív
/WE inaktív

Vagyis a memória nincs kiválasztva, nem olvasunk, és nem írunk.
Ezután az adatbusz felszabadul:
TRISA0_bit = 1;
...
TRISB1_bit = 1;
Így a PIC nem hajtja az adatvonalakat, elkerülhető a buszütközés.

Adatbusz irányváltás
A 28C16 adatbusza kétirányú. Olvasáskor az EEPROM hajtja az adatvonalakat, íráskor pedig a PIC.
Ezért van két külön függvény:
void data_dir_input(void)
void data_dir_output(void)

Olvasás előtt mindig bemenetre kell állítani a PIC adatbusz lábait:
data_dir_input();
Írás pedig a kimenetre: data_dir_output();

Ez a firmware egyik legfontosabb része, mert ha rossz sorrendben történne, akkor a PIC és az EEPROM egyszerre hajthatná ugyanazt a vonalat.


Adat kiírása a buszra
A data_put() függvény egy 8 bites értéket rak ki az adatbuszra.
RA0_bit = (v >> 0) & 1;
RA1_bit = (v >> 1) & 1;
...
RB1_bit = (v >> 7) & 1;

Mivel az adatbusz nem egyetlen teljes porton van, hanem részben PORTA-n, részben PORTB-n, ezért bitenként történik a kiírás.
A kiosztás:
bit 0 -> RA0
bit 1 -> RA1
bit 2 -> RA2
bit 3 -> RA3
bit 4 -> RA4
bit 5 -> RA5
bit 6 -> RB0
bit 7 -> RB1

Adat beolvasása a buszról:
A data_get() ennek a fordítottja. Beolvassa a portlábak állapotát, majd egy 8 bites értékké rakja össze:

if (RA0_bit) v |= 0x01;
if (RA1_bit) v |= 0x02;
...
if (RB1_bit) v |= 0x80;

Ez azért jó megoldás, mert a firmware szintjén az EEPROM adatbyte-ja már egységes unsigned char típusként kezelhető, függetlenül attól, hogy fizikailag több porton van szétszórva.


Cím beállítása:
A addr_set() függvény állítja be a kiválasztott EEPROM címet.
Az alsó 8 címvonal egyben kerül ki a PORTD-re:

ADDR_LO_PORT = (unsigned char)(a & 0xFF);
Ez adja:
A0-A7

A felső három címvonal a PORTE alsó három bitjére kerül:
hi = ADDR_HI_PORT & 0xF8;
hi |= (unsigned char)((a >> 8) & 0x07);
ADDR_HI_PORT = hi;
Ez adja:
A8-A10
A 0xF8 maszkolás azért szerepel benne, hogy a PORTE felső bitjei ne változzanak meg feleslegesen. A 28C16-hoz összesen 11 címvonal kell, ezért a firmware csak az alsó 11 bitet használja.
Byte olvasás
Az EEPROM olvasását az eep_read_byte() végzi.
A folyamat:
data_dir_input();
addr_set(a);

WE_LAT = 1;
CE_LAT = 0;
OE_LAT = 0;
delay_us_safe(2);
d = data_get();
OE_LAT = 1;
CE_LAT = 1;

Lépésenként:
    1.    Az adatbusz bemenetre áll.
    2.    A PIC beállítja a kívánt címet.
    3.    A WE inaktív marad.
    4.    A CE aktív lesz, vagyis kiválasztjuk az EEPROM-ot.
    5.    Az OE aktív lesz, vagyis az EEPROM meghajtja az adatbuszt.
    6.    Rövid várakozás után a PIC beolvassa az adatot.
    7.    Az OE és CE újra inaktív lesz.
A 2 µs várakozás bőven elegendő az ilyen régi párhuzamos EEPROM-ok elérési idejéhez.


Byte írás:
Az írást az eep_write_byte() függvény végzi. Ez már összetettebb, mert az EEPROM-nak idő kell a cella tényleges programozásához.
A folyamat elején bekapcsol a WRITE LED:
LED_WRITE_LAT = LED_ON_LEVEL;
Ezután a firmware biztonságos állapotba teszi a vezérlőjeleket:
OE_LAT = 1;
WE_LAT = 1;
CE_LAT = 1;

Majd beállítja a címet és az adatot:
addr_set(a);
data_dir_output();
data_put(v);

Ezután kiválasztja az EEPROM-ot:
CE_LAT = 0;

Majd létrehozza az íróimpulzust:
WE_LAT = 0;
delay_us_safe(5);
WE_LAT = 1;


Tehát a WE rövid időre alacsony szintre kerül. Ez indítja el az adott byte programozását.


Ezután:
CE_LAT = 1;
data_dir_input();
A memória ki van választva, az adatbusz pedig visszaáll bemenetre.

Írás utáni polling
A 28C16 nem azonnal írja be fizikailag az adatot. A cellaprogramozás néhány milliszekundumot igényelhet.

Ezért a firmware nem vakon vár fix ideig, hanem visszaolvassa az adott címet:
for (t = 0; t < 25; t++) {
    d = eep_read_byte(a);

    if (d == v) {
        LED_WRITE_LAT = LED_OFF_LEVEL;
        return 1;
    }

    delay_ms_safe(1);
}
Ez maximum 25 ms-ig próbálkozik. Ha a visszaolvasott érték megegyezik az írt értékkel, akkor az írás sikeres.

Ha 25 ms alatt sem egyezik, akkor timeout történik:
return 0;

Ez nagyon jó megoldás, mert a firmware nem csak “reméli”, hogy sikerült az írás, hanem ténylegesen visszaellenőrzi.

Soros kommunikáció:
A firmware UART-on kommunikál a PC-s programmal:
UART1_Init(9600);
A bekapcsolási üzenet:
EEPROM-PGM HW READY V2
A fő ciklus folyamatosan figyeli az UART-ot:
while (1) {
    if (UART1_Data_Ready()) {
        char c = UART1_Read();
        ...
    }
}
A karaktereket sorvége karakterig gyűjti:
'\r' vagy '\n'
Ha beérkezett egy teljes sor, akkor meghívja:
process_line(rxbuf);

A firmware csak nyomtatható ASCII karaktereket fogad el, és védi magát a túl hosszú parancsoktól is:
ERR LONG

Parancsfeldolgozás


A process_line() dolgozza fel a PC felől érkező parancsokat.
A támogatott parancsok:
P              ping
S              státusz
R cím          egy byte olvasása
W cím adat     egy byte írása
D cím hossz    blokk olvasása
E              teljes törlés
O              LED-ek ki
L              LED-ek be
T              LED teszt

A parancsfeldolgozás elején bekapcsol a CMD_PROC LED, a készenléti LED pedig kikapcsol:
command_begin();

A végén minden művelet után biztonságos állapotba kerül az EEPROM busz:
eeprom_idle();
command_end();

Ez azért fontos, mert még hibás parancs után sem marad aktív írási,22 vagy olvasási állapotban a memória.
Ping parancs
A P parancs egyszerű kapcsolatellenőrzés:
Válasz:
PING: OK EEPROM-PGM HW V2 tomcii

Ez a PC-s alkalmazásnak arra jó, hogy ellenőrizze, valóban a programozó van-e a kiválasztott COM porton.
Státusz parancs
Az S parancs visszaadja az alapvető firmware információkat:
Válasz:
STATUS:OK EEPROM-HW V2 tomcii SIZE=2048 BAUD=9600

Ebben szerepel:
hardver/firmware verzió
memóriaméret
baudrate

Ez később nagyon hasznos lehet, ha több hardververzió vagy firmware-verzió készül.
Egy byte olvasása
Az R parancs egyetlen byte-ot olvas ki:
R 0x000
Válasz:
D 0000 AA

A válasz formátuma:
D (Dump)
Ha a cím kívül esik az érvényes tartományon, akkor:
ERR ADDR

Egy byte írása
A W parancs egyetlen byte-ot ír:
W 0x0000 0xAA
Sikeres írás esetén a válasz?ó:
OK 0000 AA

A firmware írás után visszaolvassa az adott címet, és a ténylegesen olvasott értéket küldi vissza.

Ha az írás nem fejeződik be időben:
ERR TIMEOUT

Ez jelzi, hogy a polling nem kapta vissza a kívánt értéket.


Blokk olvasás
A D parancs egyszerre több byte-ot olvas ki:
D 0x0000 64

A firmware maximum 64 byte-os blokkot enged egyszerre:
if (length == 0 || length > 64) {
    uart_puts("ERR LEN\r\n");
}

Ez azért praktikus, mert a válasz nem lesz túl hosszú, a soros kommunikáció pedig stabil marad.

A válasz formátuma:
B 0000 40 AA BB CC ...

Itt:
B      = blokk válasz
0000   = kezdőcím
40     = hossz hexában
utána  = adatbyte-ok hex formában

A PC-s program ebből kényelmesen fel tudja építeni a teljes 2048 byte-os dumpot.


Teljes törlés
Az E parancs végigírja a teljes EEPROM-ot 0xFF értékkel:
E

A firmware végigmegy az összes címen:
for (i = 0; i < EEPROM_SIZE; i++) {
    if (!eep_write_byte(i, 0xFF)) {
        eraseOk = 0;
        break;
    }
}

Minden 256 byte után progress üzenetet küld:
P 0100
P 0200
P 0300
...
Hogy valamiféle visszajelzést lehetővé tegyen a törlés is a PC-s applikációban.

Sikeres törlés esetén:
OK ERASE

Ez nagyon hasznos, mert nem csak annyit tudunk, hogy sikertelen volt a törlés, hanem azt is, melyik címnél akadt el.

LED vezérlő parancsok

A firmware tartalmaz egyszerű LED tesztfunkciókat is.

LED-ek kikapcsolása:
D

Válasz:
OK LEDS OFF

LED-ek bekapcsolása:
L
Válasz:
OK LEDS ON

LED teszt:
T

Ilyenkor a firmware egymás után felvillantja a státusz LED-eket:
WRITE
READ
ERROR
ABORT
CMD
STBY

Válasz:
OK LED TEST

Ez a funkció különösen jól jön beültetés után, mert gyorsan ellenőrizhető, hogy minden LED jó irányban van-e beforrasztva.

Számformátumok kezelése
A firmware rugalmas számbevitelt enged.

Elfogad például:
R 0
R 123
R 0x000A
R 000A
W 0x0100 0xAA

A parse_number() függvény felismeri, ha a szám 0x előtaggal hexadecimális, de akkor is hexának kezeli, ha A-F karaktert talál benne.
Ez kényelmesebbé teszi a kézi terminálos használatot is.

Hibakezelés

A firmware több alapvető hibát is kezel:
Ismeretlen parancs:
ERR CMD

Érvénytelen cím:
ERR ADDR

Túl hosszú parancssor:
ERR LONG

Írás időtúllépés:
ERR TIMEOUT

Hiba esetén az ERROR LED röviden felvillan:
led_error_pulse();

Ez egyszerű, de nagyon hasznos vizuális visszajelzés.

Firmware működésének összefoglalása

A firmware alapvetően egy egyszerű, soros parancsértelmezőből, és egy alacsony szintű EEPROM buszkezelő rétegből áll.

A felépítés logikusan szétválasztható:

UART parancsok
      ↓
process_line()
      ↓
EEPROM műveletek
      ↓
cím-, adat-, és vezérlőbusz kezelése
      ↓
28C16 memória

A megoldás előnye, hogy a PC-s programnak nem kell ismernie a 28C16 időzítéseit. A számítógép csak egyszerű parancsokat küld, minden hardverközeli feladatot a PIC végez el.
Ezáltal a programozó használható akár saját Windows alkalmazással, akár egyszerű soros terminálból is.

Miért jó ez a megoldás?
A firmware nem próbál univerzális EEPROM programozó lenni. Pont az a célja, hogy a 28C16 családot egyszerűen, stabilan és átláthatóan kezelje.

A közvetlen buszvezérlés miatt nagyon jól tanulmányozható:

    •    hogyan működik egy párhuzamos EEPROM
    •    hogyan kell adatbuszt irányt váltani
    •    hogyan működik az aktív alacsony vezérlés
    •    hogyan történik az írási impulzus
    •    hogyan lehet visszaellenőrizni a programozást

Ezért a firmware nem csak a kész eszköz működtetésére alkalmas, hanem oktatási szempontból is értékes része a projektnek. A következőben ismertetem az általam VS-ben készített applikációt.


A cikk még nem ért véget, lapozz!
Következő: »»   4 / 6
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem