CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

pic16f690 - Cannot set vref to expected value

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bilbobaggins



Joined: 26 Dec 2014
Posts: 2
Location: Austria

View user's profile Send private message

pic16f690 - Cannot set vref to expected value
PostPosted: Fri Dec 26, 2014 2:27 pm     Reply with quote

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) {}
}

Quote:
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 26, 2014 4:20 pm     Reply with quote

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:
Code:
CP1_C1_VR

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

View user's profile Send private message

PostPosted: Sat Dec 27, 2014 2:38 am     Reply with quote

Thank you very much, PCM programmer
Quote:

I assume you're using this post as a model:
http://www.ccsinfo.com/forum/viewtopic.php?t=44190&start=4


Yes, i am, because it is from you Very Happy

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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