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
Mode Sleep 12F1840 pour reduire la conso
- paulfjujo
Expert- Messages : 2589
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour à tous,
J'utilise un petit (mais costaud) PIC 12F1840 pour faire l'acquisition d'une sonde de temperature OWS 18B20
et envoyer cette info sur un terminal dans un premier temps
.. via bluetooth dans un second temps !
Le montage est alimenté en 3,3V et je compte utiliser une pile plate 4,5V (ou 3 piles 1,5V) + regulateur ASM117 3,3
pour alimenter le tout
et utiliser le mode sleep sur commande .. via équipement distant pour envoyer la commande SLEEP ou WAKEUP
pour recup de l'info sur demande et reduction de conso si pas besoin.
en mode sleep conso < 15µA
en mode normal conso < 1,15mA
le probleme est du coté reveil
ma commande WAKEUP ne passe qu'au bout de la 3em fois et je recupere dans les 2 premieres fois du "garbage"
l'UART est censé reveiller le PIC des le premier caractere qui devrait etre un BREAK code 00
mais dans la pratique il se reveille avec n'importe quel car reçu..
d'ou l'envoi de "WAKEUP<CR>"
sorti du mode sleep si au moins 1 car recu
delay pour laisser passer les autres car jusqu'au <CR>
si detection du CR , examen du buffer
si message WAKEUP je reveille le PIC , sinon je le rendors ..
nota: sans l'usage du SLEEP , je n'ai AUCUN probleme sur la reception des commandes SLEEP et WAKEUP
il me semble que l'usage de asm sleep dans une condition if .. pose probleme ..
car le retour apres le sleep n'est pas dans le corps principal du programmme ,...est encore dans le if
Votre avis ?
Indice j= 1656 ; DS18B20#1 Temper.Amb.= 18,2500
Indice j= 1657 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1658 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1659 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•þ 1660 ; DS18B20#1 Temper.Amb.= 18,5625 <- 1eree tentative de reveil BAD
U-UA5
q‘¥•þ 1661 ; DS18B20#1 Temper.Amb.= 18,5625 <- 2eme tentative de reveil BAD
U-UA5
WAKEUP <- 3eme tentative de reveil OK
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1662 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1663 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1664 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1665 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1666 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•þ 1667 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5
q‘¥•þ 1668 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5
WAKEUP
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1669 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1670 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1671 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1672 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1673 ; DS18B20#1 Temper.Amb.= 18,5625
le hardware:
le code :
J'utilise un petit (mais costaud) PIC 12F1840 pour faire l'acquisition d'une sonde de temperature OWS 18B20
et envoyer cette info sur un terminal dans un premier temps
.. via bluetooth dans un second temps !
Le montage est alimenté en 3,3V et je compte utiliser une pile plate 4,5V (ou 3 piles 1,5V) + regulateur ASM117 3,3
pour alimenter le tout
et utiliser le mode sleep sur commande .. via équipement distant pour envoyer la commande SLEEP ou WAKEUP
pour recup de l'info sur demande et reduction de conso si pas besoin.
en mode sleep conso < 15µA
en mode normal conso < 1,15mA
le probleme est du coté reveil
ma commande WAKEUP ne passe qu'au bout de la 3em fois et je recupere dans les 2 premieres fois du "garbage"
l'UART est censé reveiller le PIC des le premier caractere qui devrait etre un BREAK code 00
mais dans la pratique il se reveille avec n'importe quel car reçu..
d'ou l'envoi de "WAKEUP<CR>"
sorti du mode sleep si au moins 1 car recu
delay pour laisser passer les autres car jusqu'au <CR>
si detection du CR , examen du buffer
si message WAKEUP je reveille le PIC , sinon je le rendors ..
nota: sans l'usage du SLEEP , je n'ai AUCUN probleme sur la reception des commandes SLEEP et WAKEUP
il me semble que l'usage de asm sleep dans une condition if .. pose probleme ..
car le retour apres le sleep n'est pas dans le corps principal du programmme ,...est encore dans le if
Votre avis ?
Indice j= 1656 ; DS18B20#1 Temper.Amb.= 18,2500
Indice j= 1657 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1658 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1659 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•þ 1660 ; DS18B20#1 Temper.Amb.= 18,5625 <- 1eree tentative de reveil BAD
U-UA5
q‘¥•þ 1661 ; DS18B20#1 Temper.Amb.= 18,5625 <- 2eme tentative de reveil BAD
U-UA5
WAKEUP <- 3eme tentative de reveil OK
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1662 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1663 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1664 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1665 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1666 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•þ 1667 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5
q‘¥•þ 1668 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5
WAKEUP
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1669 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1670 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1671 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1672 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1673 ; DS18B20#1 Temper.Amb.= 18,5625
le hardware:
le code :
Code : Tout sélectionner
// ATTENTION : deconnecté le signal OWS sonde DS18B20 de RA0 =ICSP DATA pour programmer avec Pickit2
#define Version "170202"
#define AVEC_MODE_SLEEP
/// modef : mise en mode sleep sur reception cde "SLEEP"
//#define Version "170202"
#define Langage "MikroC 7.0.0"
#define Directory "C:\\_MikroC\\_MesProjets_MikroC\\_12F1840_Sleep"
#define Projet "12F1840_Sleep_Temper_DS18B20_WakeUpbyUart_2017.mcppi"
#define Source "_12F1840_Sleep_WakeUpOnUartBreak_DS18B20_Test" // sans extension !
#define MCU "12F1840 DIP8"
#define POWER_SUPPLY "3,3V" // (3,3 to 4,2V battery)
#define OSCILLATEUR_INTERNE
#define FOSC 8MHZ
#define EEPROM_FILE "xxx_Eeprom.ihex"
// deconnecter l'ICSP pour reduire la conso.
// nota : necessite de rajouter des delais sur les UART Write ??
// probalement à cause de la remise en route oscillateur ??
/*
pour utiliser l'I2C,
il faut reaffecter L'UART RA0 RA1 par defaut, et L'ADC sur d'autres PIN Hardware
12F1840
pin 1 VDD Alim +5.0
pin 2 RA5 UART RX <--- UART
pin 3 RA4 UART --> TX
pin 4 RA3/MCLR/VPP -- ICSP Reset R=5.6K de rappel au +3,3V
pin 5 RA2 --------------- I2C SDA * option -- LCD avec R rappel 4,7K
pin 6 RA1 ICSP Clock ---I2C SCL * option -- LCD avec R rappel 4,7K
pin 7 RAO ICSPDAT ------ OWS sonde temperature DS18B20 avec R pull up =4,7K
pin 8 VSS alim 0V
Mesures de courant consommé
Vzersion avec Entree NALOGIQUE :
Vcc=3,3V (alim avec 3 afficheur 7seg inp=9V DC out reglée à = 3,3V)
avec Potar 4,7K entre +alim et Gnd pour consigne EA0
consom en sleep 640µA (mais 12 µA sans le POTAR 4,7K connecté)
consom reveillé 1,71mA (mais 1,09mA sans le potar connecté)
normal car 3,3V / 4,7k = 702µA consommé rien que par le potar
Alim 4 piles 1,5V -> Regulateur ACS117-3,3V
Version avec capteur OWS 18B20
consom en sleep <15µA
consom reveillé 1,15mA
*/
//ac:Schema_sleep_12F1840
#define TAB 9
#define CLS 12
#define CR 13
#define LF 10
#define STX 2
#define ETX 3
#include "built_in.h" // for Hi Lo ..etc
const code char mesg0[]=" "; // 20 blancs pour effacer la ligne LCD
const code char mesg1[]=" Compilateur : "Langage"\n\r";
const code char mesg2[]=" Directory :"Directory"\r\n";
const code char mesg3[]=" Projet :"Projet"\r\n";
const code char mesg4[]=" Source :"Source"_"Version"\r\n";
const code char mesg5[]=" MCU :"MCU"\r\n";
const code char mesg6[]=" POWER_SUPPLY: "POWER_SUPPLY"\r\n";
const code char * Messages[]={mesg0,mesg1,mesg2,mesg3,mesg4,mesg5,mesg6};
// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12
const unsigned short TEMP_RESOLUTION = 12;
unsigned int temp;
#define MAXLEN1 60
volatile unsigned char buffer1[MAXLEN1];
volatile unsigned char * p1;
char TEXTE[60];
char CRam1[20];
char *txt;
char *p;
unsigned short error;
volatile unsigned int CptErr;
volatile int Index1;
volatile unsigned char c1;
volatile unsigned int i1;
volatile int Flag_Buffer1;
unsigned int i,j,k;
unsigned int Mode_Sleep;
void strConstRamCpy(unsigned char *dest, const code char *source);
void CRLF1(void);
void interrupt(void) ;
void RAZ_Buffer1(void);
void Read_Msg_Eeprom(unsigned char depuis);
void Init_Timer0(void);
void Init_Timer1 (void); //125mS
void Init_Timer2 (void); //125mS
//void Float2Ascii (float x, unsigned char *str,char precision);
void interrupt(void) org 0x04
{
if ( (RCIE_bit) && ( RCIF_bit))
{
// traitement separe des erreurs de COM
if (RCSTA.OERR==1) // voir parag 16.1.26 p273
{
RCSTA.CREN = 0 ;
c1 = RCREG;
RCSTA.CREN = 1 ;
CptErr++;
}
if(RCSTA.FERR==1 )
{
RCSTA.SPEN = 0 ;
RCSTA.SPEN= 1 ;
CptErr++;
c1 = RCREG;
}
c1 = RCREG;
if (c1==CR)
{
Flag_Buffer1=1;
RCIE_bit=0 ; //interdit IT Reception UART
buffer1[i1]=0;
Index1=i1;
i1=0;
c1=0;
}
else
{
buffer1[i1]=c1;
Index1=i1;
i1++;
}
PIR1.RCIF=0 ;
}
}
// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(unsigned char *dest, const code char *source)
{
while (*source)*dest++ = *source++ ;
*dest = 0 ; // terminateur
}
void CRLF1()
{
UART1_Write(CR);
UART1_Write(LF);
}
void UART1_Write_CText(const char *txt) {
while (*txt)
UART1_Write(*txt++);
asm nop
asm nop
}
void Raz_Buffer1()
{
buffer1[0]=0;
Index1=0;
Flag_Buffer1 =0;
// nettoye le buffer
for(Index1=0;Index1<MAXLEN1;Index1++)buffer1[Index1]=0;
c1=RCREG;
i1=0;
Index1=0;
c1=0;
RCIE_bit = 1;
p=0;
}
void Write_Msg_Eeprom(unsigned char Adr,const char * d1)
{ int i1 ,i;
char c1;
i1=Adr;
do
{
c1=*d1;
EEPROM_Write(Adr,c1);
if ( c1==0) break;
if ( i1>254) break;
Delay_ms(5);
i1++;
}
while (i!=0) ;
}
void Display_Temperature(unsigned int temp2write)
{
const unsigned int RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// Check if temperature is negative
if (temp2write & 0x8000) {
CRam1[0] = '-';
temp2write = ~temp2write + 1; // complement à 2
}
// Extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// Convert temp_whole to characters
if ((temp_whole/100)>0)
CRam1[0] = temp_whole/100 + 48;
else
CRam1[0] = ' ';
if( (temp_whole/10)%10==0)
CRam1[1]=' ';
else
CRam1[1] = (temp_whole/10)%10 + 48; // Extract tens digit
CRam1[2] = temp_whole%10 + 48; // Extract ones digit
// Extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
CRam1[3]=',';
// Convert temp_fraction to characters
CRam1[4] = temp_fraction/1000 + 48; // Extract thousands digit
CRam1[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
CRam1[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
CRam1[7] = temp_fraction%10 + 48; // Extract ones digit
CRam1[8]=0;
// Print temperature
UART1_Write_Text(CRam1);
}
void main()
{
// FOSC INTERNE
// voir page 61
// 0=4xPLL OFF, 1111=IOFS=16Mhz 0=0 00=SCS=config via Conf1 word FOSC<2:0>
// 0=4xPLL OFF, 1110=IOFS=8Mhz 0=0 00=SCS=config via Conf1 word FOSC<2:0>
// OSCCON=0b01111000; // choix 16Mhz internal osc
OSCCON=0b01110000; // choix 8Mhz internal osc
// RA5 as input for RX , RA4 as output for TX RA2 as input
TRISA=0b00101111; // RA4 en sorties
ANSELA=0; // no analog
WPUA=0b00110000; // weak pull up on RX & TX
CM1CON0=0; // disable comparators
CM1CON1=0;
// RA4=TX RA5=RX (voir page 111 )
APFCON=0;
APFCON.P1BSEL=1; // pour deconnecter de RA0 mais connecte sur RA4 ???!!
APFCON.RXDTSEL=1; // RX sur RA5
APFCON.TXCKSEL=1; // TX sur RA4
// RA5 as input for RX , RA4 as output for TX RA2 as input
i=j=k=0;
txt=&TEXTE[0];
UART1_Init(9600);
// re-init AGAIN , because Uart init disturbing
//TRISA=0b00101111; // RA0 et RA1 en sorties
// 2 times to get empty fifo !
if (PIR1.RCIF==1) c1 = RCREG; // vide Fifo
if (PIR1.RCIF==1) c1 = RCREG; // vide fifo
UART1_Write(CLS);
Delay_ms(500);
CRLF1();
txt=&TEXTE[0];
// presentation
for (i=1;i<6;i++)
{
UART1_Write_CText(Messages[i]);
Delay_ms(100);
}
// strConstRamCpy(txt,mesg1); UART1_Write_Text(txt);
// UART1_Write_CText(mesg2);
CRLF1();
txt=&TEXTE[0];
#ifdef AVEC_MODE_SLEEP
UART1_Write_CText("Send <SLEEP> to put PIC en mode sommeil\r\n") ;
UART1_Write_CText("Send a BREAK character pour reveiller le PIC\r\n");
#else
UART1_Write_CText("Test envoi coammndes SLEEP et WAKEUP\r\n");
#endif
Delay_ms(100);
Raz_Buffer1();
PEIE_bit = 1;
GIE_bit = 1;
WUE_bit = 1;
ADC_Init();
Mode_Sleep=0;
j=0;
while(1)
{
#ifdef AVEC_MODE_SLEEP
if((Flag_Buffer1==1) && (Mode_Sleep==0))
{
p=strstr(buffer1,"SLEEP");
}
if(p>0)
{
Mode_Sleep=1;
UART1_Write_Text(buffer1);CRLF1();
Delay_ms(100);
UART1_Write_CText("Au dodo .. consommation < 15µA \r\n") ;
Delay_ms(100);
Raz_Buffer1();
}
if(((Flag_Buffer1==1) || (i1>0)) && (Mode_Sleep==1))
//if(Index1>0) // if (UART_Data_Ready()==1) au moins 1 car est arrivé
{
Delay_ms(500); //laisse passer les autres
UART1_Write_Text(buffer1);CRLF1();
p=strstr(buffer1,"WAKEUP");
if(p>0)
{
ByteToHex(buffer1[0],CRam1);
Delay_ms(100);
UART1_Write_CText("Reveillé par reception de :");
Delay_ms(100);
UART1_Write_Text(CRam1);
Delay_ms(100);
UART1_Write_CText(" Consom. remonte à ~1,15mA");
CRLF1();
Delay_ms(100);
Raz_Buffer1();
Mode_Sleep=0;
Raz_Buffer1();
}
else // reste en mode sleep
{
Mode_Sleep=1;
}
}
if( Mode_Sleep==1)
{
Raz_Buffer1();
WUE_bit=1; // voir page 265..etc
asm NOP ;
asm NOP ;
asm NOP ;
asm NOP ;
asm sleep
}
#else
if (Flag_Buffer1==1)
{
p=strstr(buffer1,"SLEEP");
if(p>0)
{
UART1_Write_Text(buffer1);CRLF1();
Delay_ms(100);
UART1_Write_CText("Sleep.. consommation < 15µA \r\n") ;
Delay_ms(100);
}
p=strstr(buffer1,"WAKEUP");
if(p>0)
{
UART1_Write_Text(buffer1);CRLF1();
Delay_ms(100);
UART1_Write_CText("Normal. consommation ~1,15mA \r\n") ;
Delay_ms(100);
}
Raz_Buffer1();
}
#endif
Raz_Buffer1();
UART1_Write_CText("Indice j=");
WordToStr(j,CRam1);
Delay_ms(100);
UART1_Write_Text (CRam1);
Delay_ms(100);
UART1_Write(TAB);
j++;
Ow_Reset(&PORTA, 0); // Onewire reset signal
Ow_Write(&PORTA, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTA, 0, 0x44); // Issue command CONVERT_T
Delay_us(200);
Ow_Reset(&PORTA, 0);
Ow_Write(&PORTA, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTA, 0, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTA, 0);
temp = (Ow_Read(&PORTA, 0) << 8) + temp;
//--- Format and display result
UART1_Write_CText(" ; DS18B20#1 Temper.Amb.=");
Delay_ms(100);
Display_Temperature(temp);
CRLF1();
Delay_ms(3000); // le temps de lire la consommation
} //while1
}
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Mode Sleep 12F1840 pour reduire la conso
- paulfjujo
Expert- Messages : 2589
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
il semblerait bien que le premier car pour reveiller le PIC
ait un codage < 0x3F ..
test avec >WAKEUP ..OK pas de garbage !
test avec .WAKEUP .. OK pas de garbage !
je vais essayer de trouver un explicage ...
page 266 Datasheet
26.4.3 AUTO WAKE P BREAK
.. the initial character in the transmission must be all '0'S.
This must be 13 times for LIN bus ,or any number of bit times for RS232
il semblerait donc que les 2 premiers bits de
">" = 0011 1110
ou
"." = 0010 1110
suffisent à sortir du mode sleep et reactiver l''UART
ait un codage < 0x3F ..
test avec >WAKEUP ..OK pas de garbage !
test avec .WAKEUP .. OK pas de garbage !
je vais essayer de trouver un explicage ...
page 266 Datasheet
26.4.3 AUTO WAKE P BREAK
.. the initial character in the transmission must be all '0'S.
This must be 13 times for LIN bus ,or any number of bit times for RS232
il semblerait donc que les 2 premiers bits de
">" = 0011 1110
ou
"." = 0010 1110
suffisent à sortir du mode sleep et reactiver l''UART
Mode Sleep 12F1840 pour reduire la conso
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 31 invités