Soucis de communication 1-wire

Electronique numérique / Circuits logiques programmables EPLD, CPLD, FPGA d'Altera ou de Xilinx VHDL, Verilog ou SystemC

Modérateur : Modérateur

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Soucis de communication 1-wire

Message par pulsar67 »

Bonjour à tous,

Tout d'abord, comme je débarque sur le forum, brève présentation : jeune ingénieur en électronique, je suis aussi passionné par tout ce qui touche à l'embarqué. A côté de cela, ma principale passion est l'astronomie, et plus particulièrement l'astrophoto. Depuis quelques temps je cherche à mettre à profit mes compétences en électronique pour apporter de nouvelles idées pour améliorer le quotidien de l'astronome amateur.

Actuellement, je travaille principalement sur un projet dont le but est de centraliser un maximum de fonctionnalités afin de rendre l'installation de l'astronome la plus autonome possible, et ainsi réduire au maximum le nombre de câbles allant jusqu'au PC (en astrophoto, le PC portable devient quasiment un outil incontournable permettant le contrôle simultané de la monture, le focuser, la caméra CCD, la régulation de température de la CCD, la webcam, la longue pose de la webcam, etc...).

Ce projet est structuré autour d'un ARM7 de chez NXP (LPC2148). Depuis quelques jours, je travaille sur une partie communication en 1-wire permettant le contrôle de différentes températures à l'aide de sondes DS18S20. Seulement voilà... ça ne veut pas vraiment, et c'est là que j'aurais besoin de votre aide.

Pour l'instant, le DS18S20 répond bien au reset... mais rien de plus, quand je veux relire, j'ai 0xFF dans chaque registre. Comme c'est la première fois que je fais du 1-wire, je suis un peu bloqué.

Quelqu'un saurait-il m'aider?

Voici les différentes fonction :

Fonction Reset :

Code : Tout sélectionner

int reset1wire(void)
{
	int status;	

	// configurer P0.28 en sortie
	IODIR0 |= 0x10000000;
	
	// P0.28 = 0
	IOCLR0 = 0x10000000;
	
	// tempo 480us
	delay(480);
	// configurer P0.28 en entrée
	IODIR0 &= 0xEFFFFFFF;

	// tempo 70us
	delay(70);
	// lecture
	if(!(IOPIN0 & 0x10000000))status = 1;
	else status = 0;

	IODIR0 |= 0x10000000;
	delay(410);

	return status;
}
Envoi d'un bit :

Code : Tout sélectionner

void send1wirebit(char bit)
{
	if(bit)
	{
		// configurer P0.28 en sortie
		IODIR0 |= 0x10000000;
		// P0.28 = 1
		IOSET0 = 0x10000000;
		// attente 6us
		delay(6);
		// configurer P0.28 en entrée
		IODIR0 &= 0xEFFFFFFF;

		// attente 64us
		delay(64);
	}
	else
	{
		// configurer P0.28 en sortie
		IODIR0 |= 0x10000000;
		// P0.28 = 0
		IOCLR0 = 0x10000000;
		// attente 60us
		delay(60);
		// configurer P0.28 en entrée
		IODIR0 &= 0xEFFFFFFF;
		// attente 10us
		delay(10);
	}	
}
Envoi d'un octet :

Code : Tout sélectionner

void send1wire(char data)
{
	char i;
	
	// boucle envoi
	for(i=0;i<8;i++)
	{
		// envoi bit
		send1wirebit(data & 0x01);
		// décalage de 1 à droite
		data >>= 1;
	}
}
Lecture d'un bit :

Code : Tout sélectionner

char read1wirebit(void)
{
	char result = 0x00;
	// configurer P0.28 en sortie
	IODIR0 |= 0x10000000;
	// P0.28 = 0
	IOCLR0 = 0x10000000;
	// attente 6us
	delay(6);
	// configurer P0.28 en entrée
	IODIR0 &= 0xEFFFFFFF;
	// attente 9us
	delay(9);
	// lecture
	result = ((IOPIN0 & 0x10000000)>>28);
	
	// attente 55us (pour compléter le time slot)
	delay(55);
	// renvoi résultat lecture
	return result;
}
Lecture d'un octet :

Code : Tout sélectionner

char read1wire(void)
{
	int i;
	char result = 0x00;
	for(i=0;i<8;i++)
	{
		result >>= 1;
		if(read1wirebit())result |= 0x80;
	}
	return result;
}
Fonction demandant de faire une conversion de température puis sensée la relire (je précise que les messages sont bien renvoyées sur la console donc que la fonction arrive à s'exécuter jusqu'au bout) :

Code : Tout sélectionner

int readtemperature(void)
{
	char templow, temphigh, th, tl, res1, res2, countremain, countperc, crc;

	if(!reset1wire())return 0;
	else
	{
		// Skip ROM
		send1wire(0xCC);
		// Convert T
		send1wire(0x44);
		// attente conversion (750ms!)
		while(read1wire()!=0xFF); 
		// reset
		if(!reset1wire())return 0;
		else
		{
			// Skip ROM
			send1wire(0xCC);
			// Read Scratchpad
			send1wire(0xBE);
			// Read byte 1
			templow = read1wire();
			// Read byte 2
			temphigh = read1wire();
			// Read byte 3
			th = read1wire();
			// Read byte 4
			tl = read1wire();
			// Read byte 5
			res1 = read1wire();
			// Read byte 6
			res2 = read1wire();
			// Read byte 7
			countremain = read1wire();
			// Read byte 8
			countperc = read1wire();
			// Read byte 9
			crc = read1wire();
			
			// Write results
			putstr("templow = ");puthex(templow);putstr("\n");
			putstr("temphigh = ");puthex(temphigh);putstr("\n");
			putstr("th = ");puthex(th);putstr("\n");
			putstr("tl = ");puthex(tl);putstr("\n");
			putstr("res1 = ");puthex(res1);putstr("\n");
			putstr("res2 = ");puthex(res2);putstr("\n");
			putstr("countremain = ");puthex(countremain);putstr("\n");
			putstr("countperc = ");puthex(countperc);putstr("\n");
			putstr("crc = ");puthex(crc);putstr("\n");
			return 1;
		}
	}
}
Ai-je fait une connerie quelque part?

Merci d'avance pour vos réponses :)

A+
Gilles
Dernière modification par pulsar67 le 31 mai 2007 12:18, modifié 2 fois.

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Message par pulsar67 »

personne ne peut m'aider? pourtant, si j'ai posté ici, c'est bien parce qu'il y en a qui ont déjà fait du 1-wire...

Matthieu
NOUVEAU
NOUVEAU
Messages : 2
Inscription : 20 avr. 2006 9:50

1-wire

Message par Matthieu »

Bonjour,

une premiere piste:
Dans ta fonction void send1wirebit(char bit),
quelque soit la valeur de ton bit, tu fais la meme chose dans le if et le else.(tu ecrirait un 0 sur le port P0.28 )

Matthieu
Dernière modification par Matthieu le 30 mai 2007 15:21, modifié 1 fois.

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Message par pulsar67 »

Oupss! Merci!

Ah c'est beau le copier-coller... Pourtant, j'avais beau revoir mon code (pourtant, il me semblais avoir fait une simul), j'ai dû passer là dessus 10x sans m'en rendre compte...

Bon, je vais corriger ça ce soir, je verrai ce que ça dit.

Encore merci!

A+
Gilles

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Message par pulsar67 »

Bon, c'était pas ça.. je relis toujours 0xFFFF comme si le bus restait scotché à 1... et le composant répond toujours au reset.

nanick
HABITUE
HABITUE
Messages : 70
Inscription : 28 mai 2006 12:53

Message par nanick »

bonjour,
au dela du code, avez vous la possibilité de mettre un oscillo sur la ligne pour voir s'il ya des changement d'état lors d'une comm.

ça peut aider.

A+

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Message par pulsar67 »

Bonjour,

C'est la prochaine étape... il faut que je voie s'il m'est possible d'emprunter un oscillo numérique au boulot car celui que je possède, c'est galère : un simple analogique tout bête, c'est chaud quand on ne peut pas faire un "run/stop" ;)

C'est un peu frustrant de chercher sans savoir à quoi ressemblent les signaux...

A+

pulsar67
NOUVEAU
NOUVEAU
Messages : 11
Inscription : 23 mai 2007 14:25
Localisation : Niederschaeffolsheim (67)
Contact :

Message par pulsar67 »

Finalement, j'ai refait tout le code de la partie 1-wire d'une autre manière, en m'inspirant d'un driver existant, et ça marche.... (à un bug près : ça fonctionne avec un DS1820 et pas avec un DS18S20)

Répondre