Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
//-----------------------------------------------------------------------------
// Sleep timer ISR function declaration
//-----------------------------------------------------------------------------
#pragma interrupt_handler SleepTimerISR;
//-----------------------------------------------------------------------------
//main() function
//-----------------------------------------------------------------------------
void main(void)
{
// Insert your main routine code here.
// Turn on interrupts
M8C_EnableGInt ;
//Turn on the Sleep Timer
SleepTimer_Start();
// Set interrupt to 1 Hz Rate. User can set this to any of 1, 8, 64 or 512 Hz. Refer User module datasheet for more details
SleepTimer_SetInterval(SleepTimer_1_HZ);
LED_1_On();
//Enable Interrupts for Sleep timer
SleepTimer_EnableInt();
SleepTimer_SetTimer(10);
// Put the M8C to sleep
M8C_Sleep;
//Loop continously
while(1)
{
// If there are other resources running in the project, this is the right place
// to stop the resources
// Put the processor to sleep
M8C_Sleep;
// If there are other operations to perform, add code to turn on all the resources and
// perform the necessary operations.
}
}
//-----------------------------------------------------------------------------
// Sleep timer ISR function definition
//-----------------------------------------------------------------------------
void SleepTimerISR_C(void)
{//Start of Sleep Timer ISR, M8C executes this ISR after it comes out of sleep
//M8C ejecuta esta interrupción después de que salga del sueño.
//Toggle P0[0]
LED_1_Off();
}
Hola.
Tengo un consumo elevado de energía en mi proyecto, por el hecho de que la mayor parte del tiempo el pic (18f4550) "no hace nada" pero se encuentra ejecutando millones de ciclos de instrucción "hasta que hace algo". Ese "algo", es guardar un dato cada una hora. El motivo por el cual el pic se mantiene activo es porque tiene que funcionar el reloj ds1307 para que cada una hora, en tiempo real, le diga al pic que tiene que guardar el dato. El problema es que la bateria no me dura mas que unos dias y la necesito durante meses.
Por este motivo me incline a incrementar la eficiencia del uso de la energia de mi proyecto, no puedo seguir agregando pilas y derrochando energía.
Estoy pensando en utilizar el modo Sleep, pero si lo implemento el integrado ds1307 dejaria de funcionar porque funciona en conjunto con el micro. Si es posible, para salir del modo sleep pretendo que cada una hora el ds1307 mande una señal y genere una interrupción.
Es posible que el micro se encuentre en modo sleep y el ds1307 siga corriendo en tiempo real ? como hago eso ?
Que alternativa me pueden presentar con su experiencia ?
Muchas gracias.
Saludos.
Gracias por la respuesta Ardogan.
Con este modo que planteas el Pic se encenderia cada 16 seg como maximo ? no se puede llegar a que se encienda cada 1 hora ?
Saludos
Se ve que la circuitería interna viene preparada para 32KHz nomás.The oscillator is a low-power circuit rated for 32 kHz crystals. It will continue to run during all power-managed modes. The
#include <proyecto2.h>
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_ENABLE_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_D6
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 20MHz)
#use fast_io(B)
#use fast_io(D)
#include <lcd.c>
#use I2C(master, I2C1, FAST = 100000)
int1 alarma1_status, alarma2_status;
char time[] = " : : ",
calendar[] = " / /20 ",
alarma1[] = "A1: : :00", alarma2[] = "A2: : :00";
int8 i, segundo, minuto, hora, dia, fecha, mes, ano,
alarma1_minuto, alarma1_hora, alarma2_minuto, alarma2_hora,
status_reg;
#INT_EXT // External interrupt routine
void ext_isr(void){
output_high(PIN_B4);
clear_interrupt(INT_EXT);
}
void DS1307_read(){ // Funcion de hora real y calendario
i2c_start();
i2c_write(0xD0); // Direccion del ds3232
i2c_write(0); // Envia direccion de registro (segundos)
i2c_start();
i2c_write(0xD1); // Inicializa info para leer
segundo = i2c_read(1); // Segundos se leen en registro 0
minuto = i2c_read(1); // Minutos en el 1
hora = i2c_read(1); // Hora en el 2
dia = i2c_read(1); // Dia en el 3
fecha = i2c_read(1); // Fecha en el 4
mes = i2c_read(1); // Mes en el 5
ano = i2c_read(0); // A*o en el 6
i2c_stop();
}
void alarms_read_display(){ // Para leer en display funcion de las alarmas
int8 control_reg, temperature_lsb;
signed int8 temperature_msb;
i2c_start();
i2c_write(0xD0); // DS3232 direccion
i2c_write(0x08); // Envia direccion de registro de los minutos
i2c_start();
i2c_write(0xD1); // Inicializa lectura de datos
alarma1_minuto = i2c_read(1); // Lee minutos de alarma 1
alarma1_hora = i2c_read(1); // Lee horas de alarma 1
i2c_read(1); // Skip alarm1 day/date register
control_reg = i2c_read(1); // Lee registro de control del ds3232
status_reg = i2c_read(1); // Lee estado del registro
i2c_read(1); // Skip aging offset register
temperature_msb = i2c_read(1);
temperature_lsb = i2c_read(0);
i2c_stop();
// Conversion de BCD a Decimal
alarma1_minuto = (alarma1_minuto >> 4) * 10 + (alarma1_minuto & 0x0F);
alarma1_hora = (alarma1_hora >> 4) * 10 + (alarma1_hora & 0x0F);
alarma2_minuto = (alarma2_minuto >> 4) * 10 + (alarma2_minuto & 0x0F);
alarma2_hora = (alarma2_hora >> 4) * 10 + (alarma2_hora & 0x0F);
// Fin de la conversion
alarma1[8] = alarma1_minuto % 10 + 48;
alarma1[7] = alarma1_minuto / 10 + 48;
alarma1[5] = alarma1_hora % 10 + 48;
alarma1[4] = alarma1_hora / 10 + 48;
alarma2[8] = alarma2_minuto % 10 + 48;
alarma2[7] = alarma2_minuto / 10 + 48;
alarma2[5] = alarma2_hora % 10 + 48;
alarma2[4] = alarma2_hora / 10 + 48;
alarma1_status = bit_test(control_reg, 0); // Read alarm1 interrupt enable bit (A1IE) from DS3231 control register
alarma2_status = bit_test(control_reg, 1); // Read alarm2 interrupt enable bit (A2IE) from DS3231 control register
lcd_gotoxy(17, 1);
printf(lcd_putc, alarma1);
lcd_gotoxy(30, 1);
if(alarma1_status) lcd_putc("ON "); // If A1IE = 1 print 'ON'
else lcd_putc("OFF"); // If A1IE = 0 print 'OFF'
lcd_gotoxy(17, 2);
printf(lcd_putc, alarma2);
lcd_gotoxy(30, 2);
if(alarma2_status) lcd_putc("ON ");
else lcd_putc("OFF");
}
void calendar_display(){ //Funcion del calendario
switch(dia){
case 1: strcpy(calendar, "Dom / /20 "); break;
case 2: strcpy(calendar, "Lun / /20 "); break;
case 3: strcpy(calendar, "Mar / /20 "); break;
case 4: strcpy(calendar, "Mie / /20 "); break;
case 5: strcpy(calendar, "Jue / /20 "); break;
case 6: strcpy(calendar, "Vie / /20 "); break;
default: strcpy(calendar, "Sab / /20 "); break;
}
calendar[13] = ano % 10 + 48;
calendar[12] = ano / 10 + 48;
calendar[8] = mes % 10 + 48;
calendar[7] = mes / 10 + 48;
calendar[5] = fecha % 10 + 48;
calendar[4] = fecha / 10 + 48;
lcd_gotoxy(1, 2);
printf(lcd_putc, calendar);
}
void DS1307_display(){
// Convierte de BCD a Decimal
segundo = (segundo >> 4) * 10 + (segundo & 0x0F);
minuto = (minuto >> 4) * 10 + (minuto & 0x0F);
hora = (hora >> 4) * 10 + (hora & 0x0F);
fecha = (fecha >> 4) * 10 + (fecha & 0x0F);
mes = (mes >> 4) * 10 + (mes & 0x0F);
ano = (ano >> 4) * 10 + (ano & 0x0F);
//Fin de conversion
time[7] = segundo % 10 + 48;
time[6] = segundo / 10 + 48;
time[4] = minuto % 10 + 48;
time[3] = minuto / 10 + 48;
time[1] = hora % 10 + 48;
time[0] = hora / 10 + 48;
calendar_display(); // Llama a la funcion de calendario en display
lcd_gotoxy(1, 1);
printf(lcd_putc, time); // Display hora
}
void blink(){
int8 j = 0;
while(j < 10 && (input(PIN_B1) || i >= 5) && input(PIN_B2) && (input(PIN_B3) || i < 5)){
j++;
delay_ms(25);
}
}
int8 edit(parameter, x, y){
while(!input(PIN_B1) || !input(PIN_B3)); // espera hasta que boton RB0 se suelte
while(TRUE){
while(!input(PIN_B2)){ //Si boton RB2 esta presionado
parameter++;
if(((i == 0) || (i == 5)) && parameter > 23) // Horas > 23 ==> horas = 0
parameter = 0;
if(((i == 1) || (i == 6)) && parameter > 59) // Minutos > 59 ==> minutos = 0
parameter = 0;
if(i == 2 && parameter > 31) // Si fecha > 31 ==> fecha = 1
parameter = 1;
if(i == 3 && parameter > 12) // Mes > 12 ==> mes = 1
parameter = 1;
if(i == 4 && parameter > 99) // A*o > 99 ==> a*o = 0
parameter = 0;
if(i == 7 && parameter > 1) // Para alarmas ON o OFF (1: alarma ON, 0: alarma OFF)
parameter = 0;
lcd_gotoxy(x, y);
if(i == 7){ // Para alarmas ON & OFF
if(parameter == 1) lcd_putc("ON ");
else lcd_putc("OFF");
}
else
printf(lcd_putc,"%02u", parameter); // Display parametro
if(i >= 5){
DS1307_read();
DS1307_display(); // Display DS3231 hora y calendario
}
delay_ms(200);
}
lcd_gotoxy(x, y);
lcd_putc(" "); // Imprime 2 espacios
if(i == 7) lcd_putc(" "); // Espacion para ON y OFF
blink(); // Llama a la funcion blink
lcd_gotoxy(x, y); //
if(i == 7){ // Para larmas ON & OFF
if(parameter == 1) lcd_putc("ON ");
else lcd_putc("OFF");
}
else
printf(lcd_putc,"%02u", parameter);
blink();
if(i >= 5){
DS1307_read();
DS1307_display();}
if((!input(PIN_B1) && i < 5) || (!input(PIN_B3) && i >= 5)){
i++; // Incrementa 'i' para el siguiente parametro
return parameter; // Devuelve el valor del parametro y termina
}
}
}
void main(){
output_b(0);
set_tris_b(0x0F); // Configura RB0 ~ 3 como pin de entrada
set_tris_d(0); // Pines del puerto D como salida
port_b_pullups(TRUE); // Enable PORTB internal pull-ups
enable_interrupts(GLOBAL); // Interrupciones globales
enable_interrupts(INT_EXT_H2L); // Enable external interrupt with edge from high to low
lcd_init();
lcd_putc('\f'); // Limpia LCD
while(TRUE){
if(!input(PIN_B1)){ // Si boton RB1 esta presionado
i = 0;
hora = edit(hora, 1, 1);
minuto = edit(minuto, 4, 1);
while(!input(PIN_B1)); // Espera hasta que boton rb0 se suelte
while(TRUE){
while(!input(PIN_B2)){ // Si boton rb2 esta presionado
dia++; // Incrementa el dia
if(dia > 7) dia = 1;
calendar_display();
lcd_gotoxy(1, 2);
printf(lcd_putc, calendar);
delay_ms(200);
}
lcd_gotoxy(1, 2);
lcd_putc(" ");
blink();
lcd_gotoxy(1, 2);
printf(lcd_putc, calendar);
blink();
if(!input(PIN_B1)) // Si boton rb1 esta presionado
break;
}
fecha = edit(fecha, 5, 2);
mes = edit(mes, 8, 2);
ano = edit(ano, 13, 2);
// Convierte de decimal a BCD
minuto = ((minuto / 10) << 4) + (minuto % 10);
hora = ((hora / 10) << 4) + (hora % 10);
fecha = ((fecha / 10) << 4) + (fecha % 10);
mes = ((fecha / 10) << 4) + (mes % 10);
ano = ((ano / 10) << 4) + (ano % 10);
// Fin de la conversion
// Escribe info de tiempo y calendario al DS3232 RTC
i2c_start();
i2c_write(0xD0); // Direccion del RTC
i2c_write(0); //
i2c_write(0); // Reset segundos
i2c_write(minuto); // Escribe valor de minutos al DS3231
i2c_write(hora); // " hora
i2c_write(dia); // " dia
i2c_write(fecha); // " fecha
i2c_write(mes); // " mes
i2c_write(ano); // " a*o
i2c_stop();
delay_ms(200);
}
if(!input(PIN_B3)){ // Si boton RB3 esta presionado
while(!input(PIN_B3)); // Espera hasta que se suelte ese boton
i = 5;
alarma1_hora = edit(alarma1_hora, 21, 1);
alarma1_minuto = edit(alarma1_minuto, 24, 1);
alarma1_status = edit(alarma1_status, 30, 1);
i = 5;
alarma2_hora = edit(alarma2_hora, 21, 2);
alarma2_minuto = edit(alarma2_minuto, 24, 2);
alarma2_status = edit(alarma2_status, 30, 2);
alarma1_minuto = ((alarma1_minuto / 10) << 4) + (alarma1_minuto % 10);
alarma1_hora = ((alarma1_hora / 10) << 4) + (alarma1_hora % 10);
alarma2_minuto = ((alarma2_minuto / 10) << 4) + (alarma2_minuto % 10);
alarma2_hora = ((alarma2_hora / 10) << 4) + (alarma2_hora % 10);
// Escribe info del las alarmas en DS3232
i2c_start();
i2c_write(0xD0); // Direccion del RTC
i2c_write(7); // Envia direccion del registro (segundos)
i2c_write(0); // Escribo 0 a alarma1 segundos
i2c_write(alarma1_minuto); // Escribir alarma1 minutos valor al DS3232
i2c_write(alarma1_hora);
i2c_write(0x80); // Alarma1 cuando horas, minutos y segundos son iguales
i2c_write(alarma2_minuto);
i2c_write(alarma2_hora);
i2c_write(0x80);
i2c_write(4 | alarma1_status | (alarma2_status << 1)); // Write data to DS3231 control register (enable interrupt when alarm)
i2c_write(0); // Clear alarm flag bits
i2c_stop();
delay_ms(200);
}
if(!input(PIN_B2) && input(PIN_B4)){ // Cuando se presiona el boton B2 con la alarma, se restablece y apaga la alarma
output_low(PIN_B4); // Se apaga el indicador de la alarma
i2c_start();
i2c_write(0xD0);
i2c_write(0x0E); // Envia direccion de registro (registro de control)
//Escribe los datos en el registro de control (apaga alarma y mantiene la otra como esta)
i2c_write(4 | (!bit_test(status_reg, 0) & alarma1_status) | ((!bit_test(status_reg, 1) & alarma2_status) << 1));
i2c_write(0); // Clear alarm flag bits
i2c_stop();
}
DS1307_read();
alarms_read_display();
DS1307_display();
delay_ms(50);
}
}
Busca el archivo "EX_WAKUP.C" en la carpeta de ejemplos de PIC C Compiler.por medio de un botón que cuando lo presione entre en modo sleep y cuando lo vuelva a presionar salga de ese modo.
en la carpeta de ejemplos de PIC C Compiler.