Stránka 6 z 6

Re: Paměťový modul

Napsal: 11 úno 2021, 18:06
od ondraN
Tady je ten driver pro STM32
viewtopic.php?f=59&t=2661

Re: Paměťový modul

Napsal: 11 úno 2021, 20:25
od AstroMiK
Díky za kód.
Na první pohled mi to nic moc neříká, ale až bude klid, tak se v tom zkusím zorientovat.


Jinak k těm pull-up odporům:
Používám převodník, který má obě strany přitažené k napájení přes 10k, tak už mi připadalo zbytečné lepit tam něco dalšího.
V příloze je fotka převodníku a té EERAM paměti.
shifter.jpg

Re: Paměťový modul

Napsal: 11 úno 2021, 20:41
od ondraN
Tak to by mělo být asi OK. Ona je totiž u obvodu i specifikovaná maximální délka náběžné a sestupné hrany CLK signálu na 100ns. Těžko ale říct, jak to ten převodník natahuje. Bohužel teď nemám žádný čas na vyzkoušení.

Re: Paměťový modul

Napsal: 12 úno 2021, 18:13
od AstroMiK
Tak na té desce s procesorem STM32F103 to bez převodníku úrovní funguje bez problémů.

Přikládám testovací kód bez knihoven s několika podprogramy pro zápis i čtení v různých režimech:
- jeden bajt - čtení i zápis
- dvojbajt (unsigned int) - čtení i zápis
- pole bajtů (nepřerušovaný rychlý zápis) - jen zápis

Kód: Vybrat vše



// Testovani EERAM pameti typ 48L512 (komunikace SPI, kapacita 64k x 8 bitu) na desce BluePill (STM32F103)
//  Bez SPI knihovny s libovolnym prirazenim pinu 
//
// Testovani se provadi zadavanim prikazu pres seriovou linku:
//  W       ... zapise do EERAM ruzne hodnoty, ruznych typu promennych (byte, unsigned int, pole bajtu)
//  R nnnnn ... precte jednobajtovou hodnotu z adresy nnnnn
//  I nnnnn ... precte dvojbajtovou hodnotu z adresy nnnnn a nnnnn+1
//  S       ... vypise aktualni stav Status registru
//
//====================================================================================


//  prirazeni pinu - je mozne podle potreby libovolne menit 
#define pin_CS       PA4
#define pin_MOSI     PA7
#define pin_MISO     PA6
#define pin_SCK      PA5


//====================================================================================
void setup(void)
  {
    Serial.begin(9600);
    
    pinMode(pin_SCK,OUTPUT);
    pinMode(pin_MOSI,OUTPUT);
    pinMode(pin_MISO,INPUT);
    pinMode(pin_CS,OUTPUT);
    digitalWrite(pin_CS,HIGH);
    digitalWrite(pin_MOSI,LOW);
  }


//====================================================================================
void loop(void)
  {
    if (Serial.available())
      {
        char znak = Serial.read();
        delay(10);

        //  priklad:  "W" zapise ruzne typy hodnot do pameti
        if (znak == 'W')  // zais nejakych hodnot do RAM
          {

            byte pole_1[] = {10,20,30,40,50,60,70,80};       // bajtove pole, ktere se zapise od adresy 100
            byte pole_2[] = {11,22,33,44,55,66,77,88};       // jine bajtove pole, ktere se zapise od adresy 200
            
            EERAM_write(100, 7, pole_1);                     // prikaz pro zapis prvnich 7 polozek z pole_1 na adresu 100
            EERAM_write(200, 5, pole_2);                     // prikaz pro zapis prvnich 5 polozek z pole_2 na adresu 200
        
            byte x = 99;
            EERAM_write(300,x);                              // zapise jeden bajt na adresu 300
        
            unsigned int y = 12345;
            EERAM_write(400,y);                              // kdyz je hodnota v rozsahu unsigned int, zapise se do pameti jako dva bajty

            Serial.println("ZAPSANO");
          }


        //  priklad:  "R 100" vrati hodnotu z adresy 100
        if (znak == 'R')  // cteni hodnot z RAM
          {
            unsigned int adresa = Serial.parseInt();
            Serial.print ("Adresa: ");
            Serial.print (adresa);

            Serial.print ("   data: ");
            Serial.println (EERAM_read(adresa));      
          }      

        //  priklad:  "I 400" vrati unsigned int hodnotu z adresy 400 a 401
        if (znak == 'I')  // cteni dvojbajtovych hodnot z RAM
          {
            unsigned int adresaI = Serial.parseInt();
            Serial.print ("Adresa: ");
            Serial.print (adresaI);

            Serial.print ("   data: ");
            Serial.println (EERAM_read_int(adresaI));      
          }      


        //  priklad:  "S" vrati binarni hodnotu Status registru
        if (znak == 'S')  // Status registr
          {
            Serial.print("Status registr: 0b");
            Serial.println(EERAM_RDSR(),BIN);

          }

        while (Serial.available()) Serial.read();

      }  
  
  }
//====================================================================================




//====================================================================================
//            P O D P R O G R A M Y 
//--------------------------------------------
// precte aktualni hodnotu Status registru
byte EERAM_RDSR(void)
  {
    digitalWrite(pin_CS,LOW);
    posli_data(5);                          // zadost o RDSR
    byte status_reg = posli_data(0);        // obsah registru
    digitalWrite(pin_CS,HIGH);  
    return status_reg;
  }


//--------------------------------------------
// zapise jeden datovy bajt na vybranou adresu
void EERAM_write(unsigned int EE_adresa, byte EE_data)
  {
    digitalWrite(pin_CS,LOW);
    posli_data(6);                          // WREN
    digitalWrite(pin_CS,HIGH);  
    delayMicroseconds(1);
    digitalWrite(pin_CS,LOW);
    posli_data(2);                          // WRITE
    posli_data(EE_adresa >> 8);             // MSB adresa
    posli_data(EE_adresa & 0xFF);           // LSB adresa
    posli_data(EE_data);                    // data (1 bajt)
    digitalWrite(pin_CS,HIGH);  
  }


//--------------------------------------------
// zapise do pameti prvnich nekolik polozek ze zvoleneho pole
void EERAM_write(unsigned int EE_adresa, unsigned int pocet , byte EE_pole[])
  {
    digitalWrite(pin_CS,LOW);
    posli_data(6);                          // WREN
    digitalWrite(pin_CS,HIGH);  
    delayMicroseconds(1);
    digitalWrite(pin_CS,LOW);
    posli_data(2);                          // WRITE   
    posli_data(EE_adresa >> 8);             // MSB 1. adresove bunky
    posli_data(EE_adresa & 0xFF);           // LSB 1. pametove bunky
    for (unsigned i = 0; i < pocet ; i++)
      {
        posli_data(EE_pole[i]);             // postupne jeden datovy bajt za druhym
      }
    digitalWrite(pin_CS,HIGH);  
  }


//--------------------------------------------
// zapis dvoubajtoveho cisla do zvolene pameti v EERAM (nejdriv se ulozi MSB a na nasledujici adresu LSB = "Big-endian")
void EERAM_write(unsigned int EE_adresa, unsigned int EE_data)
  {
    digitalWrite(pin_CS,LOW);
    posli_data(6);                          // WREN
    digitalWrite(pin_CS,HIGH);  
    delayMicroseconds(1);
    digitalWrite(pin_CS,LOW);
    posli_data(2);                          // WRITE
    posli_data(EE_adresa >> 8);             // MSB 1. adresove bunky
    posli_data(EE_adresa & 0xFF);           // LSB 1. adresove bunky
    posli_data(EE_data >> 8);               // horni pulka integeru
    posli_data(EE_data & 0xFF);             // spodni pulka integeru
    digitalWrite(pin_CS,HIGH);  
  }


//--------------------------------------------
// precteni dvou bajtu z adresy v EERAM a jejich slozeni do unsigned int cisla (0 az 65535)
unsigned int EERAM_read_int(unsigned int EE_adresa)
  {
    digitalWrite(pin_CS,LOW);
    posli_data(3);                          // READ
    posli_data(EE_adresa >> 8);             // MSB z adresy
    posli_data(EE_adresa & 0xFF);           // LSB z adresy
    unsigned int precteno = posli_data(0);  // horni pulka datoveho integeru
    precteno = precteno << 8;
    precteno = precteno + posli_data(0);    // spodni pulka datoveho integeru
    digitalWrite(pin_CS,HIGH);  
    return precteno;
  }


//--------------------------------------------
// Precteni jednoho bajtu z adresy v EERAM
byte EERAM_read(unsigned int EE_adresa)
  {
    digitalWrite(pin_CS,LOW);
    posli_data(3);                          // READ
    posli_data(EE_adresa >> 8);             // MSB z adresy
    posli_data(EE_adresa & 0xFF);           // LSB z adresy
    byte precteno = posli_data(0);          // jeden precteny bajt
    digitalWrite(pin_CS,HIGH);  
    return precteno;
  }


//--------------------------------------------
// Odeslani jednoho bajtu za soucasneho tikani hodinami.
// Zaroven pri hodinach v HIGH testuje stav pinu MISO a sklada z nej vystupni bajt
byte posli_data(byte vstupniBajt)
  {
    byte vystup = 0;
    for (byte i=8; i > 0 ; i--)                                     // prochazi se od nejvyssiho bitu k nejnizsimu
      {
        boolean databit = bitRead(vstupniBajt,i-1);
       
        if (databit == false)     digitalWrite(pin_MOSI,LOW);       // MOSI se nastavi podle aktualniho databitu
        else                      digitalWrite(pin_MOSI,HIGH);
        
        digitalWrite(pin_SCK,HIGH);                                 // jedno kladne tiknuti hodinami
        if(digitalRead(pin_MISO) == HIGH)       bitSet(vystup,i-1); // pri SCK v HIGH se testuje stav pinu MISO
        digitalWrite(pin_SCK,LOW);                                  // navrat hodin do LOW
      }
    return vystup;
  }
  


Re: Paměťový modul

Napsal: 13 úno 2021, 07:31
od ondraN
Pro 5V obvody by to chtělo asi nějaký takovýhle převodník
https://www.ti.com/logic-circuit/voltag ... l#p941=SPI

Re: Paměťový modul

Napsal: 13 úno 2021, 08:47
od AstroMiK
Zkusil jsem mezi paměť a Arduino NANO zapojit převodník TXB0108:
https://www.ti.com/product/TXB0108

Opět bez úspěchu.
Tentokrát paměť vůbec neodpovídá - výstup paměti (MISO) je trvale ve vysoké impedanci, takže výsledkem je vždycky číslo 255.
Vstupní signály na paměti jsou podle analyzátoru v pořádku.
To už se mi stalo jednou hned na začátku pokusů s Arduinem, když jsem zkusil použít SPI knihovnu.

Protáhnul jsem tedy všechny signály nadměrnými pauzami, ale pořád nic.
Napájení paměti je v pořádku.


Už s tím končím.
Můj osobní závěr tedy je, že se ta paměť nehodí pro použití s 5V Arduinem.

Re: Paměťový modul

Napsal: 13 úno 2021, 12:24
od ondraN
Možná už na to pár lidí narazilo, proto nejsou ani žádné knihovny. Až budu mít nějakou volnou chvíli, tak si na to musím posvítit, kde je zakopaný pes.