|
|
View previous topic :: View next topic |
Author |
Message |
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
Problem when using both HLVD interrupts and Brownout Func |
Posted: Thu Mar 26, 2015 8:08 pm |
|
|
Hi.
I'm have a problems when try using both HLVD interrupts and Brownout in my program.
My circuit have a large capacitor (~22000uF/5.5V) make a power backup for PIC to save data when unplug power.
So that, I used Brownout function to against PIC hang when power fast restart.
I think it conflict because I can't save data to eeprom when using HLVD with Brownout func.
Here's my config for HLVD and brownout:
Code: |
#fuses H4,PUT,PROTECT,NODEBUG,NOLVP,NOWDT,NOPBADEN,NOMCLR, BROWNOUT, BORV21 |
Code: | setup_low_volt_detect( LVD_TRIGGER_BELOW| LVD_36);
while(IRVST_BIT==0);
wait_vdd_stable();
LVDIF_BIT=0;
enable_interrupts (int_lowvolt);
|
I'm using CCS C ver5.021, PIC18F4680
Thanks _________________ Begin Begin Begin !!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 26, 2015 8:38 pm |
|
|
Quote: | setup_low_volt_detect(LVD_TRIGGER_BELOW | LVD_36);
|
What's your Vdd voltage for the PIC ? Is it 5 volts ? If so, then why set
the LVD trigger voltage to 3.6 volts ? Why not use LVD_45 instead.
That would give you more time to save to eeprom. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Thu Mar 26, 2015 8:54 pm |
|
|
Thanks for your reply.
My circuit is supplied by 5v-> diode 1N4007-> VCC pic, so that the power to PIC is ~4.4V. _________________ Begin Begin Begin !!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 26, 2015 9:56 pm |
|
|
You could use LVD_42 or LVD_40. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Thu Mar 26, 2015 10:43 pm |
|
|
Thanks u reply.
I tried all but the result no change, I afraid the errors make by the Brownout reset? _________________ Begin Begin Begin !!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 26, 2015 11:15 pm |
|
|
Put an oscilloscope on your PIC's Vdd power pin and turn off the power.
Observe and estimate how much time it takes for the Vdd to drop down
to the Brownout voltage. (ie., from 4.4v to 2.1v) Tell us what you see.
Also, explain why you have the 1N4007 diode in there. Is it for reverse
voltage protection ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Fri Mar 27, 2015 3:32 am |
|
|
Take a deep breath.
Time is everything.
Now PCM_Programmer is pointing at the first key thing. You need to know just how fast your supply rail falls. Having a 22000uF capacitor, means nothing, if the load on this is an amp (4.4R), the rail will fall 2.5v in 80mSec. However if the load is only a few mA, then it'll hold up for ages. This is why you need to actually measure the discharge rate.
Start by working out the loads on the rail. What current is drawn?. This then allows you to estimate the discharge rate. Remember that large capacitors like this are often +/-50% on their 'specified' value. You need to work with the minimum value.
Then how much data are you trying to store?. Given that the EEPROM on your chip takes 4mSec/byte, you need to allow for perhaps 50instruction times to get into the routine to actually perform the write, and then 4mSec/byte for every byte you are storing. If you are storing 20bytes, you need something like 85mSec 'guaranteed' between the point where LVD triggers, and you reach brownout.
Then, with your strange power supply (again PCM has asked an important question - why not use a Schottky diode for example), why not feed the LVD detection from the supply _before_ the diode?. This is normally how LVD is used. Monitoring something like the incoming supply (with a suitable divider), so it triggers when this drops, before the actual chip supply begins to drop. This all gives you extra time from the detection moment, till brownout.
Then you have to look at 'worst case' figures. BORV at 2.1v nominal, can trigger as high as 2.16v. LVD at (nominal) 4v can actually trigger at 4.2 to 4.01v. with your origanal 3.6v (3.63 to 3.8v), you then have the calculation as time from 3.63v to 2.16v. Is this longer than the time needed to write the EEPROM?.
Then there are other questions.
How does your code handle the LVD going off after it has triggered?. Your code in the ISR, must not return to the main routine until this happens, otherwise you can get repeated triggers. So a flow something like:
1) LVD triggers
2) Switch off any circuits you can to reduce the supply load. This extends your available time.
3) Write the data.
4) Sit now monitoring the LVD input. Has it gone 'good' again?. Loop if not.
5) Wait a time (0.1seconds perhaps). Is the LVD still good?. No, go back to 3. Yes. Switch circuits back on, and exit the interrupt.
You must ensure that the code does not exit the interrupt till the supply is 'good', and has stayed good for a while. Otherwise you risk multiple triggers, which will result in the data being corrupted. Also, anything you can do to reduce the current consumption helps give you extra time. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Mar 27, 2015 8:39 pm |
|
|
Thanks for all yours reply.
Really I have make a circuit for a long time but I haven't ensure test the HLVD.
With my circuit, from main power supply (5V DC)-> two branch with 2 diode ( I have replaced by 1N4148 Schottky diode, because I think the DC voltage is switching slower frequency than diode ), one is power supply for loads ( 3 red leds, 1 LCD 16X2, 1 RFID reader board, 2 opto couplers, IC 74HC14), and another is power supply for PIC and external EEPROM, this power is backup by 0.22F capacitor, as an image:
https://drive.google.com/file/d/0Bz215_lkn4g-cEdfV3ZiNlNFVkE/view?usp=sharing
The first time, I used the HLVD pin of PIC18F4680 to detect power down, but it's seem not stable for controlling HLVD interrupts (can by your program isn't good when processing) so that I change to used internal voltage detect for HLVD.
As Ttelmah told, I have a problems when control HLVD ISR, if I set HLVD trigger near a power supply voltage (setup 4V for HLVD trigger), it'll switch to HLVD ISR when power on, so that I try to set HLVD trigger lower.
Adding, I also using WDT function in my program to against PIC hang.
I'll show some short program for process:
1) Config fuses
Code: |
#include "18F4680.h"
#fuses H4,PUT,PROTECT,NODEBUG,NOLVP,NOWDT,NOPBADEN,MCLR, BROWNOUT, BORV21
#use delay(clock=40000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors)
|
2) Config bit HLVD
Code: | #bit HLVD_EN_BIT = getenv("SFR:HLVDCON").4
#bit IRVST_BIT = getenv("SFR:HLVDCON").5
#bit LVDIF_BIT = getenv("SFR:PIR2").2 |
3) HLVD ISR
Code: | #int_lowvolt
void ngat_hlvd(void)
{
HLVD_EN_BIT=0;
pwr_loss=1;
} |
4) check power stable
Code: | void wait_vdd_stable(void)
{
int16 timeout_count;
timeout_count = 0xFFFF; // Many milliseconds
while(timeout_count--)
{
if( LVDIF_BIT==1)
{
LVDIF_BIT=0;
timeout_count = 0xFFFF;
delay_ms(10);
leds_on;
}
}
} |
5) Main program (be shorted)
Code: |
void main(void)
{
.....
setup_low_volt_detect( LVD_TRIGGER_BELOW| LVD_38);
while(IRVST_BIT==0);
wait_vdd_stable();
LVDIF_BIT=0;
enable_interrupts (int_lowvolt);
enable_interrupts (int_rb);
enable_interrupts (int_rda);
enable_interrupts (global);
setup_wdt(WDT_ON|WDT_2S);
for(;;)
{
restart_wdt();
if(pwr_loss==1)
{
pwr_loss=0;
disable_interrupts(global);
#fuses NOBROWNOUT // turn off Brownout reset
setup_timer_0( T0_OFF);
setup_timer_1( T1_DISABLED);
setup_timer_2( T1_DISABLED,195,16 );
read_Pointer_from_eeprom....
write_20_byte_to_eepom....
LVDIF_BIT = 0; // Clear the LVD interrupt flag
enable_interrupts(INT_LOWVOLT);
#fuses BROWNOUT // turn on Brownout
}
else
{
perform_task_main....
}
}
}
|
Thanks. _________________ Begin Begin Begin !!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 9:07 pm |
|
|
Quote: | write_20_byte_to_eeprom.... |
Is this routine a for() loop, with 20 sequential calls to write_ext_eeprom() ?
Or are you using page mode ?
Post the part number of the external eeprom.
Also post your #use i2c() statement. Or is it an SPI eeprom ?
In that case, post your #use spi() or setup_spi() statement.
What driver file are you using for the eeprom ? If it's a CCS driver file,
post the filename. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Mar 27, 2015 9:28 pm |
|
|
PCM programmer wrote: | Quote: | write_20_byte_to_eeprom.... |
Is this routine a for() loop, with 20 sequential calls to write_ext_eeprom() ?
Or are you using page mode ?
Post the part number of the external eeprom.
Also post your #use i2c() statement. Or is it an SPI eeprom ?
In that case, post your #use spi() or setup_spi() statement. |
Thanks PCM
In mys circuit using AT24C128 EEPROM (http://tme.vn/Product.aspx?id=687#page=pro_info)
And in this program, I reduced to save ~9byte and I read and write bytes sequential after check flag ok, also I'm using <24128.c> CCSC driver for external EEPROM
Here is my program in this case:
Code: |
if(pwr_loss==1)
{
pwr_loss=0;
disable_interrupts(global);
#fuses NOBROWNOUT
setup_timer_0( T0_OFF);
setup_timer_1( T1_DISABLED);
setup_timer_2( T1_DISABLED,195,16 );
if(save_tag_eepr==1)
{
if(app_code==0)
{
app_code= app_code_new;
}
pt_eepr_hi= read_ext_eeprom(0);
delay_us(100);
pt_eepr_lo= read_ext_eeprom(1);
pt_eepr = make16(pt_eepr_hi, pt_eepr_lo);
if(pt_eepr==0) { pt_eepr=20;}
pt_eepr+=1;
if(chk_offset_pc_new==1) write_ext_eeprom(pt_eepr, 0xC0);
else write_ext_eeprom(pt_eepr, 0x80);
delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(count_ac,2)); delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(count_ac,1)); delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(count_ac,0)); delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(app_code,2)); delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(app_code,1)); delay_us(100);
pt_eepr+=1;
write_ext_eeprom(pt_eepr, make8(app_code,0)); delay_us(100);
write_ext_eeprom(0, make8(pt_eepr,1)); delay_us(100);
write_ext_eeprom(1, make8(pt_eepr,0)); delay_us(100);
save_tag_eepr=0;
}
while(IRVST_BIT==0);
wait_vdd_stable();
LVDIF_BIT=0;
delay_ms(100);
while(IRVST_BIT==0);
wait_vdd_stable();
LVDIF_BIT=0;
enable_interrupts (int_lowvolt);
#fuses BROWNOUT
}
|
My config for I2C
Code: | #define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
|
Thanks. _________________ Begin Begin Begin !!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 9:45 pm |
|
|
Quote: | I'm using <24128.c> CCSC driver for external EEPROM |
That file has a 10 ms delay after each write. See below:
Code: |
void write_ext_eeprom(long int address, BYTE data)
{
.
.
.
.
.
delay_ms(10);
}
|
I count 10 sequential writes to external eeprom in your code.
That's 10 x 10 ms = 100 ms to write all bytes.
Did you measure the power-down time for Vdd with an oscilloscope or
some other instrument ? I don't see it in your post.
Do you have 100 ms available before the power goes too low ?
That's the question. How much time do you have ?
Or, can you use page mode to speed up the write operation, or can
you switch to FRAM to really speed it up ? |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Mar 27, 2015 9:54 pm |
|
|
Sorry, I don't have an oscilloscope to view it clearly, I using digital multimetter and saw the VDD when power loss about ~3V, it's difficult for me to measure it.
I'm trying and find if I don't enable Brownout after save eeprom, PIC can save data but if power on fast again it's seem hang, must wait a long time (10s).
I'll try edit in my program and send back the result later.
Thanks _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sat Mar 28, 2015 4:00 am |
|
|
As well as the much worse timings for this apporach, you have another problem.
What is the minimum specified voltage for your EEPROM to work?. 2.7v.....
You only have the time for the supply to droop from the LVD triggering to 2.7v now....
Then you have fuses scattered through the code - won't work. Fuses are _one time_ when the chip is programmed, they are not code lines.
Then even worse, you are not servicing the writing inside the interrupt handler, instead you call the interrupt handler, set a flag, exit from this, and have to poll the flag in the main. Each of these operations takes yet more time.
Your approach is fundamentally flawed. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Tue Mar 31, 2015 1:16 am |
|
|
Thanks for your repply.
Really I don't have enough equipment to check time discharge of capacitor to LVD trigger
But i have found a error but I think the voltage of capacitor can discharge enough time to save EEPROM.
In my program, when I send a data from PC to MCU node, if after that power loss, it can save data to EEPROM. Otherwise it can't save data to EEPROM.
I checked in sub program when received data from CAN bus, it only update the data on LCD, haven't change anthing.
Is there problems between CAN RCV with HLVD ISR?
Really I don't have a way to fix this problems, so that I can only checking my program.
Thanks _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Tue Mar 31, 2015 1:48 am |
|
|
Seriously, not having even a basic oscilloscope, really isn't where to start working with microprocessors. I built my first scope, then my first computer. Nowadays second hand scopes are very cheap, and even better, there are basic LCD models, that are very cheap indeed.
It's like a workman coming to fix your TV, and not even having a screwdriver to open the case....
I suspect you are going to find when you actually put a scope on the power rails, that your system has supply problems, which is why when you start using the microprocessor's ability to monitor these, things do not behave as you expect. |
|
|
|
|
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
|