|
|
View previous topic :: View next topic |
Author |
Message |
bilbobaggins
Joined: 26 Dec 2014 Posts: 2 Location: Austria
|
pic16f690 - Cannot set vref to expected value |
Posted: Fri Dec 26, 2014 2:27 pm |
|
|
Hi,
i am really confused with the following problem. I tried to test how does comparator work on pic16f690. My test program works quiet well, only one thing does not work - i cannot set various values for vref -> it is always about 0.9v (measured by multimeter directly on trimpot connected to A0). Voltage on A0 varies from 0V up to 5V by turning of trim poty, but comparator triggers its status always at 0.9V (independently on what i try to set).
All attempts to change it by setting VREF_LOW_THRESHOLD(and/or VREF_HIGH_THRESHOLD -> see below) were not successfull. Please help! What is wrong with my code?
My environment is following :
MPLAB 8.60.00.00
CCS PCM C Compiler, Version 5.019, 5967
Code: |
#include <16F690.h>
#fuses INTRC,NOWDT,NOPROTECT, NOMCLR//, NOLVP
#use delay(clock=4000000)
#define GP0 PIN_C0
#define VREF_LOW_THRESHOLD 11 // Expected Vref = 2.3 volts
#define VREF_HIGH_THRESHOLD 12 // Expected Vref = 2.5 volts
#INT_COMP
void isr() {
clear_interrupt(INT_COMP);
if(C1OUT == 0) {
output_low(GP0);
setup_vref(VREF_LOW | VREF_COMP1| VREF_HIGH_THRESHOLD);
} else {
output_high(GP0);
setup_vref(VREF_LOW | VREF_COMP1 | VREF_LOW_THRESHOLD);
}
}
void main() {
setup_comparator(NC_NC_NC_NC);
setup_comparator(CP1_C1_A0 | CP1_INVERT);
setup_vref(VREF_LOW | VREF_COMP1 | VREF_HIGH_THRESHOLD);
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
while (TRUE) {}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 26, 2014 4:20 pm |
|
|
I assume you're using this post as a model:
http://www.ccsinfo.com/forum/viewtopic.php?t=44190&start=4
Your setup line below has a problem:
Quote: |
setup_comparator(CP1_C1_A0 | CP1_INVERT); |
You're not including VR in the inputs. If you look at the setup_vref()
section in the 16F690.h file, it shows you should be using this:
So one input is taken from the vref module, and the other input is pin C1.
Also, my sample code shows that you're supposed to read the CMCON
register in the isr to clear the mismatch condition. You need to do that.
This is not the same as clearing the interrupt. You're doing that at the
start of the isr and it's not necessary. CCS automatically puts in code
to clear the interrupt. You don't have to do it. But you must clear the
mismatch condition. |
|
|
bilbobaggins
Joined: 26 Dec 2014 Posts: 2 Location: Austria
|
|
Posted: Sat Dec 27, 2014 2:38 am |
|
|
Thank you very much, PCM programmer
Yes, i am, because it is from you
Now i see my mistake. I have implemented the solution accordingly to your suggestion and it's working pretty well ! Once more thank you.
Finally my test solution is the following :
Code: |
#include <16F690.h>
#fuses INTRC,NOWDT,NOPROTECT, NOMCLR//, NOLVP
#use delay(clock=4000000)
#define GP0 PIN_C0
#define VREF_LOW_THRESHOLD 11 // Expected Vref = 2.3 volts
#define VREF_HIGH_THRESHOLD 12 // Expected Vref = 2.5 volts
#byte CM1CON = getenv("SFR:CM1CON0")
#INT_COMP
void isr() {
int8 cmcon;
if(C1OUT == 0) {
output_low(GP0);
setup_vref(VREF_LOW | VREF_COMP1| VREF_HIGH_THRESHOLD);
} else {
output_high(GP0);
setup_vref(VREF_LOW | VREF_COMP1| VREF_LOW_THRESHOLD);
}
cmcon = CM1CON;
}
void main() {
int8 cmcon;
setup_comparator(NC_NC_NC_NC);
setup_vref(VREF_LOW | VREF_COMP1 | VREF_HIGH_THRESHOLD);
setup_comparator(CP1_A1_VR | CP1_INVERT);
cmcon = CM1CON;
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
while (TRUE) {}
}
|
Only one question, probably off topic, but it is important for my understanding. Why is it neccessary to read CMCON register within interrupt routine? What is a reason behind? Could you give some documentation reference, please? |
|
|
|
|
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
|