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

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#11 Message par marcus_95 » sam. 4 janv. 2020 09:15

Bonjour,
merci de ton aide.
Cdt.

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#12 Message par marcus_95 » sam. 4 janv. 2020 20:32

Bonjour,
après plusieurs essais, je suis arrivé a ça

Code : Tout sélectionner

// 16F887 avec quartz 20MHz
// led B0 clignotante chaque seconde

#include <xc.h>
#include <stdlib.h>
#include <ctype.h>
#include "UART.h"
#define _XTAL_FREQ 20000000
#pragma config FOSC = HS  // HS oscillateur
#pragma config WDTE = OFF // watchdog off
void main(void)
{
UART_Init (9600);  // Initialise le module UART à 9600bps
__delay_ms (100);  // Attendre que le module UART se stabilise
UART_send_string("UART Module OK ");  
#define ONE_WIRE_PIN   PORTDbits.RD0
#define ONE_WIRE_LOW   TRISA = 0b00000000; RD0=0;
#define ONE_WIRE_HIGH  TRISA = 0b00000001;  

  OSCCON = 0b01111000;    // HS oscillateur
  ANSEL  = 0;             // I/O numériques
  ANSELH = 0;             // I/O numériques
  TRISBbits.TRISB0 = 0;   // output led sur B0
 
  while
(1)
  {  
            
            PORTBbits
.RB0 = 1;    // led on         
            UART_send_string("RED LED -> ON"); 
            UART_send_char
(255);
            __delay_ms(1000);     // 1 seconde
        
           PORTBbits
.RB0 = 0;    // led off
           UART_send_string("RED LED -> OFF"); 
           UART_send_char
(255);
           __delay_ms(1000);     // 1 seconde
  }
}
void onewire_init()  // OK if just using a single permanently connected device
{  
//onewire_disable_interrupts(TRUE);
   ONE_WIRE_LOW;
   __delay_us( 500 ); // pull 1-wire low for reset pulse
   ONE_WIRE_HIGH;     // float 1-wire high
   __delay_us( 80 );  // wait for presence pulse, allowing for device variation
   __delay_us( 420 ); // wait-out remaining initialisation window.
   ONE_WIRE_HIGH;      //float 1-wire pin
//onewire_disable_interrupts(FALSE);


Fichier H

Code : Tout sélectionner

#include <xc.h> // include processor files - each processor file is guarded.  
#define _XTAL_FREQ 20000000
char UART_Init(const long int baudrate)
{
    unsigned int x;
    x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
    if(x>255)
    {
    x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
    BRGH = 1;
    }
    if(x<256)
    {
      SPBRG  = x;
      SYNC   = 0;
      SPEN   = 1;
      TRISC7 = 1;
      TRISC6 = 1;
      CREN   = 1;
      TXEN   = 1;
      return 1;
    }
    return 0;
}

char UART_get_char()   
{
    if(OERR) // check for Error 
    {
    CREN = 0; //If error -> Reset 
    CREN = 1; //If error -> Reset 
    }
    
    while
(!RCIF);  // hold the program till RX buffer is free
    return RCREG;  //receive the value and send it to main function
}
                                               
void UART_send_char
(char bt)  
{
    while(!TXIF);  // hold the program till TX buffer is free
    TXREG = bt;     //Load the transmitter buffer with the received value
}
//**Fonction convertion string en byte**//
void UART_send_string(char* st_pt)
{
    while(*st_pt)               // s'il y a un char 
    UART_send_char(*st_pt++);   // le traiter comme un octet de données 

et ça marche :-D
reste a savoir si OK pour lire une DS18B20.
Cdt.
Marcus.
main.c:34:34: warning: (359) illegal conversion between pointer types: grave ou pas grave ?

Lecture DS18B20 16F887
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#13 Message par satinas » sam. 4 janv. 2020 22:49

Tu progresses bien :-)

Ca marche sur un simulateur ou sur un vrai pic ?

Le tx uart est sur C6, je sais pas pourquoi dans le code exemple il fait TRISC6 = 1, il faudrait faire TRISC6 = 0
Mais je pense que le pic s'en fout, dès qu'on fait TXEN = 1, il met C6 en ouput, idem pour CREN = 1 qui passe C7 en input.

C'est pas conseillé de mettre du code dans un fichier .h
Renomme le fichier uart.h en uart.c et ajoute le au projet.
Il faut mettre le réglage de l'horloge (OSCCON) en premier dans le main.
Le fichier main.c un peu modifié :

Code : Tout sélectionner

// 16F887 avec quartz 20MHz
// led B0 clignotante chaque seconde

#include <xc.h>
#include <stdlib.h>
#include <ctype.h>

#define _XTAL_FREQ 20000000

#pragma config FOSC = HS  // HS oscillateur
#pragma config WDTE = OFF // watchdog off

extern char UART_Init(const long int baudrate);
extern void UART_send_string(char* st_pt);
extern void UART_send_char(char bt);
extern float ds1820_read();

void main(void)
{
  OSCCON = 0b01111000;    // HS oscillateur
  ANSEL  = 0;             // I/O numériques
  ANSELH = 0;             // I/O numériques
  TRISBbits.TRISB0 = 0;   // output led sur B0
 
  UART_Init (9600);       // Initialise le module UART à 9600bps
  __delay_ms(100);        // 100ms
  UART_send_string((char*)"UART Module OK "); 

  while(1)
  { 
    PORTBbits.RB0 = 1;    // led on         
    UART_send_string((char*)"RED LED -> ON");
    UART_send_char(255);
    __delay_ms(1000);     // 1 seconde
       
    PORTBbits.RB0 = 0;    // led off
    UART_send_string((char*)"RED LED -> OFF");
    UART_send_char(255);
    __delay_ms(1000);     // 1 seconde
   
    // data = ds1820_read();
    // convert data to string s
    // UART_send_string(s); 
  }
}


Quand ça marche, tu peux ajouter au projet les 2 fichiers 1wire.c et ds1820.c
Ensuite les compiler après les avoir rendus compatible avec xc8.
C'est le nom des registres de pins qui coince, les compilateurs les baptisent de 36 façons différentes.
Je te laisse faire :-)

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#14 Message par marcus_95 » dim. 5 janv. 2020 12:05

Bonjour pour "Le tx uart est sur C6, je sais pas pourquoi dans le code exemple il fait TRISC6 = 1"
je me suis fier au fichier

Code : Tout sélectionner

SPBRG = x; // Rédaction du registre SPBRG
    SYNC = 0; // Réglage du mode asynchrone, c'est-à-dire UART
    SPEN = 1; // Active le port série
    TRISC7 = 1; // Tel que prescrit dans la fiche technique
    TRISC6 = 1; // Tel que prescrit dans la fiche technique
    CREN = 1; // Permet une réception continue
    TXEN = 1; // Active la transmission  

Aller c'est parti
Cdt.

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#15 Message par marcus_95 » dim. 5 janv. 2020 17:41

Bonjour,
j'utilise proteus comme simulateur plus simple pour faire les essais avant de passer au montage final.
J'ai mis le fichier ds1820_read.c et modifier le fichier UART.H en .C
Si je décommente la ligne "data = ds1820_read();" ça ne marche plus, j'ai essayé d'ajouter 1-wire en .H ou en .C c'est pire.

Code : Tout sélectionner

// 16F887 avec quartz 20MHz
// led B0 clignotante chaque seconde

#include <xc.h>
#include <stdlib.h>
#include <ctype.h>
#define _XTAL_FREQ 20000000

#pragma config FOSC = HS  // HS oscillateur
#pragma config WDTE = OFF // watchdog off

extern char UART_Init(const long int baudrate);
extern void UART_send_string(charst_pt);
extern void UART_send_char(char bt);
extern float ds1820_read();
extern float data;

void main(void)
{
  
OSCCON 0b01111000;    // HS oscillateur
  
ANSEL  0;             // I/O numériques
  
ANSELH 0;             // I/O numériques
  
TRISBbits.TRISB0 0;   // output led sur B0     
  #define LED PORTBbits.RB0

  
UART_Init (9600);       // Initialise le module UART à 9600bps
  
__delay_ms(100);        // 100ms
  
UART_send_string((char*)"UART Module OK "); 

  while(
1)
  { 
    
LED 1;    // led on         
    
UART_send_string((char*)"RED LED -> ON");
    
UART_send_char(255);
    
__delay_ms(1000);     // 1 seconde
       
    
LED 0;    // led off
    
UART_send_string((char*)"RED LED -> OFF");
    
UART_send_char(255);
    
__delay_ms(1000);     // 1 seconde
   
   
data ds1820_read();
//    convert data to string s
//    UART_send_string(s); 
  
}
}
 

Code : Tout sélectionner

#include <xc.h> // include processor files - each processor file is guarded.  
#define _XTAL_FREQ 20000000
char UART_Init(const long int baudrate)
{
    
unsigned int x;
    
= (_XTAL_FREQ baudrate*64)/(baudrate*64);
    if(
x>255)
    {
    
= (_XTAL_FREQ baudrate*16)/(baudrate*16);
    
BRGH 1;
    }
    if(
x<256)
    {
      
SPBRG  x;
      
SYNC   0;
      
SPEN   1;
      
TRISC7 1;
      
TRISC6 1;
      
CREN   1;
      
TXEN   1;
      return 
1;
    }
    return 
0;
}

char UART_get_char()   
{
    if(
OERR// check for Error 
    
{
    
CREN 0//If error -> Reset 
    
CREN 1//If error -> Reset 
    
}
    
    while(!
RCIF);  // hold the program till RX buffer is free
    
return RCREG;  //receive the value and send it to main function
}
                                               
void UART_send_char(char bt)  
{
    while(!
TXIF);  // hold the program till TX buffer is free
    
TXREG bt;     //Load the transmitter buffer with the received value
}
//**Fonction convertion string en byte**//
void UART_send_string(charst_pt)
{
    while(*
st_pt)               // s'il y a un char 
    
UART_send_char(*st_pt++);   // le traiter comme un octet de données 
}  

Code : Tout sélectionner

float ds1820_read()
{
 
int busy=0temp1temp2;
 
float temp3;
 
float data;

 
onewire_reset();
 
onewire_write(0xCC);
 
onewire_write(0x44);

 while (
busy == 0)
 
busy onewire_read();
 
onewire_reset();
 
onewire_write(0xCC);
 
onewire_write(0xBE);
 
temp1 onewire_read();
 
temp2 onewire_read();
 
temp3 make16(temp2temp1);
 
 
data = (float) temp3 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution
 
__delay_ms(200);
 return(
data);

je comprend pas pourquoi

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#16 Message par marcus_95 » dim. 5 janv. 2020 17:58

le fichier 1wire

Code : Tout sélectionner

////// 1wire.c fontion //////
///// DS18b20 data pin connected to  pic16f628 B0 pin //////
/***********************1Wire Class***********************/
/*Description: This class handles all communication */
/* between the processor and the 1wire */
/* sensors.
*//*********************************************************/
/*-------1-wire definitions-------*/
#define SONDE  PORTCbits.RC6 
/*******************1-wire communication functions********************/
void onewire_reset()  // OK if just using a single permanently connected device
{
output_low(SONDE);
__delay_us500 ); // pull 1-wire low for reset pulse
output_float(SONDE); // float 1-wire high
__delay_us500 ); // wait-out remaining initialisation window.
output_float(SONDE);
}
/*********************** onewire_write() ********************************/
/*This function writes a byte to the sensor.*/
/* */
/*Parameters: byte - the byte to be written to the 1-wire */
/*Returns: */
/*********************************************************************/

void onewire_write(int data)
{
int count;

for (
count=0count<8; ++count)
{
  
output_low(SONDE);
  
__delay_us); // pull 1-wire low to initiate write time-slot.
  
output_bit(SONDEshift_right(&data,1,0)); // set output bit on 1-wire
  
__delay_us60 ); // wait until end of write slot.
  
output_float(SONDE); // set 1-wire high again,
  
__delay_us); // for more than 1us minimum.
}
}

/*********************** read1wire() *********************************/
/*This function reads the 8 -bit data via the 1-wire sensor. */
/* */
/*Parameters: */
/*Returns: 8-bit (1-byte) data from sensor */
/*********************************************************************/

int onewire_read()
{
int countdata;

for (
count=0count<8; ++count)
{
  
output_low(SONDE);
  
__delay_us); // pull 1-wire low to initiate read time-slot.
  
output_float(SONDE); // now let 1-wire float high,
  
__delay_us); // let device state stabilise,
  
shift_right(&data,1,input(SONDE)); // and load result.
  
__delay_us120 ); // wait until end of read slot.
}

return( 
data );

Lecture DS18B20 16F887
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#17 Message par satinas » dim. 5 janv. 2020 20:05

Chaque fichier .c déclaré dans le projet est une unité de compilation autonome avec ses variables et ses fonctions.
Lors d'un build tous ces fichiers .c sont compilés un par un, puis le linker regroupe les résultats dans le .hex
En faisant un clic droite sur le nom du fichier 1wire.c, tu peux lancer sa compilation.

Le fichier 1wire.c lors de sa compilation a aussi besoin (comme uart.c) de l'include xc.h, et du define _XTAL_FREQ pour ses delay(). Pour alléger, tu peux supprimer le fichier ds1820.c et mettre la fonction ds1820_read() à la fin du fichier 1wire.c.

Compile les fichiers séparément avec un clic droite, et quand ils passent tous sans erreur, tu lances le build.
le "extern" devant "float data" est en trop.
La SONDE est sur C6, bizarre ...
Tu as regardé le contenu du fichier 1wire.c ?
Va falloir te mettre au C ou (re)passer à l'arduino :-)

En début de 1wire.c, Il faut déclarer les macros output_low(), output_float(), output_bit, shift_right()
Je sais pas où elles étaient définies dans la version CCS, en tout cas il faut les refaire
J'ai été un peu vite en te disant que ce serait simple, je pensais que tu avais commencé à le faire :-(
par exemple, voir en haut de page -> #define ONE_WIRE_LOW TRISA = 0b00000000; RD0=0;

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#18 Message par marcus_95 » lun. 6 janv. 2020 17:56

Bonsoir,
après des heures de recherches j'en suis toujours au même point.
Clic droit pour compiler les fichiers 1 par 1, OK et quand je fait un build problème avec la routine ds1820_read();
C'est sur avec Arduino aucun problème.
Ce programme une fois fini vas venir compléter un programme PIC pour un système de sarter.
Je vois pas du tout ou ça cloche.

Code : Tout sélectionner

// 16F887 avec quartz 20MHz
// led B0 clignotante chaque seconde
// PIC16F887 Configuration Bit Settings
#define _XTAL_FREQ 20000000
#include <xc.h>
#include <stdlib.h>
#include <ctype.h>
#include "fuses.h"
extern char UART_Init(const long int baudrate);
extern void UART_send_string(char* st_pt);
extern void UART_send_char(char bt);
extern float ds1820_read();
float data;
char s= "FIN DE BOUCLE  ";
float result;
//------------------------------------------------------------------------------
void main(void)
{
  OSCCON = 0b01111000;    // HS oscillateur
  ANSEL  = 0;             // I/O numériques
  ANSELH = 0;             // I/O numériques
  TRISBbits.TRISB0 = 0;   // output led sur B0     
  #define LED   PORTBbits.RB0
            
  UART_Init 
(9600);      // Initialise le module UART à 9600bps
  __delay_ms(100);        // 100ms
  UART_send_string((char*)"UART Module OK "); // Affichage

  while(1)
  { 
    
//**********************************************
      LED = 1;    // led on         
    UART_send_string((char*)"RED LED -> ON");
    UART_send_char(13);
    __delay_ms(1000);     // 1 seconde
    //**********************************************   
    LED = 0;    // led off
    UART_send_string((char*)"RED LED -> OFF");
    UART_send_char(13);
    __delay_ms(1000);     // 1 seconde
    //***********************************************
 
//---------------------------------------------     
ds1820_read();
//convert data to string s;
UART_send_string (s);
UART_send_char(13);
//---------------------------------------------- 
  }}
 

Code : Tout sélectionner

#define _XTAL_FREQ 20000000
#include <xc.h>
#define SONDE PORTAbits.RA0
#define BUS_A TRISAbits.TRISA0 
//------------------------------------------------------------------------------
void onewire_reset()  // OK if just using a single permanently connected device
{
output_low(SONDE);
__delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(SONDE); // float 1-wire high
__delay_us( 500 ); // wait-out remaining initialisation window.
output_float(SONDE);
}
//------------------------------------------------------------------------------
void onewire_write(int data)
{
int count;

for (count=0; count<8; ++count)
{
  output_low(SONDE);
  __delay_us( 2 ); // pull 1-wire low to initiate write time-slot.
  output_bit(SONDE, shift_right(&data,1,0)); // set output bit on 1-wire
  __delay_us( 60 ); // wait until end of write slot.
  output_float(SONDE); // set 1-wire high again,
  __delay_us( 2 ); // for more than 1us minimum.
}
}
//------------------------------------------------------------------------------
int onewire_read()
{
int count, data;

for (count=0; count<8; ++count)
{
  output_low(SONDE);
  __delay_us( 2 ); // pull 1-wire low to initiate read time-slot.
  output_float(SONDE); // now let 1-wire float high,
  __delay_us( 8 ); // let device state stabilise,
  shift_right(&data,1,input(SONDE)); // and load result.
  __delay_us( 120 ); // wait until end of read slot.
}
return(
 data );
}
//------------------------------------------------------------------------------
float ds1820_read ()
{
 int busy=0, temp1, temp2;
 float temp3;
 float result;

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0x44);

 while (busy == 0)
 busy = onewire_read();

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0xBE);
 temp1 = onewire_read();
 temp2 = onewire_read();
 temp3 = make16(temp2, temp1);
 
 result 
= (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution
  __delay_ms(200);

 return(result);
}
//------------------------------------------------------------------------------
 

j'ai tester en faisant un seul fichier c'est pareil.

"En début de 1wire.c, Il faut déclarer les macros output_low(), output_float(), output_bit, shift_right() il faut les refaire"
Comment ont fait ça ?

Cdt.
Marcus.

Lecture DS18B20 16F887
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#19 Message par satinas » lun. 6 janv. 2020 18:38

Bonsoir
En début de 1wire.c, Il faut définir les macros ou fonctions input(), output_low(), output_float(), output_bit(), shift_right(), make16()
Je sais pas où elles étaient définies dans la version CCS, en tout cas il faut les refaire, car elles n'existent pas dans xc8.
http://www.ccsinfo.com/downloads/CReferenceManual.pdf

Démarrer un capteur sur un bus 1-wire c'est pas simple. Même en s'inspirant d'un autre programme, il faut se documenter sur le bus, lire le datasheet du capteur, et faire des essais progressifs dans le monde réel.
Désolé mais je peux pas le faire en aveugle et à ta place.

L'avantage de l'Arduino, c'est que tu as les bibliothèques OneWire et DS18B20 toutes faites et fiables, et pour les utiliser même un débutant en C peut s'en sortir.

Lecture DS18B20 16F887
marcus_95
Débutant
Débutant
Messages : 49
Âge : 61
Enregistré en : mai 2018
Localisation : LE BOURGET

#20 Message par marcus_95 » mar. 7 janv. 2020 13:02

Bonjour,
merci de m'avoir aidé, je vais approfondir le bus 1wire pour PIC.
Merci pour la Doc.
Oui 1wire sur Arduino c'est hyper simple a mettre en oeuvre, j'ai fait un régulateur de température du BED sur une Anet A8 (résistance en 220V).
Le starter fonctionne avec un Arduino pro mini, je voulais faire plus simple car il y a pas mal de broches libres sur le 16F887, je ne lâche pas j'ai du temps.
Cdt.
Marcus.


Retourner vers « Langage C »

Qui est en ligne

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