explication ligne prog
|
|
salut!
j'aurai aimé que quelqu'un me décrive une ligne de prog (qui sert pour écrire vers une mémoire en I2c...)
voila la ligne:
i2c_write((0xa0|(byte)(address>>7))&0xfe);
j'auari voulu savoir a quoi correspondent toutes ces valeurs...
merci beaucoup!!
nico
Numéro de l'article: 96055
| De: nico
| Date: 2004-05-10 16:11:07
|
RE: explication ligne prog
en fait mon prog a pour but de lire une tension qui arrive sur RA0, de la stocker dans une mémoire et de la relire aussitot aprés...
le prog arrive bien a trouver la bonne tension et l'envoyer vers la mémoire mais ensuite lorsqu'il li la mémoire, c'est plus la meme donnée et je sais pas trop pourquoi???
voila le prog
:
#include<16F873.h>
#define PIN_LED7 PIN_B7
#define RB6 PIN_B6
#ifndef EEPROM_SDA
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#endif
#define EEPROM_ADDRESS long int
#device adc=10
#use delay (clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#use i2c(Master,Fast,sda=PIN_C4, scl=PIN_C3)
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
double result;
float x;
int res;
void init_ext_eeprom();
void write_ext_eeprom(long int, byte);
byte read_ext_eeprom(long int);
main()
{
input (PIN_A3);
setup_adc_ports(ALL_ANALOG); // le portA est défini en entrée analogique
setup_adc(ADC_CLOCK_DIV_32); // utilisation de l'horloge interne pour l'ADC
setup_adc_ports(ANALOG_RA3_REF); // RA3 est au +5v pour servir de référence pour la conversion
set_adc_channel(1); // Lecture sur le canal 1 du portA
while(1)
{
output_high(PIN_B7); //allume la led
delay_ms(500);
output_low(PIN_B7); //éteint la led
delay_ms(500);
result = (double)(read_adc()); //récupere la valeur, et donne la tension sur RA1
delay_ms(100);
x = 5.029*(double)(read_adc())/1024;
printf("result = %f \n\r",result); //affichage de la tension sur RA1
printf("tension = %f \n\r",x);
delay_ms(500);
res = read_ext_eeprom(1);
printf("ancienne valeur en memoire = %x\n\r" ,res);
init_ext_eeprom();
delay_ms(500);
printf("Write!\n\r");
delay_ms(500);
write_ext_eeprom(1,result);
delay_ms(500);
printf("Read!\n\r");
delay_ms(500);
res = read_ext_eeprom(1);
delay_ms(500);
printf("Write = %f; Read = %x\n\r" ,result,res);
delay_ms(1000);
output_low(PIN_B7);
void init_ext_eeprom()
{
output_float(eeprom_scl);
output_float(eeprom_sda);
void write_ext_eeprom(long int address, byte data)
{
i2c_start();
i2c_write((0xa0|(byte)(address>>7))&0xfe);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(500); //Avant y'avait 11
byte read_ext_eeprom(long int address)
{
byte data;
i2c_start();
i2c_write((0xa0|(byte)(address>>7))&0xfe);
i2c_write(address);
i2c_start();
i2c_write((0xa0|(byte)(address>>7))|1);
data=i2c_read(0);
i2c_stop();
return(data);
si quelqu'un peut me trouver la faille ca, serai super pour moi!!!!
merci!!
@+
nico
Numéro de l'article: 96070
| De: nico
| Date: 2004-05-10 17:00:38
|
RE: explication ligne prog
Je présume que "adresse" est un mot de 16 bits, dont il est shifté vers la droite de 7, car le poids fort de adresse contine tl'adresse i2c a écrire... ensuite, tu fais un masque, afin de mettre le bit de poids faible de l'octet résulatant a 0 (&0xfe) cela veut dire que tu vas ecrire sur l'i2c... et enfin tu fais un ou avec la valeur 0x0a, autrement dit tu mets les bits 7 et 5 a "1" et c'est cette valeur que tu ecris sur l'i2c...
Exemple si adresse contient 0x1234
apres le décallage, tu auras 0x24
apres le masque 0xfe => tu auras 0x24
et enfin apres le ou avex 0xa0, tu auras 0xa4...
C'est cette valeur que tu ecris sur l'i2c...
Numéro de l'article: 96072
| De: pazcal
| Date: 2004-05-10 17:03:36
|
RE: explication ligne prog
alors quel est le moyen de récupérer ma bonne valeur?
Numéro de l'article: 96075
| De: nico
| Date: 2004-05-10 17:09:41
|
RE: explication ligne prog
Il y a plusioeurs choses a vérifier...
l'adresse i2c de ton chip, j'ai pas lu la datasheet, mais il doit y avoir une partie fixe, et une partie 'variable' que tu positionne avec des pins externes... cela va donner l'aresse i2c tu chip... ensuite pour lire, il faut mette le poids faible de l'adresse a 1 et non pas a 0!!!
sinon ca veut dire que tu ecris... donc la ligne de code doit être :
i2c_write((0xa0|(byte)(address>>7)) | ~0xfe);
ou bien
i2c_write((0xa0|(byte)(address>>7)) | 0x01);
c'est pareil....
good luck
Numéro de l'article: 96079
| De: pazcal
| Date: 2004-05-10 17:17:40
|
RE: explication ligne prog
voila ce que je peux lire sur mon hyper terminal:
ancienne valeur en memoire = 254.999995
Write!
Read!
Write = 1020.999968; Read = 254.999995
result = 1018.999963
tension = 5.014266
j'ai l'impression que c'est pas bon au niveau des formats (ou type de variables...)
j'ai mis:
double result,res;
float x;
Numéro de l'article: 96085
| De: nico
| Date: 2004-05-10 17:26:23
|
RE: explication ligne prog
pour les eeprom I²C je crois que c'est :
1 / 0 / 1 / 0 / A0 / A1 / A2 / R/W
Numéro de l'article: 96106
| De: Manu
| Date: 2004-05-10 17:54:20
|
RE: explication ligne prog
pour ma mémoire 24C16, y'a pas besoin de connecter les broches 1 2 et 3
y'a juste scl sur la 6
sda sur la 5
mais la n'est pas le probleme je crois...
puisque j'arrive a écrire et a lire, meme que si je coupe l'alim et ke je rallume, je retrouve la derniere valeur qui était dans la mémoire...
mais le truc, c'est que j'écris une valeur sur 10bits (valeurs de la tension qui rentre sur RA1, qui fait 5V) et il me revient une donnée qui est 255...pourquoi ca????
merci!!
Numéro de l'article: 96111
| De: nico
| Date: 2004-05-10 18:03:57
|
RE: explication ligne prog
oulala... mdr
Numéro de l'article: 96142
| De: Manu
| Date: 2004-05-10 19:54:41
|
RE: explication ligne prog
quoi mdr????
super l'entraide...
Numéro de l'article: 96246
| De: nico
| Date: 2004-05-11 09:07:23
|
RE: explication ligne prog
pour revenir au début de ta question, prenons cette fonction:
void write_ext_eeprom(long int address, byte data)
{
i2c_start();
i2c_write((0xa0|(byte)(address>>7))&0xfe);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(500); //Avant y'avait 11
le premier I2C_write ecrit les bits de poids haut de l'adresse.
a0 c'est l'adresse physique de ta eeprom en ecriture, ensuite on prend la partie "haute" de ton adresse.
le deuxieme I2C write, c'est la partie basse de ton adresse.
pour le delay, remet les 11ms, cela suffit.
Ton probleme, c'est que avec ces fonctions, on ne peut ecrire que des entiers sur 8 bits! et toi tu ecrit un 16 bits, donc forcement cela ne va pas.
essaie cela:
int8 tempo;
pour l'ecriture:
tempo = (int8)((result>>8));
write_ext_eeprom(1,result);
tempo = (int8)(result & 0x0FF);
write_ext_eeprom(2,(result);
pour l'ecriture:
int16 res;
res = ((int16)(read_ext_eeprom(1))<<8) + ((int16)(read_ext_eeprom(2)));
Numéro de l'article: 96261
| De: SamB
| Date: 2004-05-11 09:42:00
|
RE: explication ligne prog
j'ai mis ce que tu m'as dis et il y une erreur que je connais pas:
Error[3] datalogger.c 90 : Floating point numbers not supported for this operation
voila le prog en entier:
#include<16F873.h>
#define PIN_LED7 PIN_B7
#define RB6 PIN_B6
#ifndef EEPROM_SDA
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#endif
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 65536
#device adc=10
#use delay (clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#use i2c(Master,Fast,sda=PIN_C4, scl=PIN_C3)
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
double result;
//byte res;
float x;
void init_ext_eeprom();
void write_ext_eeprom(long int, byte);
byte read_ext_eeprom(long int);
int8 tempo;
int16 res;
main()
{
input (PIN_A3);
setup_adc_ports(ALL_ANALOG); // le portA est défini en entrée analogique
setup_adc(ADC_CLOCK_DIV_32); // utilisation de l'horloge interne pour l'ADC
setup_adc_ports(ANALOG_RA3_REF); // RA3 est au +5v pour servir de référence pour la conversion
set_adc_channel(1); // Lecture sur le canal 1 du portA
while(1)
{
output_high(PIN_B7); //allume la led
delay_ms(500);
output_low(PIN_B7); //éteint la led
delay_ms(500);
result = (double)(read_adc()); //récupere la valeur, et donne la tension sur RA1
delay_ms(100);
x = 5.029*(double)(read_adc())/1024;
printf("result = %f \n\r",result); //affichage de la tension sur RA1
printf("tension = %f \n\r",x);
delay_ms(500);
res = ((int16)(read_ext_eeprom(1))<<8) + ((int16)(read_ext_eeprom(2)));
printf("ancienne valeur en memoire = %x\n\r" ,res);
init_ext_eeprom();
delay_ms(500);
printf("Write!\n\r");
delay_ms(500);
write_ext_eeprom(1,x);
delay_ms(500);
printf("Read!\n\r");
delay_ms(500);
res = ((int16)(read_ext_eeprom(1))<<8) + ((int16)(read_ext_eeprom(2)));
delay_ms(500);
printf("Write = %f; Read = %2x\n\r" ,x,res);
delay_ms(1000);
output_low(PIN_B7);
void init_ext_eeprom()
{
output_float(eeprom_scl);
output_float(eeprom_sda);
void write_ext_eeprom(long int address, byte data)
{
tempo = (int8)((result>>8));
write_ext_eeprom(1,result);
tempo = (int8)(result & 0x0FF);
write_ext_eeprom(2,(result);
delay_ms(11);
byte read_ext_eeprom(long int address)
{
byte data;
i2c_start();
i2c_write((0xa0|(byte)(address>>9))&0x01);
i2c_write(address);
i2c_start();
i2c_write((0xa1|(byte)(address>>9))|1);
data=i2c_read(0);
i2c_stop();
return(data);
Numéro de l'article: 96290
| De: nico
| Date: 2004-05-11 10:30:10
|
RE: explication ligne prog
il faut laiser les fonctions read et write comme elles sont, le code que je t'ai proposé, il faut le mettre dans ton main.
Apres seulement, tu feras d'autres fonctions ou tu modifieras les fonctions existantes.
Numéro de l'article: 96328
| De: SamB
| Date: 2004-05-11 11:49:42
|
RE: explication ligne prog
ok mais j'ai toujours la meme erreur quand je compile:
Error[3] datalogger.c 90 : Floating point numbers not supported for this operation
et je sais pas ce que sait...
il m'indique la ligne suivant avec une flèche:
tempo = (int8)((result>>8));
Numéro de l'article: 96356
| De: nico
| Date: 2004-05-11 13:35:57
|
RE: explication ligne prog
voila rien que le main()
main()
{
input (PIN_A3);
setup_adc_ports(ALL_ANALOG); // le portA est défini en entrée analogique
setup_adc(ADC_CLOCK_DIV_32); // utilisation de l'horloge interne pour l'ADC
setup_adc_ports(ANALOG_RA3_REF); // RA3 est au +5v pour servir de référence pour la conversion
set_adc_channel(1); // Lecture sur le canal 1 du portA
while(1)
{
output_high(PIN_B7); //allume la led
delay_ms(500);
output_low(PIN_B7); //éteint la led
delay_ms(500);
result = (double)(read_adc()); //récupere la valeur, et donne la tension sur RA1
delay_ms(100);
x = 5.029*(double)(read_adc())/1024;
printf("result = %f \n\r",result); //affichage de la tension sur RA1
printf("tension = %f \n\r",x);
delay_ms(500);
res = ((int16)(read_ext_eeprom(1))<<8) + ((int16)(read_ext_eeprom(2)));
// res = read_ext_eeprom(2);
printf("ancienne valeur en memoire = %x\n\r" ,res);
init_ext_eeprom();
delay_ms(500);
printf("Write!\n\r");
delay_ms(500);
tempo = ((int8)(result>>8));
write_ext_eeprom(1,result);
tempo = (int8)(result & 0x0FF);
write_ext_eeprom(2,(result);
// write_ext_eeprom(2,x);
delay_ms(500);
printf("Read!\n\r");
delay_ms(500);
res = ((int16)(read_ext_eeprom(1))<<8) + ((int16)(read_ext_eeprom(2)));
// res = read_ext_eeprom(2);
delay_ms(500);
printf("Write = %f Read = %x\n\r" ,x,res);
delay_ms(1000);
output_low(PIN_B7);
Numéro de l'article: 96358
| De: nico
| Date: 2004-05-11 13:38:41
|
RE: explication ligne prog
l'opération que je t'ai donnée est faie pour les integer, pas les doubles....
Sauvegarder un integer dans une eeprom, c'est faisable, pour un double c'est une autre histoire...
Numéro de l'article: 96599
| De: SamB
| Date: 2004-05-11 21:48:27
|
RE: explication ligne prog
tu veux dire qu'il me sera impossible de sauvegarder un chiffre tel que: 2.256325 par exemple???? car c'est cela qui m'interresse...
ou alors qu'est ce que je peux faire??
Numéro de l'article: 96666
| De: nico
| Date: 2004-05-12 09:08:17
|