cteni z DS1302

Dobry den, rozbiham komunikaci mezi ATMEGA8 a RTC DS1302 a nejak mi nasledujici procedura nevraci obsah z pameti RTC. SDI a SDO je tentyz pin, akorat SDI je vazan na PINB0 kvuli cteni a SDO na PORTB0 kvuli zapisu. RTC komunikuje prostrednictvi 3 wire komunikace. Elektronicka komunikace je OK, testoval jsem pomoci osciloskopu. Poradte prosim, kde mam chybu. Mam podezreni, ze je chyba v bitovych posunech
Dekuji

unsigned char read_DS1302 (unsigned char adresa)
{
unsigned char cc1, data;
init_DS1302();
data=0;
RESET = 1; // aktivovat linku, zahajit prenos
for (cc1=0; cc1<8; cc1++) // prenos command BYTE
{
if ((adresa&0x01) == 1) SDO = 1;
else SDO = 0;
adresa = adresa >> 1; // posunout o jeden bit vpravo
SCLK = 0;
delay_us(1);
SCLK = 1;
delay_us(1);
SCLK=0;
}

SDA_M = 0; // nastavit linku SDA jako vstup
data = 0;
for (cc1=0; cc1<8;cc1++) // prenos data
{
SCLK = 0;
delay_us(2);
data = data|(unsigned char)SDI;
LED = !(unsigned char)SDI; // abych overil na osciloskopu, ze to funguje
data>>1;
SCLK = 1;
delay_us(2);
}
SDO =0; // ukonceni komunikace
SCLK = 0;
RESET =0;
return data;
}

A co to dělá, přijímáš samé nuly ?
Co přesně znamená tento zápis: “data = data|(unsigned char)SDI;”

Používám jiný překladač i MCU, tak se ptám.

po skonceni behu funkce mam hodnotu v data = 0x01. Ten radek by mel zapsat LSB bit podle toho jestli nastakl nebo ne. Zkousel jsem to i timto zapisem a vysledek je stejny:
if (SDI == 1) {LED=1; data = data|0x01;}
else {LED=0; data = data|0x00;};
zajimave je ze na vystupu LED mam skutecne hodnoty vyctene z EEPROM, zatimco v promenne data jen 0x01

Mozno sa mi to len zda, ale nerotujes data opacnym smerom?
nemal by tam byt riadok

data<<1 ?

Takto si to co si zapisal, vyhodis prec. Ale ako pisem, moc som to nestudoval, mozno s tym robis aj nieco ine.

diky za tip, mas pravdu ta rotace by mela byt vlevo, ale presto to neslape. Neni nejaka chyba v zapisu?

Rotace musí jít vpravo, protože první bit z 1302 jde LSB.
Já to mám napsané takto:

data>>= 1; if ( rtc_io ) data |= 128;

poz. “rtc_io” je vstupní pin.

Dekuji zkusil jsem to a opet mi to nefunguje. Testuji to tak, ze vysledek odesilam na seriovy port do hyperterminalu.

  1. zapisi hodnotu do RAM RTC treba 0x6D
  2. to se pak precte funkci viz. vyse
  3. pak se to vypise na seriovy port:
    k = read_DS1302(0xC1);
    putchar(k);

Bohuzel na seriovem portu mi i pri ruzne zapsanych znacich leze tentyz znak. S posledni upravou je jiny, ale ne ten co jsem zapsal do RTC.
Uz netusim, kde mam chybu. Prosim jeste o jednu radu

Dej sem ještě jednou ten kód upravený, stačí jen tu přijímací část.

unsigned char read_DS1302 (unsigned char adresa)
{
  unsigned char cc1, data;
  init_DS1302();
  data=0;
  RESET = 1;                    // aktivovat linku, zahajit prenos
  for (cc1=0; cc1<8; cc1++)     // prenos command BYTE
     {
       if ((adresa&0x01) == 1) SDO = 1;
         else SDO = 0;
       adresa = adresa >> 1;    // posunout o jeden bit vpravo
       SCLK = 0;
       delay_us(1);
       SCLK = 1;
       delay_us(1);
       SCLK=0;
     }


  SDA_M = 0;                    // nastavit linku SDA jako vstup
  data = 0;
  for (cc1=0; cc1<8;cc1++)      // prenos data
     {
       SCLK = 0;
       delay_us(2);
       if (SDI) data |=128;


//       data = data|(unsigned char)SDI;
//       LED = !(unsigned char)SDI;
       data>>= 1; 
//       1<<data;
//       data>>1;
       SCLK = 1;
       delay_us(2); 
     }
  SDO =0;                       // ukonceni komunikace
  SCLK = 0;
  RESET =0;
  return data;
}

Tu rotaci dej před zápis do “data”.

[code] for (cc1=0; cc1<8;cc1++) // prenos data
{
SCLK = 0;
delay_us(2);

   data>>= 1;
   if (SDI) data |=128; 


   SCLK = 1; 
   delay_us(2); 
 } 

[/code]