|
|
View previous topic :: View next topic |
Author |
Message |
ritz
Joined: 06 Mar 2009 Posts: 8 Location: Bucharest
|
Problem with PIC 18F2520 in sleep mode |
Posted: Thu Mar 10, 2016 11:01 am |
|
|
Hi all
I'm not a very good programmer for microcontrollers. I work more on computer programming (and industrial electronic repairs) and I need a little help. I built an application that has
a stopwatch and a numeric keypad where I can enter data, which I saved into an external memory. I used a PIC 18F2520 and CCS compiler v 5.008.
The program is quite complex and I will improve. It works well with one exception: not working in sleep mode (I need a low consumption).
I do not have a debugger, so I made a simple simulation on a test circuit board with the following simple program:
Code: |
#include "18F2520.h"
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
//#include "24256.c"
#use delay(clock=8000000)
#fuses NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use fast_io(B)
#define LED PIN_C5
#define INT_PERIPHERAL 0xF240
static unsigned int32 powerticks;
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD //TIMER1 CONFIG REGISTER LOOK DATASHEET
#byte OSCCON = 0xFD3
#bit IDLEN=OSCCON.7
#int_timer1
clock_t1(){
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
powerticks++;
}
void setup(){
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
set_tris_b(0b00001111);
set_tris_c(0b10010000);
port_b_pullups(TRUE);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
// enable_interrupts(INT_PERIPHERAL);
enable_interrupts(GLOBAL);
}
void main()
{
setup();
output_low(LED1);
sleep();
output_toggle(LED);
//while(1);
}
|
The timer increments every second in variable powerticks, which I save into internal memory and turn it in seconds. I used a quartz 32768 KHz, external.
The problem is:
If in MAIN have a loop "while", the pic go to spleep,after a second wakes and never go into sleep again. But if I cancel "while loop", work ok. At every second he wakes up, LED lights and after that go to sleep. In my real program, I have this loop in MAIN:
Code: |
while (1) { // main loop
if (powerticks % 100 == 0) {
i = powerticks;
write_eeprom(4, i % 256);
i = i >> 8;
write_eeprom(3, i % 256);
i = i >> 8;
write_eeprom(2, i % 256);
i = i >> 8;
write_eeprom(1, i);
}
|
This it saves hours, minutes, seconds in internal eeprom. Like in program test, if this "while loop" not exist in MAIN, the PIC go to sleep in every
second and wake up.
Please give me some advice,
thank you very much _________________ ritz |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Mar 10, 2016 12:49 pm |
|
|
I'm confused.
Please tell us exactly what you want to happen.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Thu Mar 10, 2016 1:44 pm |
|
|
there are several problems to be dealt with
1) what's the purpose of the program? it's unclear at the moment
2) get rid of the # use fast_io() and the set_tris() commands. Let the compiler handle all those details AUTOMATICALLY for you.
3) look at the software RTC in the code library. It works ! and may help you.
4) saving data to any EEPROM takes a lot of time and energy
5) perhaps use a HW RTC like the DS1307
6) sleep may not be efficient for you. A bigger battery,better coding might work better.
we're not sure what your overall plan is ,so please outline in detail what you want to accomplish.
jay |
|
|
ritz
Joined: 06 Mar 2009 Posts: 8 Location: Bucharest
|
18f2520 sleep |
Posted: Thu Mar 10, 2016 2:56 pm |
|
|
Thank you very much for your answers!
Yes, I think I was not sufficiently explicit. Put off my program and take for example this simple program again, from which I removed everything that was not necessary:
Code: |
#include "18F2520.h"
#use delay(clock=8000000)
#fuses NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#define LED PIN_C5
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD //TIMER1 CONFIG REGISTER LOOK DATASHEET
#byte OSCCON = 0xFD3
#bit IDLEN=OSCCON.7
#int_timer1
clock_t1(){
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
powerticks++;
}
void setup(){
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
set_tris_b(0b00001111);
set_tris_c(0b10010000);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
}
void main()
{
setup();
sleep();
output_toggle(LED);
//while(1);
}
|
In this program, the PIC go to sleep and wake up at one second, LED lights, and after that the pic go to sleep for one second again.
In my MAIN, as you see,while loop is comment. If I deleting comments, ( while (1);), the pic not return in sleep mode. He go to sleep
at first time, after that wake up and never go into sleep.
In my real program, the problem is the same. As long as I have a loop "while" in main, Pic go to sleep one time, and after wake up,
never not come back in sleep. It would have been enough to save energy and the external eeprom rarely is used, only when must input some
some data. Maybe in the future will save a timer to a longer interval, but important for me is to work this sleep.
I ask now: why this happen? what is wrong with "while"? I need to send PIC for one (or more) seconds in sleep mode, and wake up when timer1 generate an interrupt.
Thank you _________________ ritz |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Mar 10, 2016 3:23 pm |
|
|
The sleep needs to be inside the loop....
Code: |
void main()
{
setup();
while (TRUE)
{
sleep();
delay_cycles(1); //read the data sheet for why you should have this
output_toggle(LED);
}
}
|
Otherwise it only gets executed once.... |
|
|
ritz
Joined: 06 Mar 2009 Posts: 8 Location: Bucharest
|
sleep 18F2520 |
Posted: Sat Mar 12, 2016 2:55 am |
|
|
Thank you very much, Ttelmah, yes work now. And thank you very much to all for help! I had one more question. This pic (18F2520--it is not LF, but is SMD with 28 pins) it has around 400 microamperes consumption in sleep mode (with Timer1 running with external 32.768 KHz). It's not too much? _________________ ritz |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Mar 12, 2016 3:43 am |
|
|
You have to remember that every pin that connects to something, could potentially be delivering current. Also all inputs should not be left floating (set unused pins as outputs).
A 'floating' input, can reach the voltage where the internal logic switches. This happens even if the chip is asleep, so power is then drawn,
An output 'driving' something, delivers that power even when the chip is asleep. So you need to ensure all output pins are set to the state where they are not delivering into the external circuitry, before going to sleep.
Then there are other peripherals that should be explicitly turned off. Comparator. PWM. ADC. Vref. HLVD. MSSP etc.. Never 'assume' they will be off.
Also how are you generating the supply?. Anything like an external regulator, will itself draw power.
Set things up right, and the chip _will_ meet it's data sheet spec's. You should be able to get down to about 13uA (assuming you are on 5v). |
|
|
ritz
Joined: 06 Mar 2009 Posts: 8 Location: Bucharest
|
18F2520 consumption |
Posted: Sat Mar 12, 2016 6:35 am |
|
|
I tested with simple piece of code of your example,without any peripherals(only with timer1 external quartz) and power source from 5 Volts,and from battery Li-Ion 3.7V.And I tested with my code .Consumption it is the same(~400 microamperes).Only port B have 4 pins as inputs.But I will try with another settings and with another chipset,for to see if something changes.
Thank you _________________ ritz |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Mar 12, 2016 7:52 am |
|
|
The point is that the rest of 'port B' is there (as are the other ports). All pins wake as inputs, and on all circuitry of this type a pin should never be left 'undriven'. Wire all the unused pins together, and connect them with a resistor to ground. Or set them as outputs and drive them low.
Undriven pins increase the risk of electrical damage to the chip, and also can potentially draw power. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|