Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#1 Message par dyli » lun. 13 mars 2017 16:11 lien vers la Data-Sheet : Cliquez ici

Bonjour tout le monde,

Voici un code que j'ai trouvé sur internet qui permet de lire un capteur de temperature DS18S20 via pic16f877a et afficher le résultat sur un lcd 2x16.
Donc le programme fonctionne mais j'arrive pas a interpreter quelques lignes dans ce programme. Merci d'avance


Voici les lignes que j'ai mis en rouge dans le code.

1- unsigned short RES_SHIFT = TEMP_RESOLUTION - 8

2-if (temp2write & 0x8000) , ici on fait un ET bit a bit voir datasheet page 6 , donc pour -0.5 degre DS indique 1111 1111 1111 1111 si on fait ET 0x8000
comme resultat on a 0000 0000 0000 0000. comment ce resultat est considéré comme négatif?

3-temp2write = ~temp2write + 1; on fait le complément a 2 , pourquoi ceci?

4- temp_whole = temp2write >> RES_SHIFT ; on décale a droite si j'ai bien compris, mais combien de fois?


Code : Tout sélectionner

//  lecture de temperature par DS18S20  pic1f6877A
// LCD module connections

sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections

//  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
//  18S20: 9  (default setting; can be 9,10,11,or 12)
//  18B20: 12
//Programmer: Syed Tahmid Mahbub
//Compiler: mikroC PRO for PIC v4.60
//Target PIC: PIC16F877A

// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12
unsigned short TEMP_RESOLUTION = 9;
unsigned temp;
char *text = "000.00";
int i;
int colona;

void Read_Temperature()
{
// Perform temperature reading
Ow_Reset(&PORTE, 2); // Onewire reset signal
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0x44); // Issue command CONVERT_T
Delay_us(120);
Ow_Reset(&PORTE, 2);
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTE, 2);
temp = (Ow_Read(&PORTE, 2) << 8) + temp;
}

void Display_Temperature()
{
[
color=#FF0000]unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;[/color]
char temp_whole;
unsigned int temp2write;
unsigned int temp_fraction;

temp2write = temp;
// Check if temperature is negative
[color=#FF0000]if (temp2write & 0x8000)[/color]
{
text[0] = '-';
[
color=#FF0000]temp2write = ~temp2write + 1;[/color]
}
// Extract temp_whole
[color=#FF0000]temp_whole = temp2write >> RES_SHIFT ;[/color]
// Convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;

text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
text[3] = '.';
// Extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// Convert temp_fraction to characters
text[4] = temp_fraction/1000 + 48; // Extract thousands digit
// Print temperature on LCD
Lcd_Out(1, 1, text);
// Print degree character and'C' for Celsius
Lcd_Chr_CP(0xDF); // 223 ASCII for degree symbol on my LCD
Lcd_Chr_CP('C');
}

void main()
{
CMCON |=7;
ADCON1 = 0x0D;
TRISE.B2 = 1; // Configure RE2 pin as input

Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off

// Main loop
do
{
Read_Temperature();
Display_Temperature();
Delay_ms(100);
}
 while (1);

question sur langage c pour pic
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » lun. 13 mars 2017 19:48 lien vers la Data-Sheet : Cliquez ici

bonsoir,



if (temp2write & 0x8000)


Ce test permet d'isoler le bit de signe
on aurait put ecrire
if (temp2write >>15)
le resultat du ET donne soit 0 soit 8000h
donc si >0 ( le signe est negatif .. car sur un entier signé 16 bits , le bit 15 , c'est le signe. ( bit 15 ....bit0))

-temp2write = ~temp2write + 1; on fait le complément a 2 , pourquoi ceci?

parceque c'est imposé ..dans la datasheet
et cela sert à representer des nombres negatifs :
et pour faire un complement à 2 on inverse tous les bits et on rajoute 1
sur 8 bits signes 0xff represente -1 ..
0xFF inversé => 0x00 + 1 => et avec le signe - => -1

temp_whole = temp2write >> RES_SHIFT ; on décale a droite si j'ai bien compris, mais combien de fois?

dans le programme

Code : Tout sélectionner


definition de TEMP_Resolution
unsigned short TEMP_RESOLUTION 
= 9;
....
unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
//soit :
unsigned short RES_SHIFT = 9 - 8 = 1 ;   
//donc
 temp_whole = temp2write >> 1 ;



j'ai testé un 12F1840 8 Pin avec 2 sondes DS18B20et e nvoi via blueTooth
appilcation Appinventor2 en cours ..
Aide toi, le ciel ou FantasPic t'aidera

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#3 Message par dyli » lun. 13 mars 2017 19:58 lien vers la Data-Sheet : Cliquez ici

Bonsoir paulfjujo,

Ah, tu as un site personnel ... je vais voir
Encore une fois, merci beaucoup pour tes réponses Merci !

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#4 Message par dyli » mer. 15 mars 2017 18:56 lien vers la Data-Sheet : Cliquez ici

Bonsoir paulfjujo,

j'ai encore une question concernant la comparaison de la temperature mesurée par un DS18S20 avec PIC16f877A.

si par exemple je veut allumer une led rouge ( ou faire tourner un vetilo) si la temperature dépasse les 30 degré et faire allumer une led orange si la température est en dessous de 5 degré

c'est bien temperature2write que je dois comparer?

si je fais if (temperature2write >3c ) portc.R0=1;

merci d'avance

question sur langage c pour pic
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » mer. 15 mars 2017 20:58 lien vers la Data-Sheet : Cliquez ici

bonsoir ,


si je fais if (temperature2write >3c ) portc.R0=1;




pourquoi 3C ?
0x3C => 60
tu veux dire 30 ? 30°C


il faut utiliser temp_vhole qui represente la temperature entiere ( sans decimale )
donc exprimée en degres

Attention!!
par contre
char temp_whole;
est à declarer comme variable globale
au lieu de la declarer dans void Display_Temperature()
afin d'etre accessible dans le programme principal


Code : Tout sélectionner



char temp_whole
;

// en supposant les 3 leds sur le portC
.......
 Display_Temperature();
if (temp_whole>=30) 
  portC
.B0=;  // led rouge sur RC0
 else
 portC
.B0=0;
 
  if 
(temp_whole>25) && (temp_whole<30)
   portC.B1=;  // led orange sur RC1
   else
    portC
.B1=;
 if (temp_whole<=25)
  portC.B2=;  // led verte sur RC2
  else
  portC
.B2=0;
  ...
  
Aide toi, le ciel ou FantasPic t'aidera

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#6 Message par dyli » mer. 15 mars 2017 21:05 lien vers la Data-Sheet : Cliquez ici

Re bonsoir

pour 30C, j'avais regardé la DS du DS18s20 page 6, donc pour +0.5 c'est ecrit 0000 0000 0000 0001 ce qui fait ( 0001h) en hexa.
j'en ai déduit que pour chaque demi degré on ajoute 1, c'est probablement faux ...

merci

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#7 Message par dyli » mer. 15 mars 2017 22:40 lien vers la Data-Sheet : Cliquez ici

Rebonsoir,

Je viens de testé le programme, mais la led sur RC0 ne s'allume pas quand la température est égale ou plus grande que 30 degré ?

J'ai ajouté le code aprés Display_Temperature(); et char temp_whole apres void main()

Code : Tout sélectionner

//  lecture de temperature par DS18S20  pic1f6877A

// LCD module connections

sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections

//  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
//  18S20: 9  (default setting; can be 9,10,11,or 12)
//  18B20: 12
//Programmer: Syed Tahmid Mahbub
//Compiler: mikroC PRO for PIC v4.60
//Target PIC: PIC16F877A

// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12

unsigned short TEMP_RESOLUTION = 9;
unsigned temp;
char *text = "000.00";
int i;
int colona;
  char temp_whole;

void Read_Temperature()
{
// Perform temperature reading
Ow_Reset(&PORTE, 2); // Onewire reset signal
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0x44); // Issue command CONVERT_T
Delay_us(120);
Ow_Reset(&PORTE, 2);
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTE, 2);
temp = (Ow_Read(&PORTE, 2) << 8) + temp;
}



void Display_Temperature()
{
unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp2write;
unsigned int temp_fraction;

temp2write = temp;
// Check if temperature is negative
if (temp2write & 0x8000)
{
text[0] = '-';
temp2write = ~temp2write + 1;
}
// Extract temp_whole   12
temp_whole = temp2write >> RES_SHIFT ;
// Convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;

text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
text[3] = '.';

// Extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;

// Convert temp_fraction to characters

text[4] = temp_fraction/1000 + 48; // Extract thousands digit
// Print temperature on LCD
Lcd_Out(1, 1, text);
// Print degree character and'C' for Celsius
Lcd_Chr_CP(0xDF); // 223 ASCII for degree symbol on my LCD
Lcd_Chr_CP('C');
}



void main()
{
char temp_whole;
CMCON |=7;
ADCON1 = 0x0D;
TRISE.B2 = 1; // Configure RE2 pin as input
TRISC =0X00;  // portc en sortie
PORTC =0;

Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off

// Main loop


do
{
Read_Temperature();
Display_Temperature();
if (temp_whole>=30)
  portC.B0=;  // led rouge sur RC0
 else
 portC
.B0=0;



Delay_ms(100);
}
 while (1);

question sur langage c pour pic
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#8 Message par paulfjujo » jeu. 16 mars 2017 10:01 lien vers la Data-Sheet : Cliquez ici

et char temp_whole apres void main()


tu te retrouves avec 3 definitions de char temp_whole !

il n'en faut qu'une .. celle ci

Code : Tout sélectionner

unsigned short TEMP_RESOLUTION = 9;
unsigned temp;
char *text = "000.00";
int i;
int colona;
char temp_whole


enleve la variable temp_whole de la fonction Display_Temperature
et supprime celle que tu as mis dans le main

une autre posibilité serait que la fonction display_Temperature retourne la valeur de temp_whole
dans ce cas là, on laisse la variable temp_whole uniquement dans la fonction
car visible uniquement dans celle ci , on en a pas besoin ailleurs
la fonction retournera une copie de cette valeur .. à utiliser dans le main program

Code : Tout sélectionner


char  Display_Temperature
()
{
unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp2write;
unsigned int temp_fraction;

temp2write = temp;
// Check if temperature is negative
if (temp2write & 0x8000)
{
text[0] = '-';
temp2write = ~temp2write + 1;
}
// Extract temp_whole   12
temp_whole = temp2write >> RES_SHIFT ;
// Convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;

text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
text[3] = '.';

// Extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;

// Convert temp_fraction to characters

text[4] = temp_fraction/1000 + 48; // Extract thousands digit
// Print temperature on LCD
Lcd_Out(1, 1, text);
// Print degree character and'C' for Celsius
Lcd_Chr_CP(0xDF); // 223 ASCII for degree symbol on my LCD
Lcd_Chr_CP('C');
return (temp_whole);
}
 


//definir une variable globale , ou dans le main pour recevoir ce resultat
char Degres;

Code : Tout sélectionner

.... 
Degres
=Display_Temperature()
if (Degres>=30)
  portC.B0=;  // led rouge sur RC0
 else
 portC
.B0=0;
....

 
Aide toi, le ciel ou FantasPic t'aidera

question sur langage c pour pic
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#9 Message par dyli » jeu. 16 mars 2017 10:28 lien vers la Data-Sheet : Cliquez ici

bonjour paulfjujo,

merci :-D , ca marche , j'aurais jamais deviné que ca venait de ca...faut avoir de l'experience.
Modifié en dernier par dyli le jeu. 16 mars 2017 14:54, modifié 1 fois.

question sur langage c pour pic
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#10 Message par Jérémy » jeu. 16 mars 2017 11:12 lien vers la Data-Sheet : Cliquez ici

faut avoir de l'experence.


+1 et Paul il en a plein :bravo:
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 18 invités