- 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 ---
Modérateur : Jérémy
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
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 ?
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
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.
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(char* st_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;
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
}
Code : Tout sélectionner
float ds1820_read()
{
int busy=0, temp1, temp2;
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(temp2, temp1);
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
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_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);
}
/*********************** 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=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.
}
}
/*********************** 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 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 );
}
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;
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.
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.
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.
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 28 invités