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

#21 Message par marcus_95 » jeu. 9 janv. 2020 13:27

Bonjour,
après des recherches et des essais j' ai réussi a finaliser mon programmes.
A votre avis c'est correct, la lecture de la température sert 1 fois jusqu'au prochain redémarrage.

Code : Tout sélectionner

// Modifier pour un starter
// 3 lectures de la sonde, affichage pour le test.
// a inclure dans autre programme
/*
 * Interfacing PIC16F887 microcontroller with DS18B20 temperature sensor.
 * C Code for MPLAB XC8 compiler.
 * Internal oscillator used @ 8MHz.---->( 20MHz)
 * This is a free software with NO WARRANTY.
 * https://simple-circuit.com/
*/ 
#define _XTAL_FREQ 20000000
#include "fuses.h"
#include <xc.h>
#include <stdint.h>        // include stdint header
                           // DS18B20 data pin is connected to pin RB1
#define DS18B20_PIN      RB1
#define DS18B20_PIN_Dir  TRISB1
//------------------------------------------------------------------------------
// a supprimer si OK 
extern char UART_Init(const long int baudrate);
extern void UART_send_string(charst_pt);
extern void UART_send_char(char bt);
//------------------------------------------------------------------------------ 
uint16_t raw_temp;
char     temp[] = "000.0000 C";
 
__bit ds18b20_start()
{
  
DS18B20_PIN 0;      // send reset pulse to the DS18B20 sensor
  
DS18B20_PIN_Dir 0;  // configure DS18B20_PIN pin as output
  
__delay_us(500);      // wait 500 us
 
  
DS18B20_PIN_Dir 1;  // configure DS18B20_PIN pin as input
  
__delay_us(100);      // wait 100 us to read the DS18B20 sensor response
 
  
if (!DS18B20_PIN)
  {
    
__delay_us(400);    // wait 400 us
    
return 1;           // DS18B20 sensor is present
  
}
 
  return 
0;   // connection error
}
 
void ds18b20_write_bit(uint8_t value)
{
  
DS18B20_PIN 0;
  
DS18B20_PIN_Dir 0;  // configure DS18B20_PIN pin as output
  
__delay_us(2);        // wait 2 us
 
  
DS18B20_PIN = (__bit)value;
  
__delay_us(80);       // wait 80 us
 
  
DS18B20_PIN_Dir 1;  // configure DS18B20_PIN pin as input
  
__delay_us(2);        // wait 2 us
}
 
void ds18b20_write_byte(uint8_t value)
{
  for(
uint8_t i 08i++)
    
ds18b20_write_bit(value >> i);
}
 
__bit ds18b20_read_bit(void)
{
  static 
__bit value;
 
  
DS18B20_PIN 0;
  
DS18B20_PIN_Dir 0;  // configure DS18B20_PIN pin as output
  
__delay_us(2);
 
  
DS18B20_PIN_Dir 1;  // configure DS18B20_PIN pin as input
  
__delay_us(5);        // wait 5 us
 
  
value DS18B20_PIN;  // read and store DS18B20 state
  
__delay_us(100);      // wait 100 us
 
  
return value;
}
 
uint8_t ds18b20_read_byte(void)
{
  
uint8_t value 0;
 
  for(
uint8_t i 08i++)
    
value |= ds18b20_read_bit() << i;
 
  return 
value;
}
 
__bit ds18b20_read(uint16_t *raw_temp_value)

  if (!
ds18b20_start())       // send start pulse
    
return 0;                 // return 0 if error
 
  
ds18b20_write_byte(0xCC);   // send skip ROM command
  
ds18b20_write_byte(0x44);   // send start conversion command
 
  
while(ds18b20_read_byte() == 0);  // wait for conversion complete
 
  
if (!ds18b20_start())       // send start pulse
    
return 0;                 // return 0 if error
 
  
ds18b20_write_byte(0xCC);   // send skip ROM command
  
ds18b20_write_byte(0xBE);   // send read command
 
  // read temperature LSB byte and store it on raw_temp_value LSB byte
  
*raw_temp_value  ds18b20_read_byte();
  
// read temperature MSB byte and store it on raw_temp_value MSB byte
  
*raw_temp_value |= (uint16_t)(ds18b20_read_byte() << 8);
 
  return 
1;   // OK --> return 1
}
/*************************** main function *********************/
// Rajour autre programme
void main(void)
{
  
OSCCON 0b01111000;    // HS oscillateur
  
ANSEL  0;             // I/O numériques
  
ANSELH 0;             // configure all PORTB pins as digital
 //-----------------------------------------------------------------------------
  
UART_Init (9600);       // Initialise le module UART à 9600bps
  
__delay_ms(100);        // 100ms
//------------------------------------------------------------------------------
 
int i;
 
for (
03i++)  // Faire 3 meusures
{
  
temp[8] = 223;         // put degree symbol ( ° )
//------------------------------------------------------------------------------
  
if(ds18b20_read(&raw_temp))
    {
      if(
raw_temp 0x8000)          // if the temperature is negative
      
{
        
temp[0] = '-';               // put minus sign (-)
        
raw_temp = (~raw_temp) + 1;  // change temperature value to positive form
      
}
 
      else
      {
        if((
raw_temp >> 4) >= 100)  // if the temperature >= 100 °C
          
temp[0] = '1';            // put 1 of hundreds
        
else                        // otherwise
          
temp[0] = ' ';            // put space ' '
      
}
      
// put the first two digits ( for tens and ones)
      
temp[1] = ( (raw_temp >> 4) / 10 ) % 10 '0';  // put tens digit
      
temp[2] =   (raw_temp >> 4)        % 10 '0';  // put ones digit
 
      // put the 4 fraction digits (digits after the point)
      // why 625?  because we're working with 12-bit resolution (default resolution)
      
temp[4] = ( (raw_temp 0x0F) * 625) / 1000 '0';          // put thousands digit
      
temp[5] = (((raw_temp 0x0F) * 625) / 100 ) % 10 '0';    // put hundreds digit
      
temp[6] = (((raw_temp 0x0F) * 625) / 10 )  % 10 '0';    // put tens digit
      
temp[7] = ( (raw_temp 0x0F) * 625) % 10 '0';            // put ones digit
   
}    
      else
    {
      
UART_send_string((char*)" Error! "); // Affichage
    
}
}
//------------------------------------------------------------------------------
  
while(1// ne doit pas etre bloquante
  
{
      
UART_send_string (temp);
      
UART_send_char(13);
  }
}     

Code : Tout sélectionner

#define _XTAL_FREQ 20000000
#include <xc.h>
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

#define _XTAL_FREQ 20000000
#include <xc.h>
#include <stdlib.h>
#include <ctype.h>
// CONFIG1
#pragma config FOSC  = HS       // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE  = OFF      // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP    = OFF      // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD   = OFF      // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO  = OFF      // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP   = OFF      // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

//------------------------------------------------------------------------------
 

Cdt.
Marcus.

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

#22 Message par satinas » jeu. 9 janv. 2020 15:32

Bonjour, tu es le seul à pouvoir répondre à ta question.
Si le compilateur ne retourne ni erreur ni warning, c'est bon signe.
Le blog où tu as récupéré le programme est sérieux, il y a toutes les chances que cela marche.
Je vois pas l'intérêt des 3 mesures, fais comme ta source une mesure chaque seconde.

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

#23 Message par marcus_95 » jeu. 9 janv. 2020 21:18

Bonjour,
"Je vois pas l'intérêt des 3 mesures, fais comme ta source une mesure chaque seconde."
Pour le starter il me faut une info uniquement a la mise en route du prog, après c'est plus utile.
Le prog est fait pour tourner a 8MHs,et pour mon utilisation il doit tourner a 20MHz, j'ai moins d’erreurs avec une boucle (voir un return).
Je posterais le programme complet après une petite mise en forme.
Merci !
Marcus.

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

#24 Message par marcus_95 » ven. 10 janv. 2020 18:09

Bonsoir,
voila les fichiers modifiés.
L'ensemble fonctionne correctement, le temps de retrouver mon PICKIT3 et faire des testes réel.

Code : Tout sélectionner

//
// Cyril Haenel
// http://chaenel.free.fr
// 
// Avertissement :
//
// - Ce programme n'est pas garanti
// - Si vous utilisez ce programme dans votre véhicule, vous le faites
//   à vos risques et périls. Je ne pourrai être tenu pour responsable
//   s'il vous arrivait quelque chose (à vous, à un tier, a votre véhicule, etc...)
// - Je vous autorise à exploiter ce programme uniquement dans un but personnel
//   et non commercial. Pour une utilisation commerciale, veuillez me contacter
//   par l'interface de mon site : http://chaenel.free.fr/cmsimple/?&mailform
//
/*
 * Interfacing PIC16F887 microcontroller with DS18B20 temperature sensor.
 * C Code for MPLAB XC8 compiler.
 * Internal oscillator used @ 8MHz.---->( 20MHz)
 * This is a free software with NO WARRANTY.
 * https://simple-circuit.com/

 Modification par marcus:
 * Ajout d'un starter automatique avec une sonde DS18B20.
 * Compatiilé avec MPLA X IDE XC8 mode 90
 * Changement des IRF540 par des TIP122,les IRF540 faisais bugger le programme
 * par intermittence
 */
 

#define _XTAL_FREQ 20000000
#include <pic16f887.h>
#include <xc.h>
#include <stdint.h>       
#include <stdlib.h>
#include <ctype.h>
#include "timer.h"     
#include "ihm.h"
#include "def.h"       
#include "fuses.h"
// DS18B20 data pin is connected to pin RA3
#define DS18B20_PIN      RA3
#define DS18B20_PIN_Dir  TRISA3
#define OK_PIN           RA2
#define OK_PIN_Dir       TRISA2 
int * status;
// a supprimer si OK 
extern char UART_Init(const long int baudrate);
extern void UART_send_string(char* st_pt);
extern void UART_send_char(char bt);
uint16_t raw_temp;
char     temp[] = "000.0000 C";
float temp_ext;
char temp2;
//-----------------------------------------------------------------------------
__bit ds18b20_start()
{
  DS18B20_PIN = 0;      // send reset pulse to the DS18B20 sensor
  DS18B20_PIN_Dir = 0;  // configure DS18B20_PIN pin as output
  __delay_us(500);      // wait 500 us
 
  DS18B20_PIN_Dir 
= 1;  // configure DS18B20_PIN pin as input
  __delay_us(100);      // wait 100 us to read the DS18B20 sensor response
 
  if 
(!DS18B20_PIN)
  {
    __delay_us(400);    // wait 400 us
    return 1;           // DS18B20 sensor is present
  }
 
  return 0
;   // connection error
}
 
void ds18b20_write_bit
(uint8_t value)
{
  DS18B20_PIN = 0;
  DS18B20_PIN_Dir = 0;  // configure DS18B20_PIN pin as output
  __delay_us(2);        // wait 2 us
 
  DS18B20_PIN 
= (__bit)value;
  __delay_us(80);       // wait 80 us
 
  DS18B20_PIN_Dir 
= 1;  // configure DS18B20_PIN pin as input
  __delay_us(2);        // wait 2 us
}
 
void ds18b20_write_byte
(uint8_t value)
{
  for(uint8_t i = 0; i < 8; i++)
    ds18b20_write_bit(value >> i);
}
 
__bit ds18b20_read_bit
(void)
{
  static __bit value;
 
  DS18B20_PIN 
= 0;
  DS18B20_PIN_Dir = 0;  // configure DS18B20_PIN pin as output
  __delay_us(2);
 
  DS18B20_PIN_Dir 
= 1;  // configure DS18B20_PIN pin as input
  __delay_us(5);        // wait 5 us
 
  value 
= DS18B20_PIN;  // read and store DS18B20 state
  __delay_us(100);      // wait 100 us
 
  return value
;
}
 
uint8_t ds18b20_read_byte
(void)
{
  uint8_t value = 0;
 
  for
(uint8_t i = 0; i < 8; i++)
    value |= ds18b20_read_bit() << i;
 
  return value
;
}
 
__bit ds18b20_read
(uint16_t *raw_temp_value)
{
 
  if 
(!ds18b20_start())       // send start pulse
    return 0;                 // return 0 if error
 
  ds18b20_write_byte
(0xCC);   // send skip ROM command
  ds18b20_write_byte(0x44);   // send start conversion command
 
  while
(ds18b20_read_byte() == 0);  // wait for conversion complete
 
  if 
(!ds18b20_start())       // send start pulse
    return 0;                 // return 0 if error
 
  ds18b20_write_byte
(0xCC);   // send skip ROM command
  ds18b20_write_byte(0xBE);   // send read command
 
  
// read temperature LSB byte and store it on raw_temp_value LSB byte
  *raw_temp_value  = ds18b20_read_byte();
  // read temperature MSB byte and store it on raw_temp_value MSB byte
  *raw_temp_value |= (uint16_t)(ds18b20_read_byte() << 8);
 
  return 1
;   // OK --> return 1
}
//------------------------------------------------------------------------------
void _lowInit(void)
{
//----------------------------- PIC 16F887 -----------------------------        
    OSCCON = 0b01111000;    // HS oscillateur        
    ANSEL   = 0;  // Configure AN pins as digital
    ANSELH  = 0;
    CM1CON0 = 7;  // Comparators off
    CM2CON0 = 7;
        //----------------------------------------------------------------------
        //----------------------------- PIC 16F876 -----------------------------
        //ADCON1 = 0b0111; // 0x81; // Désactive PORTA ADC
        //CMCON = 0b111;   // Désactiver les comparateurs
        //------------------------Sortie = 0 Entrée = 1-------------------------
        //PORTA = 0;
         TRISA0 = 0;       // Sortie
         TRISA1 = 0;       // Sortie
         TRISA2 = 0;       // Sortie
        // Soprties Injecteurs
        PORTB = 1;         // Init du port B,
        TRISB = 0;         // En Sorties
        // Entrées injecteurs
        PORTC = 0;         // Init du port C
        TRISC = 0xFF;      // En entrées
        //---------------------------  NC  -------------------------------------
        PORTD = 0;         // En Sorties mises a la masse car NC
        TRISD = 0;         // Mises a la masse car NC
        // derniere modif le 09/01/2020 tris D et E a 0
        PORTE = 0;         // En Sorties mises a la masse car NC
        TRISE = 0;         // Mises a la masse car NC
}
  void main ( void )
{
   OK_PIN_Dir = 0;
   OK_PIN = 0;       
  _lowInit
();             // Configuration des ports ci-dessus.
  _ihmInit();             // Temps pour modifier l'inter SP E85
  UART_Init (9600);       // Initialise le module UART à 9600bps
  __delay_ms(100);        // 100ms
//------------------------------------------------------------------------------
  if(ds18b20_read(&raw_temp))
    {
      if(raw_temp & 0x8000)          // if the temperature is negative
      {
        temp[0] = '-';               // put minus sign (-)
        raw_temp = (~raw_temp) + 1;  // change temperature value to positive form
      }
 
      else
      
{
        if((raw_temp >> 4) >= 100)  // if the temperature >= 100 °C
          temp[0] = '1';            // put 1 of hundreds
        else                        // otherwise
          temp[0] = ' ';            // put space ' '
      }
      // put the first two digits ( for tens and ones)
      temp[1] = ( (raw_temp >> 4) / 10 ) % 10 + '0';  // put tens digit
      temp[2] =   (raw_temp >> 4)        % 10 + '0';  // put ones digit
 
      
// put the 4 fraction digits (digits after the point)
      // why 625?  because we're working with 12-bit resolution (default resolution)
      temp[4] = ( (raw_temp & 0x0F) * 625) / 1000 + '0';          // put thousands digit
      temp[5] = (((raw_temp & 0x0F) * 625) / 100 ) % 10 + '0';    // put hundreds digit
      temp[6] = (((raw_temp & 0x0F) * 625) / 10 )  % 10 + '0';    // put tens digit
      temp[7] = ( (raw_temp & 0x0F) * 625) % 10 + '0';            // put ones digit

      __delay_ms(5); 

      temp_ext 
= atoi(temp);
      UART_send_string (temp);
      UART_send_char(13);
      
      if 
(temp_ext == 85)// bug programme lecture fausse 
    { return;}    
     UART_send_string
((char*)" OK !...... "); // Affichage  
     OK_PIN = 1;     
  
_timerInit
();        // Init des interruptions timer et gestion injecteurs
}
//------------------------------------------------------------------------------ 
   while( 1 )        // Tache de fond, aucun processus bloquant.
 { 
    _ihmRun
();        // LED
    _timerRun();      // Timer 
 }
}

Code : Tout sélectionner

#define _XTAL_FREQ 20000000
#include <pic16f887.h>
#include <xc.h>
#include <stdint.h>       
#include <stdlib.h>
#include <ctype.h>
#include "timer.h"     
#include "ihm.h"
#include "def.h"       
#include "fuses.h"
#define LED   PORTAbits.RA0  // LED de vie et pourcentage en plus par 5%
#define RC7   PORTCbits.RC7  // Pour l'inter 
#define SONDE PORTAbits.RA1  // Relay temperature
static BYTE  ROUE;           // valeur 30% tablau 6
static BYTE  injectionValue; // Valeur de l'injection supplémentaire du mode E85
// Au bout d'un certain temps après le demarrage on n'est plus autorisé
// à changer de mode ou changer l'enrichissement
static WORD startupTmp; // Temporisation pour la gestion du mode de carburation
static WORD starterTmp; // Temporisation pour le starter
// Variables pour la gestion de l'affichage du mode en cours
static WORD ledTmp;
static BYTE ledCyc;
static BYTE ledFlashNumber;
//------------------------------------------------------------------------------
unsigned int _ihmInjectionValueGet ( void )// lecture de la valeur supplementaire
{            
    if 
(startupTmp != 0)              // Dans les 20 secondes on peut modifier l'inter
    {
        if ( RC7 == 0 )               // En mode SP95, pas d'enrichissement
           { ROUE = 0; return 0;}     // 0%
       
        if 
(starterTmp !=0)           // Boucle starter 10 seconde
        {
            if (temp_ext < 16)
            {ROUE = 10; SONDE = 1; return 10;}     // Starter 50% + Sonde
        
             if 
((temp_ext > 16) && (temp_ext < 30))// Starter 50%
             {ROUE = 10; return 10;} 
        
             if 
( temp_ext > 30 )                   // pas de Starter                
             { ROUE = 6; return 6; }  
        
}
    if ( RC7 == 0 )               // En mode SP95, pas d'enrichissement
       { ROUE = 0; return 0;}     // 0%
    else
    
{ROUE = 6; SONDE = 0; }       // 30%
   
    
}                            
           
    injectionValue 
= ROUE;    
    return injectionValue
;
}
//------------------------------------------------------------------------------
void _ihmInit ( void )         
{
  startupTmp = 20000;          // 20 secondes pour modifier l'inter
  starterTmp = 10000;          // starter 10 secondes
}
//------------------------------------------------------------------------------
void _ihm1msInt ( void )        // Appeler toute les 1ms depuis le timer
{
 if ( ledTmp ) ledTmp--;        
 if 
( startupTmp ) startupTmp--;    
 if 
( starterTmp ) starterTmp--;      
}
//------------------------------------------------------------------------------
void _ihmRun ( void )           // Appeler par main.c boucle while( 1 )
{
// Gestion de l'affichage du mode en cours
    switch( ledCyc )
    { case 0 : 
       if 
( ROUE == 0 )
           { // Si en mode SP95, la led est ON en permanence
             LED = 1;
           }
       else
           
{ // Sinon on est en mode E85, on affiche le taux d'enrichissement
             ledCyc = 10;
           }
             break;

         case 10: 
       
// Affichage du taux d'enrichissement E85
       ledTmp = 2000; // On commence par une pause de 2s (2000ms) avec la led eteinte
       LED = 0;
       ledCyc++;
             break;

         case 11: 
       if 
( ledTmp )
           break;
       // Pause finie, on flashe la led
       ledFlashNumber = ROUE;
       ledCyc++;
             break;

         case 12: 
       if 
( ledFlashNumber == 0 )
           { // Si plus de flash à faire on a fini
                ledCyc = 0;
                break;
           }
       // Sinon on allume la led pour 200ms
       ledTmp = 200;
       LED = 1;
       ledCyc++;
       break;
       
         case 13
: 
       if 
( ledTmp )
           break;
       // Pause finie, on coupe la led pour 200ms
       ledTmp = 200;
       LED = 0;
       ledCyc++;
             break;

         case 14: 
       if 
( ledTmp )
           break;
       // Pause finie, on decremente le compteur de flash et on repart en 12
       ledFlashNumber--;
       ledCyc = 12;
             break;

   default : // Y'a un bin's !!
       ledCyc = 0;
       break;
    }
}

Cdt.
Marcus.
E85 PIC16F887-NANO-Modif-INTER.pdf
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 45 invités