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 ---
- 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
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour à tous,
Voila plusieurs jours que je cherche, modifie et tourne en rond sur un problème de timing.
Quelques chose doit m'échapper car j'ai bout tourner dans tous les sens je ne trouve pas de solutions mais surtout je ne vois même pas d'où ca peut venir.
Le contexte :
Il s'agit de la carte qui va gérer mon arrosage et un projecteur. cette carte sera dans mon local jardin. j'ai fais le même principe que pour mes stores bannes, à savoir, que la carte rentre en veille 2secondes ( le temps du watchdog) et se réveille pendant 300 ms pour écouter si un signal est reçu . Comme j'ai simplifier au maximum le programme pour trouver le bug je m’arrêterais la pour les explications et ne pas vous embrouiller.
Pour le moment la carte ne fait que passer en veille mais déjà la ça coince.
Afin de vérifier qu'il n'y ai pas de RESET du pic par faute d'alimentation ou autre, je fais clignoter rapidement une led verte au démarrage. aucun RESET du PIC à déclarer.
Je précise que la fréquence est de 500 Khz, j'ai pas besoin de vitesse et surtout je consomme beaucoup moins. je n'ai pas rencontrer de problème particulier avec l'UART à cette vitesse. de toute façon ici l'UART ne rentre pas en compte.
Mes timers sont testés et fonctionnent parfaitement !
Le principe est le suivant dans la boucle infinie :
- je surveille le drapeau F_Sleep qui doit m'indiquer que je dois rentrer en veille. Ce drapeau est levé par le timer0 toutes les 300ms.
- Une fois le drapeau levé je rentre dans la routine d’extinction
- j''éteins la led rouge qui est mon signal à observer à l'oscillo
- j'éteins tous les interruptions
- J'active le watchdog configurer sur 2s en début
- Je rentre en veille. le watchdog me sort de la veille au bout de 2s .
En sortie de veille
- j’éteins le watchdog
- je réveil mon module radio avec une impulsion sur sa broche wake-up.
- Je réinitialise le timer 0, je le lance
- j'allume la led rouge
- et je réactive les interruptions. Comme le timer 0 est activé je vais donc rester allumé pendant la durée du timer 0 soit 300ms
Donc pour moi la led rouge devrait s'allumer pendant 300ms à peu prêt ( + quelques lignes)
Le problème :
Dans 90% des cas elle s'allume bien pendant 300ms à l'oscillo, mais parfois il y a des ratés !!!!
je n'ai pas réussis à trouver une cohérence avec ces ratés. des fois l'impulsions ne dure que 150ms et des fois 600ms, voir 600ms plus une rapide impulsion à zéro(40ms) et re 300ms .
Ma question est qu'est ce qui pourrait générer ces erreurs dans les timings !
Tous n'est pas utilisé dan le programme cetaines focntion sont absentes !
Ci joint une photo du genre de problème.
Voila plusieurs jours que je cherche, modifie et tourne en rond sur un problème de timing.
Quelques chose doit m'échapper car j'ai bout tourner dans tous les sens je ne trouve pas de solutions mais surtout je ne vois même pas d'où ca peut venir.
Le contexte :
Il s'agit de la carte qui va gérer mon arrosage et un projecteur. cette carte sera dans mon local jardin. j'ai fais le même principe que pour mes stores bannes, à savoir, que la carte rentre en veille 2secondes ( le temps du watchdog) et se réveille pendant 300 ms pour écouter si un signal est reçu . Comme j'ai simplifier au maximum le programme pour trouver le bug je m’arrêterais la pour les explications et ne pas vous embrouiller.
Pour le moment la carte ne fait que passer en veille mais déjà la ça coince.
Afin de vérifier qu'il n'y ai pas de RESET du pic par faute d'alimentation ou autre, je fais clignoter rapidement une led verte au démarrage. aucun RESET du PIC à déclarer.
Je précise que la fréquence est de 500 Khz, j'ai pas besoin de vitesse et surtout je consomme beaucoup moins. je n'ai pas rencontrer de problème particulier avec l'UART à cette vitesse. de toute façon ici l'UART ne rentre pas en compte.
Mes timers sont testés et fonctionnent parfaitement !
Le principe est le suivant dans la boucle infinie :
- je surveille le drapeau F_Sleep qui doit m'indiquer que je dois rentrer en veille. Ce drapeau est levé par le timer0 toutes les 300ms.
- Une fois le drapeau levé je rentre dans la routine d’extinction
- j''éteins la led rouge qui est mon signal à observer à l'oscillo
- j'éteins tous les interruptions
- J'active le watchdog configurer sur 2s en début
- Je rentre en veille. le watchdog me sort de la veille au bout de 2s .
En sortie de veille
- j’éteins le watchdog
- je réveil mon module radio avec une impulsion sur sa broche wake-up.
- Je réinitialise le timer 0, je le lance
- j'allume la led rouge
- et je réactive les interruptions. Comme le timer 0 est activé je vais donc rester allumé pendant la durée du timer 0 soit 300ms
Donc pour moi la led rouge devrait s'allumer pendant 300ms à peu prêt ( + quelques lignes)
Le problème :
Dans 90% des cas elle s'allume bien pendant 300ms à l'oscillo, mais parfois il y a des ratés !!!!
je n'ai pas réussis à trouver une cohérence avec ces ratés. des fois l'impulsions ne dure que 150ms et des fois 600ms, voir 600ms plus une rapide impulsion à zéro(40ms) et re 300ms .
Ma question est qu'est ce qui pourrait générer ces erreurs dans les timings !
Tous n'est pas utilisé dan le programme cetaines focntion sont absentes !
Code : Tout sélectionner
/*
08/09/21
DS : PIC16F1825 : http://ww1.microchip.com/downloads/en/devicedoc/41440a.pdf
DS : AMB8220 : https://www.we-online.de/katalog/manual/2603011021000_Triton%202603011x2100x%20Manual_rev1.pdf
le module se reveille toutes les 2 secondes (watchdog) et reste allumé pendant 300ms ( TMR0 )
Dès la premiere donnée recue par voir radio il reste allumé tant qu'il recoit une ligne de vie
A l'allumage de l'ecran , l'ecran envoie des données toutes les 100ms pendant 3 secondes ensuite il passe une LDV / seconde
Quand il ne recoit plus de ligne de vis il attend 3 secondes et repasse en veille
Si un relais est activé il reste activer maximum 48 secondes
*/
//#############################################################################
//---------------------------- INCLUDES ---------------------------
#include "Ordre_define.h"
#define LED_R LATA0_bit
#define LED_V LATA1_bit
#define Projo LATA2_bit
#define BP PORTA.B3
#define AMB_WUP LATA4_bit
#define AMB_RST LATA5_bit
#define Sens_GaG LATC0_bit
#define Pulse_GaG LATC1_bit
#define Sens_arr LATC2_bit
#define Pulse_arr LATC3_bit
//############################## VARIABLES ################################################
unsigned int i=0,CPT_100ms=0, CPT_10ms=0, Compteur_relais;
unsigned char F_LdV=0, RSSI=0;
//-------- UART
unsigned char tmp=0, Valeur=0 ;
char Parametre_OK=0, DATA=0, F_DATA_OK=0, F_Sleep_OK=0;
char F_Sleep;
//############################## PROTOTYPES ###############################################
void Sleep_mode_on();
void Sleep_mode_off();
void Conf_AMB8220();
//##############################################################################
//----------------------- INTERRUPTION -----------------------------
void interrupt(){
if (TMR0IF_bit){ // Determine le temps d'allumage du circuit : 300ms
TMR0IF_bit = 0;
TMR0 = 61;
CPT_100ms++;
F_Sleep = 0;
if (CPT_100ms>=3){
CPT_100ms=0 ;
F_Sleep = 1 ;
}
}
if (TMR1IF_bit){ // Determine la durée maximum d'allumage des relais
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
Compteur_relais++;
if (Compteur_relais >= 48 ){
Compteur_relais = 0 ;
TMR1IE_bit = 0; // j'éteins le TIMER
}
}
if (TMR2IF_bit){
TMR2IF_bit = 0;
if (TMR1IE_bit == 0) CPT_10ms++;
F_Sleep = 0;
if (CPT_10ms >= 300){
CPT_10ms = 0;
TMR0IE_bit = 1;
F_Sleep = 1 ;
}
}
//----------------------- UART -----------------------------
if (RCIF_bit == 1) {
tmp = UART1_Read(); // On récupere et stock la donnée
switch (Valeur){
case 0: if (tmp == 0x02){ // Start signal
Valeur = 1;
}
else
Valeur = 0;
break;
// Numéro de la commande recue
case 1: if (tmp == 0x49) // Parametre OK
Valeur = 2;
else if (tmp == 0x81) // Validation d'un envoi
Valeur = 10;
else if (tmp == 0x68) // reponse d'une demande de sleep
Valeur = 20;
else
Valeur = 0;
break;
case 2: if (tmp == 0x01) // Nombre bytes
Valeur = 3;
else{
Valeur = 0;
}
break;
case 3: if (tmp == 0x00) //status
Valeur = 4;
else{Valeur = 0;}
break;
case 4: if (tmp == 0x4A){ // checksum 0x02 0x49 0x01 0x00 0x4A
Parametre_OK = 1; // Je léve le FLAG
}
Valeur = 0;
break;
case 10: if (tmp == 0x03) //lenght
Valeur = 11;
else Valeur = 0;
break;
case 11: if (tmp == 0x01) //adress source, 01=ecran
Valeur = 12;
else{Valeur = 0;}
break;
case 12: DATA = tmp ; // j'enregistre les données recues
Valeur = 13;
break;
case 13: RSSI = tmp ; //RSSI
Valeur = 14;
break;
case 14: if (tmp == 0x81^DATA^RSSI){
F_DATA_OK = 1; //DATA recues et valides
}
Valeur = 0;
break;
case 20: if (tmp == 0x01) //sleep
Valeur = 21;
else {Valeur = 0;}
break;
case 21: if (tmp == 0x01) //sleep
Valeur = 22;
else {Valeur = 0;}
break;
case 22: if (tmp == 0x6A){ //sleep
F_Sleep_OK = 1;
}
Valeur = 0;
break;
}
}
}
/*#################################################################################################
################################ MAIN #######################################
#################################################################################################*/
void main() {
ANSELA = ANSELC = 0x00; // Tout en numérique
TRISA = 0b11001000; // en sortie: AMB_RST, AMB_WUP, LED_R, LED_V et Projecteur
TRISC = 0b11100000; // En entrée: RX UART
//******* OSCILLATEUR ******
OSCCON = 0b00111010 ; // PLL disable ; MF 500 Khz ; internal OSC
AMB_RST = 1;
AMB_WUP = 1;
//-------------------------- INTERUPT. TIMER0 : 100ms ---------------------------------
OPTION_REG = 0x85; // Prescaler 1:64; pullup dés-actived p.189
TMR0 = 61; // TMR0 Preload = 61
TMR0IE_bit = 0 ; // p.93
TMR0IF_bit = 0; // p.93
//-------------------------- INTERUPT. TIMER1 : 1s ---------------------------------
T1CON = 0x11; //Prescaler 1:2; timer1=ON ; p.197
TMR1H = 0x0B; // TMR1 Preload = 3036
TMR1L = 0xDC;
TMR1IF_bit = 0;
TMR1IE_bit = 0;
//-------------------------- INTERUPT. TIMER2 : 10ms ---------------------------------
T2CON = 0x24; // Prescaler 1:1; Postscaler 1:5;
PR2 = 249; // TMR2 Preload = 249;
TMR2IF_bit = 0;
TMR2IE_bit = 0;
//------------------------------ INTERUPT. UART -------------------------------------
PEIE_bit = 1; // Active les INT peripherique p.93
RCIE_bit = 1; // Active les Interruptions sur Rx UART p.94
RCIF_bit = 0; // RAZ flag p.98
//******* UART ******
UART1_Init(9600);
//******* WATCHDOG ******
WDTCON = 0b00010110 ; // timer period=2s ; SWDTEN=0 p.107
//------------------------------- INTERRUPTION ----------------------------------------
GIE_bit = 1; // Active toutes les INT p.93
CPT_100ms = CPT_10ms = 0;
F_Sleep = 1;
delay_ms(100);
for (i=0;i<=5 ;i++){
LED_V = 1;
delay_ms(50);
LED_V = 0;
delay_ms(50);
}
TMR2IE_bit = 1;
LED_R = 1;
/*#################################################################################################
################################ BOUCLE PRINCIPALE #######################################
#################################################################################################*/
while (1){
// Mise en veille par le TIMER 0
if (F_Sleep == 1){ // C'est l'heure de dormir
F_Sleep = 0;
LED_R = 0;
//Sleep_mode_on(); // je met le module radio en veille avant d'eteindre les INT
GIE_bit = 0; // j'eteins les int
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm CLRWDT ;
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
SWDTEN_bit = 0; // Je désactive le watchdog
delay_ms(2);
//Sleep_mode_off(); // Je réveil le module radio
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = Valeur = 0;
TMR0IE_bit = 1 ;
LED_R = 1;
GIE_bit = 1;
}
// reception d'une donnée
if (F_DATA_OK == 1){
F_DATA_OK =0; // raz flag
TMR0IE_bit = 0; // J'arrete la mise en veille
TMR0 = 61;
CPT_100ms = 0 ;
CPT_10ms = 0;
switch (DATA){
case Reveil : TMR2IE_bit = 1; LED_V=~LED_V; break; // je recois une ligne de vie, je raz le comtpeur
default: asm nop;
}
}
}
}
/*#################################################################################################
################################ PROGRAMME SECONDAIRE ####################################
#################################################################################################*/
void Sleep_mode_on(){
// Cette fonction fait renter le module radio en LPM. j'attends la réponse 3 fois aprés je sors pour ne pas bloquer
// rentrer en LPM ( Low Power Mode)
// envoie en hexa (02 28 01 01 2A)
// Response (02 68 01 01 6A)
char CPT_LOC=0;
do{
UART1_Write(0x02); // Start
UART1_Write(0x28); // Commande
UART1_Write(0x01); // Lenght
UART1_Write(0x01); // LPM
UART1_Write(0x2A); // CS
delay_ms(50);
CPT_LOC++;
if (CPT_LOC >= 3) break;
}while (F_Sleep_OK == 0);// Attente de la réponse
F_Sleep_OK = 0; // RAZ flag
}
//----- Cette fonction sort le module radio de la veille
void Sleep_mode_off(){
AMB_WUP = 0;
delay_ms(20);
AMB_WUP = 1;
delay_ms(10);
}
Ci joint une photo du genre de problème.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
watchdog et timer
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour Satinas,
Je suis pas sur d'avoir compris ta question.
Dans la configuration projet :
CONFIG1 : $8007 : 0x3FAC
CONFIG2 : $8008 : 0x1613
Le watchdog est reglé sur controlled by SWDTEN ... voir la photo ci jointe.
Dans le programme la valeur est :
Pense ce tempsje continue mes investigations.
Quand je supprime les focntions Sleep_mode_on(); et Sleep_mode_off(); je n'ai aucun bug de timing.
Du coup j'ai l'impression que ce la viens du module radio et/ou de 'l'UART qui interfererai avec le watchdog.
En fait quand j'endors le module radio en lui envoyant la commande (0x02 0x28 0x01 0x01 0x2A) celui-ci me répond par "02 68 01 01 6A" en hexa . dnas mon code précedent je traitais cette réponse avant de continuer. c'est pour cela que j'éteignais les interruptions apres le paasage du module en veille.
Par contre je ne traitais pas le retour de veille.
Quand je fais sortir le module radio de veille en appliquant un état bas sa sa broche Wake-up, celui m'envoie un message quand il est réveillé. Il m’envoie "02 C0 01 00 C3". Maintenant je le traite avant de continuer mon programme.
Je n'ai plus de bug à 600ms , mais par contre j'ai toujours des bugs de durée raccourci à 200ms.
J'ai l’impression que les temps sont divisés par 2 ou multipliés par deux. C'est bizarre !
Voici mon nouveau code de test avec le traitement de la sortie de veille par l'UART.
Je suis pas sur d'avoir compris ta question.
Dans la configuration projet :
CONFIG1 : $8007 : 0x3FAC
CONFIG2 : $8008 : 0x1613
Le watchdog est reglé sur controlled by SWDTEN ... voir la photo ci jointe.
Dans le programme la valeur est :
Code : Tout sélectionner
//******* WATCHDOG ******
WDTCON = 0b00010110 ; // timer period=2s ; SWDTEN=0 p.107
Pense ce tempsje continue mes investigations.
Quand je supprime les focntions Sleep_mode_on(); et Sleep_mode_off(); je n'ai aucun bug de timing.
Du coup j'ai l'impression que ce la viens du module radio et/ou de 'l'UART qui interfererai avec le watchdog.
En fait quand j'endors le module radio en lui envoyant la commande (0x02 0x28 0x01 0x01 0x2A) celui-ci me répond par "02 68 01 01 6A" en hexa . dnas mon code précedent je traitais cette réponse avant de continuer. c'est pour cela que j'éteignais les interruptions apres le paasage du module en veille.
Par contre je ne traitais pas le retour de veille.
Quand je fais sortir le module radio de veille en appliquant un état bas sa sa broche Wake-up, celui m'envoie un message quand il est réveillé. Il m’envoie "02 C0 01 00 C3". Maintenant je le traite avant de continuer mon programme.
Je n'ai plus de bug à 600ms , mais par contre j'ai toujours des bugs de durée raccourci à 200ms.
J'ai l’impression que les temps sont divisés par 2 ou multipliés par deux. C'est bizarre !
Voici mon nouveau code de test avec le traitement de la sortie de veille par l'UART.
Code : Tout sélectionner
/*
09/09/21
DS : PIC16F1825 : http://ww1.microchip.com/downloads/en/devicedoc/41440a.pdf
DS : AMB8220 : https://www.we-online.de/katalog/manual/2603011021000_Triton%202603011x2100x%20Manual_rev1.pdf
le module se reveille toutes les 2 secondes (watchdog) et reste allumé pendant 300ms ( TMR0 )
Dès la premiere donnée recue par voir radio il reste allumé tant qu'il recoit une ligne de vie
A l'allumage de l'ecran , l'ecran envoie des données toutes les 100ms pendant 3 secondes ensuite il passe une LDV / seconde
Quand il ne recoit plus de ligne de vis il attend 3 secondes et repasse en veille
Si un relais est activé il reste activer maximum 48 secondes
*/
//#############################################################################
//---------------------------- INCLUDES ---------------------------
#include "Ordre_define.h"
#define LED_R LATA0_bit
#define LED_V LATA1_bit
#define Projo LATA2_bit
#define BP PORTA.B3
#define AMB_WUP LATA4_bit
#define AMB_RST LATA5_bit
#define Sens_GaG LATC0_bit
#define Pulse_GaG LATC1_bit
#define Sens_arr LATC2_bit
#define Pulse_arr LATC3_bit
//############################## VARIABLES ################################################
unsigned int i=0,CPT_100ms=0, CPT_10ms=0, Compteur_relais;
unsigned char F_LdV=0, RSSI=0;
//-------- UART
unsigned char tmp=0, Valeur=0 ;
char Parametre_OK=0, DATA=0, F_DATA_OK=0, F_Sleep_OK=0, F_Reveil_OK=0;
char F_Sleep;
//############################## PROTOTYPES ###############################################
void Sleep_mode_on();
void Sleep_mode_off();
void Conf_AMB8220();
//##############################################################################
//----------------------- INTERRUPTION -----------------------------
void interrupt(){
if (TMR0IF_bit){ // Determine le temps d'allumage du circuit : 300ms
TMR0IF_bit = 0;
TMR0 = 61;
CPT_100ms++;
F_Sleep = 0;
if (CPT_100ms>=3){
CPT_100ms=0 ;
F_Sleep = 1 ;
}
}
if (TMR1IF_bit){ // Determine la durée maximum d'allumage des relais
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
Compteur_relais++;
if (Compteur_relais >= 48 ){
Compteur_relais = 0 ;
TMR1IE_bit = 0; // j'éteins le TIMER
}
}
if (TMR2IF_bit){
TMR2IF_bit = 0;
if (TMR1IE_bit == 0) CPT_10ms++;
F_Sleep = 0;
if (CPT_10ms >= 300){
CPT_10ms = 0;
TMR0IE_bit = 1;
F_Sleep = 1 ;
}
}
//----------------------- UART -----------------------------
if (RCIF_bit == 1) {
tmp = UART1_Read(); // On récupere et stock la donnée
switch (Valeur){
case 0: if (tmp == 0x02){ // Start signal
Valeur = 1;
}
else
Valeur = 0;
break;
// Numéro de la commande recue
case 1: if (tmp == 0x49) // Parametre OK
Valeur = 2;
else if (tmp == 0x81) // Validation d'un envoi
Valeur = 10;
else if (tmp == 0x68) // reponse d'une demande de sleep
Valeur = 20;
else if (tmp == 0xC0) // reponse d'une sortie de sleep
Valeur = 30;
else
Valeur = 0;
break;
case 2: if (tmp == 0x01) // Nombre bytes
Valeur = 3;
else{
Valeur = 0;
}
break;
case 3: if (tmp == 0x00) //status
Valeur = 4;
else{Valeur = 0;}
break;
case 4: if (tmp == 0x4A){ // checksum 0x02 0x49 0x01 0x00 0x4A
Parametre_OK = 1; // Je léve le FLAG
}
Valeur = 0;
break;
case 10: if (tmp == 0x03) //lenght
Valeur = 11;
else Valeur = 0;
break;
case 11: if (tmp == 0x01) //adress source, 01=ecran
Valeur = 12;
else{Valeur = 0;}
break;
case 12: DATA = tmp ; // j'enregistre les données recues
Valeur = 13;
break;
case 13: RSSI = tmp ; //RSSI
Valeur = 14;
break;
case 14: if (tmp == 0x81^DATA^RSSI){
F_DATA_OK = 1; //DATA recues et valides
}
Valeur = 0;
break;
case 20: if (tmp == 0x01) //sleep
Valeur = 21;
else {Valeur = 0;}
break;
case 21: if (tmp == 0x01) //sleep
Valeur = 22;
else {Valeur = 0;}
break;
case 22: if (tmp == 0x6A){ //sleep
F_Sleep_OK = 1;
}
Valeur = 0;
break;
// réponse aprés un reveil par la broche wake-up
case 30: if (tmp == 0x01){ Valeur = 31; } else { Valeur = 0; } break;
case 31: if (tmp == 0x00){ Valeur = 32; } else { Valeur = 0; } break;
case 32: if (tmp == 0xC3){ F_Reveil_OK = 1; } Valeur = 0; break;
}
}
}
/*#################################################################################################
################################ MAIN #######################################
#################################################################################################*/
void main() {
ANSELA = ANSELC = 0x00; // Tout en numérique
TRISA = 0b11001000; // en sortie: AMB_RST, AMB_WUP, LED_R, LED_V et Projecteur
TRISC = 0b11100000; // En entrée: RX UART
//******* OSCILLATEUR ******
OSCCON = 0b00111010 ; // PLL disable ; MF 500 Khz ; internal OSC
AMB_RST = 1;
AMB_WUP = 1;
//-------------------------- INTERUPT. TIMER0 : 100ms ---------------------------------
OPTION_REG = 0x85; // Prescaler 1:64; pullup dés-actived p.189
TMR0 = 61; // TMR0 Preload = 61
TMR0IE_bit = 0 ; // p.93
TMR0IF_bit = 0; // p.93
//-------------------------- INTERUPT. TIMER1 : 1s ---------------------------------
T1CON = 0x11; //Prescaler 1:2; timer1=ON ; p.197
TMR1H = 0x0B; // TMR1 Preload = 3036
TMR1L = 0xDC;
TMR1IF_bit = 0;
TMR1IE_bit = 0;
//-------------------------- INTERUPT. TIMER2 : 10ms ---------------------------------
T2CON = 0x24; // Prescaler 1:1; Postscaler 1:5;
PR2 = 249; // TMR2 Preload = 249;
TMR2IF_bit = 0;
TMR2IE_bit = 0;
//------------------------------ INTERUPT. UART -------------------------------------
PEIE_bit = 1; // Active les INT peripherique p.93
RCIE_bit = 1; // Active les Interruptions sur Rx UART p.94
RCIF_bit = 0; // RAZ flag p.98
//******* UART ******
UART1_Init(9600);
//******* WATCHDOG ******
WDTCON = 0b00010110 ; // timer period=2s ; SWDTEN=0 p.107
//------------------------------- INTERRUPTION ----------------------------------------
GIE_bit = 1; // Active toutes les INT p.93
CPT_100ms = CPT_10ms = 0;
F_Sleep = 1;
delay_ms(100);
for (i=0;i<=5 ;i++){
LED_V = 1;
delay_ms(50);
LED_V = 0;
delay_ms(50);
}
TMR2IE_bit = 1;
LED_R = 1;
/*#################################################################################################
################################ BOUCLE PRINCIPALE #######################################
#################################################################################################*/
while (1){
// Mise en veille par le TIMER 0
if (F_Sleep == 1){ // C'est l'heure de dormir
F_Sleep = 0;
Sleep_mode_on(); // je met le module radio en veille avant d'eteindre les INT
LED_R = 0;
GIE_bit = 0; // j'eteins les int
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm CLRWDT ;
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
SWDTEN_bit = 0; // Je désactive le watchdog
GIE_bit = 1;
delay_ms(1);
Sleep_mode_off(); // Je réveil le module radio
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = 0;
TMR0IE_bit = 1 ;
LED_R = 1;
}
/*
// reception d'une donnée
if (F_DATA_OK == 1){
F_DATA_OK =0; // raz flag
TMR0IE_bit = 0; // J'arrete la mise en veille
TMR0 = 61;
CPT_100ms = 0 ;
CPT_10ms = 0;
switch (DATA){
case Reveil : TMR2IE_bit = 1; LED_V=~LED_V; break; // je recois une ligne de vie, je raz le comtpeur
default: asm nop;
}
}
*/
}
}
/*#################################################################################################
################################ PROGRAMME SECONDAIRE ####################################
#################################################################################################*/
void Sleep_mode_on(){
// Cette fonction fait renter le module radio en LPM. j'attends la réponse 3 fois aprés je sors pour ne pas bloquer
// rentrer en LPM ( Low Power Mode)
// envoie en hexa (02 28 01 01 2A)
// Response (02 68 01 01 6A)
char CPT_LOC=0;
do{
UART1_Write(0x02); // Start
UART1_Write(0x28); // Commande
UART1_Write(0x01); // Lenght
UART1_Write(0x01); // LPM
UART1_Write(0x2A); // CS
delay_ms(100);
CPT_LOC++;
if (CPT_LOC >= 3) break;
}while (F_Sleep_OK == 0);// Attente de la réponse
F_Sleep_OK = 0; // RAZ flag
}
//----- Cette fonction sort le module radio de la veille
void Sleep_mode_off(){
AMB_WUP = 0;
delay_ms(20);
AMB_WUP = 1;
while ( F_Reveil_OK == 0);
F_Reveil_OK = 0;
}
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Voici un exemple peut etre plus clair, car je suis conscient que ce ne doit pas être évident de m'aider.
Voici une portion de code ou j'ai déplacé la mesure du temps..
J'ai donc placé la mesure pile poil à la sortie du watchdog ( LED_R = 1) et je ferme la mesure quand je rentre dans la fonction de mise en veille ( meme un peu apres car j'execute la fonction Sleep_mode_on(); ).
C'est la ou s’arrête ma compréhension. En tout état de cause, c'est fonction est gérée par le timer 0 qui est réglé sur 300ms. je ne peux donc pas rentrée dans cette fonction avant, c'est IMPOSSIBLE !!!!
et pour tant voici un exemple :
J'ai donc une impulsion de 270ms ????? alors que c'est impossible d'être inférieur à 300ms qui le temps du timer0
Je suis perdu !!!!
Voici une portion de code ou j'ai déplacé la mesure du temps..
Code : Tout sélectionner
if (F_Sleep == 1){ // C'est l'heure de dormir
F_Sleep = 0;
Sleep_mode_on(); // je met le module radio en veille avant d'eteindre les INT
LED_R = 0;
GIE_bit = 0; // j'eteins les int
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm CLRWDT ;
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
SWDTEN_bit = 0; // Je désactive le watchdog
LED_R = 1;
GIE_bit = 1;
delay_ms(1);
Sleep_mode_off(); // Je réveil le module radio
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = 0;
TMR0IE_bit = 1 ;
}
J'ai donc placé la mesure pile poil à la sortie du watchdog ( LED_R = 1) et je ferme la mesure quand je rentre dans la fonction de mise en veille ( meme un peu apres car j'execute la fonction Sleep_mode_on(); ).
C'est la ou s’arrête ma compréhension. En tout état de cause, c'est fonction est gérée par le timer 0 qui est réglé sur 300ms. je ne peux donc pas rentrée dans cette fonction avant, c'est IMPOSSIBLE !!!!
et pour tant voici un exemple :
J'ai donc une impulsion de 270ms ????? alors que c'est impossible d'être inférieur à 300ms qui le temps du timer0
Je suis perdu !!!!
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
watchdog et timer
L'entrée et la sortie du mode sleep déclenche le reset auto du watchdog.
Commence avec un programme ultra simple avec SWDTEN_bit restant à 1, pas de flag.
Le programme boucle, sleep, 2s de watchdog, sortie et tempo par delay() de 300ms.
Ensuite tu ajoutes le module radio, si possible sans timer.
Après tu ajoutes les timers, et pourquoi ces TMR0IE_bit = 0, c'est assez compliqué comme ça, le timer on peut l'arrêter.
Commence avec un programme ultra simple avec SWDTEN_bit restant à 1, pas de flag.
Le programme boucle, sleep, 2s de watchdog, sortie et tempo par delay() de 300ms.
Ensuite tu ajoutes le module radio, si possible sans timer.
Après tu ajoutes les timers, et pourquoi ces TMR0IE_bit = 0, c'est assez compliqué comme ça, le timer on peut l'arrêter.
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
satinas a écrit :Source du message Commence avec un programme ultra simple avec SWDTEN_bit restant à 1, pas de flag.
Code : Tout sélectionner
while (1){
LED_R = 0;
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
SWDTEN_bit = 0; // Je désactive le watchdog
LED_R = 1;
delay_ms(300);
}
Après tu ajoutes les timers, et pourquoi ces TMR0IE_bit = 0, c'est assez compliqué comme ça, le timer on peut l'arrêter.
C'est vrai que j'ai pris la mauvaise habitude d’arrêter mon traitement timer en arrêtant les intéruptions lié a ce timer, ce qui en soi, n'arrete pas le timer mais seulement ces interruptions .
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
watchdog et timer
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Après 5 bonne minutes a regarder mon oscillo je n'ai plus eu de bug. comme sur al photo en #6 !!!
Peut etre du à ma sonde d'oscillo ou un parasite ou un extraterrestre lol, mais je n'ai pas de bug avec cette fonction simple.
Pour infos j'avais essayé mon programme sans utilisé le SWDTEN_bit . En laissant activer le WDT en permanence et en le resetant dans le programme par des " asm CLRWDT" , le résultat était le même.
Peut etre du à ma sonde d'oscillo ou un parasite ou un extraterrestre lol, mais je n'ai pas de bug avec cette fonction simple.
Pour infos j'avais essayé mon programme sans utilisé le SWDTEN_bit . En laissant activer le WDT en permanence et en le resetant dans le programme par des " asm CLRWDT" , le résultat était le même.
watchdog et timer
Je sais pas d'où vient le problème, je dis juste qu'on peut le laisser à 1 si la période d'activité ne dépasse jamais 2s, et on n'a pas à resetter le watchdog, le mode sleep s'en charge.
When the device enters Sleep, the WDT is cleared. When the device e xits Sleep, the WDT is cleared again
Si tu écartes une erreur, elle te reviendra sous une autre forme.
Ou alors du mets un compteur d'erreurs, que tu affiches, j'ai cru vois passer un lcd.
When the device enters Sleep, the WDT is cleared. When the device e xits Sleep, the WDT is cleared again
Si tu écartes une erreur, elle te reviendra sous une autre forme.
Code : Tout sélectionner
char CPT_LOC=0;
do {
...
delay_ms(50);
CPT_LOC++;
if (CPT_LOC >= 3) break;
} while (F_Sleep_OK == 0); // Attente de la réponse
F_Sleep_OK = 0; // RAZ flag
Ou alors du mets un compteur d'erreurs, que tu affiches, j'ai cru vois passer un lcd.
Modifié en dernier par satinas le mer. 8 sept. 2021 16:48, modifié 1 fois.
watchdog et timer
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
bon on peut considérer que le watchdog fonctionne comme il faut
J'avance doucement donc. Je remplace le delay de 300ms par le timer0 ( après vérification, apparemment ce timer ne peut pas s'arrêter sur ce pic)
avec cette fonction aucun bug non plus :
J'avance doucement donc. Je remplace le delay de 300ms par le timer0 ( après vérification, apparemment ce timer ne peut pas s'arrêter sur ce pic)
avec cette fonction aucun bug non plus :
Code : Tout sélectionner
if (F_Sleep == 1){ // C'est l'heure de dormir
F_Sleep = 0;
TMR0IE_bit = 0 ;
LED_R = 0;
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
SWDTEN_bit = 0; // Je désactive le watchdog
LED_R = 1;
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = 0 ;
TMR0IE_bit = 1 ;
}
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 17 invités