|
|
View previous topic :: View next topic |
Author |
Message |
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
High/Low voltage detect on PIC18F45K22 (solved) |
Posted: Mon Sep 26, 2011 7:08 am |
|
|
Hi there,
I am trying to detect a brownout with 4.7V level (some of my external components need this rather high level).
Some questions:
1. Do I need to connect the HLVDIN Pin (RA5) to the supply voltage or is there a way to supervise the voltage at the VDD pin not using an extra pin?
2. If I only need the Vdd pin, how must the setup look like?
Right now I am using the RA5 as an output and I tried:
Code: |
setup_low_volt_detect(LVD_47 | LVD_TRIGGER_BELOW);
...
#INT_HLVD
void low_voltage_detection()
{
reset_cpu();
}
|
This one gives me a reset (as soon as RA5 is switched).
Thanks in advance!
Michael
Last edited by mdemuth on Tue Sep 27, 2011 2:29 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 26, 2011 1:02 pm |
|
|
Quote: |
1. Do I need to connect the HLVDIN Pin (RA5) to the supply voltage or is
there a way to supervise the voltage at the VDD pin not using an extra pin?
|
According to the 18F45K22 data sheet, you can either use the HLVDIN pin
or you can use an internal voltage divider as the source. This selection
is programmable with the setup_low_voltage_detect() function.
Quote: | 2. If I only need the Vdd pin, how must the setup look like? |
It's all listed in the PIC data sheet. They tell you everything to do:
Quote: |
23.2 HLVD Setup
To set up the HLVD module:
1. Select the desired HLVD trip point by writing the
value to the HLVDL<3:0> bits.
2. Set the VDIRMAG bit to detect high voltage
(VDIRMAG = 1) or low voltage (VDIRMAG = 0).
3. Enable the HLVD module by setting the
HLVDEN bit.
4. Clear the HLVD interrupt flag (PIR2<2>), which
may have been set from a previous interrupt.
5. If interrupts are desired, enable the HLVD
interrupt by setting the HLVDIE and GIE/GIEH
bits (PIE2<2> and INTCON<7>, respectively).
An interrupt will not be generated until the
IRVST bit is set.
Note:
Before changing any module settings
(VDIRMAG, HLVDL<3:0>), first disable the
module (HLVDEN = 0), make the changes
and re-enable the module. This prevents
the generation of false HLVD events.
|
Items 1, 2, and 3 are handled by the setup_low_volt_detect() function.
You have to do items 4 and 5, with lines of code. My previous post on
LVD shows how to do this:
http://www.ccsinfo.com/forum/viewtopic.php?t=24577
The data sheet also says:
Quote: |
Each time the HLVD module is enabled, the circuitry
requires some time to stabilize.
The IRVST bit (HLVDCON<5>) is a read-only bit used
to indicate when the circuit is stable. The module can
only generate an interrupt after the circuit is stable and
IRVST is set.
|
CCS doesn't handle this. You have to do it. My previous post on LVD
has a routine to do this. See the link above.
However, the address of the HLVDCON register for the 18F45K22 is
different than the LVDCON register in that post. It's better to let the
compiler generate the correct register address by using the line below
to declare the IRVST bit:
Code: |
#bit IRVST_BIT = getenv("SFR:HLVDCON").5
|
Quote: |
Right now I am using the RA5 as an output.
This one gives me a reset (as soon as RA5 is switched).
|
Post a full test program that shows this problem. It should be copy-and-
paste compilable in MPLAB with no edits required and no compilation
errors. For example, in the code that you posted, you have an interrupt
routine, but you don't ever enable the INT_HLVD interrupt or GLOBAL
interrupts. And you don't toggle pin RA5. A full test program will do
these things.
And also you should explain how you're lowering the Vdd voltage.
Are you using a variable bench power supply, and you're turning the
voltage knob down slowly from +5.0v ?
Make sure you post your compiler version. We don't remember
your version from previous posts. |
|
|
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
|
Posted: Tue Sep 27, 2011 2:29 am |
|
|
SOLVED!
All I had to do is to clear the interrupt bit (simple).
The code listed below works fine.
Code: |
//// CCS Compiler Version: 4.124
#include <18f45k22.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,BROWNOUT,MCLR, BORV29,PUT
#use delay(clock=64000000)
int8 counter=0;
#bit LVDIF_BIT = getenv("SFR:PIR2").2
#use rs232(stream=COM2, baud=9600,PARITY=N, BITS=8, STOP=1, UART2,ERRORS) //
#INT_HLVD
void lvd_isr(void)
{
counter=0;
reset_cpu(); // If I do this
}
#zero_ram
void main()
{
setup_oscillator (OSC_64MHZ);
setup_uart(9600,COM2);
setup_low_volt_detect(LVD_47 | LVD_TRIGGER_BELOW);
delay_ms(500); // Wait for voltage beeing stable
fputc(0x0C,COM2); //Formfeed for LCD display
fprintf(COM2,"START\n\r");
for (counter =0; counter < 10; counter++)
{
fprintf(COM2,"x"); // show start-up
delay_ms(200);
}
[b]LVDIF_BIT = 0; // Clear the LVD interrupt flag [/b]
enable_interrupts(INT_HLVD); //
enable_interrupts(GLOBAL);
while (1)
{
counter++;
fputc(0x0C,COM2); //Formfeed
fprintf(COM2,"COUNTER=%03u", counter); // show activity
delay_ms(100);
restart_wdt();
}
} // Ende main
|
Thanks for putting me on the right track. |
|
|
|
|
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
|