Re: Paměťový modul
Napsal: 11 úno 2021, 18:06
Tady je ten driver pro STM32
viewtopic.php?f=59&t=2661
viewtopic.php?f=59&t=2661
České fórum pro všechny nadšence do Arduina a dalších technologií.
https://forum.hwkitchen.cz/
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;
}