Pages: [1]   Go Down
Author Topic: [Résolu] Comment exploiter la mémoire du DS1307?  (Read 592 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello à tous,

J'attends mon DS1307 et j'aimerais savoir si vous connaissez une class qui permet d'exploiter la RAM disponible de ce CI.
56 octets, ce qui donne la possibilité de stocker 11 dates sauvegardées grâce à la pile bouton.

Je pensais à un champ de bits du genre:
Code:
struct {
unsigned int day : 5; // 0 -> 30
unsigned int month : 4; // 0 -> 11
unsigned int year : 6; // 0 -> 64 (2000 -> 2064)
unsigned int hour : 5; // 0 -> 23
unsigned int minute : 6; // 0 -> 59
unsigned int second : 6; // 0 -> 59
unsigned int dayofWeek : 3; // 0 -> 6
unsigned int daysinMonth : 2; // 0 -> 3 (28+0 -> 28+3)
unsigned int bisexYear : 1; }; // 0 -> 1 (false or true)

J'ai cherché mais je n'ai rien trouvé, j'essaie de faire qlqs chose mais j'ai qlqs difficultés à mettre ça en place.

Merci
« Last Edit: February 15, 2012, 03:08:17 pm by moribond » Logged

Bretagne
Offline Offline
Edison Member
*
Karma: 11
Posts: 1299
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

Tu ne dois pas être loin, je pense, mais ce type de déclaration [unsigned int varName : n;], je connais pas. Un unsigned int, c'est un 16 bits, j'ai bien peur que ta structure ne soit quand même compilée sur 18 octets...

dans l'idée, il faudrait une fonction qui code une structure "date" en un tableau de 5 byte, non? avec des << et des >>, ça serait très rapide

Code:
struct {
byte day; // 0 -> 30
byte month; // 0 -> 11
byte year; // 0 -> 63 (2000 -> 2063) codé sur 6 bits...
byte hour; // 0 -> 23
byte minute; // 0 -> 59
byte second; // 0 -> 59
byte dayofWeek; // 0 -> 6
byte daysinMonth; // 0 -> 3 (28+0 -> 28+3)
byte bisexYear; // 0 -> 1 (false or true)
        byte h24; // 0 -> 1 (12h or 24h)
        byte bonusBit; // 0 -> 1 (car il reste de la place...) pourquoi pas heure hiver / été?
byte memBytes[5]; // les 5 octets codés
 };

void compileDate(dateStruct *dat_var){  // compile la date sur 5 octets
  with (dat_var){
    day &= 0x1F;
    month &= 0x0F;
    year &= 0x3F;
    hour &= 0x1F;
    minute &= 0x3F;
    second &= 0x3F;
    dayofWeek &= 0x07;
    daysinMonth &= 0x03;
    bisexYear &= 0x01;
    h24 &= 0x01;
    bonusBit &= 0x01;
    memBytes[0] = day + (month << 5);
    memBytes[1] = (month >>3) + (year << 1) + (hour << 7);
    memBytes[2] = (hour >> 1) + (minute << 4);
    memBytes[3] = (minute >> 4) + (second << 2);
    memBytes[4] = dayofWeek + (daysinMonth << 3) + (bisexYear << 5) + (h24 << 6) + (bonusBit << 7);
  }
}
Bon, je n'ai pas encore bien bûché les accès par pointeurs, donc ça doit pas bien compiler, mais c'est l'idée. Reste à faire la fonction inverse (qui passe de memBytes[] vers les variables heures, minutes etc etc). J'ai du coup rajouté au passage deux boolean, puis qu'il nous restait deux bits sur les 5 octets...
« Last Edit: February 15, 2012, 02:07:58 am by Super_Cinci » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

La structure de Moribond tient sur 6 octets (3 unsigned int). Le principe même du champ de bits (ou bit field) est de n'utiliser que quelques bits d'un ou plusieurs octets pour faire tenir un champ.
Par exemple, le champ day va prendre les 5 premiers bits de l'entier non signé 16 bits, le champ month les 5 suivants et ainsi de suite...
Logged


Made in Belgium
Offline Offline
God Member
*****
Karma: 0
Posts: 756
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

En jouant avec les opérateur bit à bit ça devrait être assez simple .
Exemple vite fais pour enregistré une valeur à la fois, juste changer le jours par exemple, etc. (avec l'année bissextile ça fait pile 16 bit)
Code:
unsigned int date;

date &= 0xFFE0; (1111 1111 1110 0000)
date += month;

date &= 0xFE1F; (1111 1110 0001 1111)
date += (day << 5);

date &= 0x81FF; (1000 0001 1111 1111)
date += (year << 9);

date &= 0x81FF; (0111 1111 1111 1111)
date += (bisexYear << 15);
.
.
.
date &= 0x81E0; (1000 0001 1110 0000)
date += (month+(year << 9)); // juste le mois et l'année

date =  month+(day << 5)+(year << 9)+(bisexYear << 15); //tout en 1 coup

pour les deux premier octet ça sera simple, pour les 54 autres  smiley-confuse.
Peut être utilisé 5 octet (2 variable int + 1byte) par structure comme le propose Super_Cinci donc 40 bit (2 de perdu ou autre chose à ajouter, retenir  ?) comme tu en as besoin de 38.

day+month+year+bisexYear : 2 octet (int dont 16bit occupé)
hour + minute + dayofWeek  : 2 octet (int dont 14 bit occupé)
second + daysinMonth : 1 octet (byte dont 8bit occupé)

second ne serait pas dans le deuxième int pour facilité le travail comme l'ensemble de l'heure fais 17bit, mais bon il serait au début du 3 ième (byte) et entier.
La structure sur laque tu travaillerais.
Code:
struct date
{
uint16_t champ1;
uint16_t champ2;
uint8_t champ3;
};

date dates[11];
« Last Edit: February 15, 2012, 12:21:32 pm by osaka » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C'est bien un problème syntaxe sur lequel je butte. Je n'ai jamais eu l'occasion de jouer avec des bits.
Finalement je pense pouvoir zapper qlqs infos et une structure sur 4 octets devrait faire l'affaire. A stocker dans 2 int donc.

5 pour le jour
5 pour l'année
6 pour les minutes

4 pour le mois
5 pour les heures
6 pour les secondes

Je vais potasser les opérations avec les bits et ce que tu as posté Super_Cinci.
Je n'ai tjrs pas mon DS donc impossible de tester pour le moment. 23 jours qu'il est commandé:(

« Last Edit: February 15, 2012, 12:32:20 pm by moribond » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tu avais raison Osaka, plutôt simple.
J'ai stocké ça dans un long. Ce qui devrait me permettre de stocker 14 dates dans le DS.

Si ça peut servir...
Code:
struct {
byte jour;
byte mois;
byte annee;
byte heure;
byte minute;
byte seconde; };

unsigned long DT2mem(byte jour, byte mois, byte annee, byte heure, byte minute, byte seconde) {
return(((long) annee << 27) + ((long) mois << 23) + ((long) jour << 18) + ((long) heure << 13) +
((long) minute << 7) + ((long) seconde << 1)); }

void mem2DT(unsigned long v, Datime *r) {
r->annee= (byte) (v >> 27);
r->mois= (byte) ((v << 5) >> 28);
r->jour= (byte) ((v << 9) >> 27);
r->heure= (byte) ((v << 14) >> 27);
r->minute= (byte) ((v << 19) >> 26);
r->seconde= (byte) ((v << 25) >> 26); }
« Last Edit: February 15, 2012, 03:52:21 pm by moribond » Logged

Pages: [1]   Go Up
Jump to: