It is currently 23 Aug 2017 19:05

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: 08 Aug 2017 22:10 
Offline

Joined: 12 Dec 2005 21:01
Posts: 73
Location: Oslo, Norway
Hi! I am trying to use one of the internal comparators of a PIC16F18325 to detect when a signal crosses a certain voltage. I (think I) have connected a square wave to the negative input of the comparator and a 2.5V DC to the positive input. I've tried enabling interrupts on both positive and negative edges, but I cannot seem to get the interrupt to trigger.

Here is my simplified example code:

// inputs:
// PORTC.F3: square wave input, connected to Comparator 1, In 3 negative
// PORTA.F0: 2.5V (100k/100k resistor divider between gnd and +5V), C1IN+

// output:
// PORTC.F2: square wave output

unsigned short shortDelay = 0;

void interrupt(){
  if(C1IF_bit){
    //if interrupt is ever triggered, reduce the square wave delay to signal that things have changed (will be visible on my oscilloscope)
    shortDelay = 1;
  }
}

void main() {
  // interrupt on rising and falling edge, pos inp = C1IN+, neg = C1IN3-
  CM1CON1 = 0x11000011;
  C1ON_bit = 1;
  C1POL_bit = 0;
  C1SP_bit = 1;
  C1HYS_bit = 0;
  C1SYNC_bit = 0;
 
  PEIE_bit = 1;          //Peripheral interrupt enable bit
  GIE_bit = 1;           //Enable global interrupt
  C1IE_bit = 1;
  C1IF_bit = 0;

  TRISC.F3 = 1; // input, comparator 1 IN 3-
  TRISC.F2 = 0; // output, shows pulse, but is also connected to TRISC.F3 to
                // use as one of two comparator inputs.
  while(1){

    // shows 500Hz 50/50 square wave on portc.f2 if C1IF has not been triggered.
    // If C1IF is triggered, this changes the duty cycle, letting me see when
    // the interrupt has been triggered.
    PORTC.F2 = 1;
    if(shortDelay == 0){
      delay_us(1000);
    } else {
      delay_us(200);
    }
    PORTC.F2 = 0;
    delay_ms(1);
  }
}


Am I missing something significant? Anything ANSEL related?

_________________
Joakim Tysseng


Top
 Profile  
 
PostPosted: 08 Aug 2017 22:43 
Offline

Joined: 24 Nov 2005 20:07
Posts: 1135
Location: Colorado, USA
Don't forget to clear the C1 interrupt flag each time executing the ISR.


Top
 Profile  
 
PostPosted: 11 Aug 2017 08:43 
Offline

Joined: 12 Dec 2005 21:01
Posts: 73
Location: Oslo, Norway
Hi and thanks for pointing that out,

in this example it is actually intentional - I just wanted to know if the interrupt was ever triggered, no retriggering is needed.

EDITED: Stupid me, I forgot that if I didn't clear the interrupt, it would just jump into the ISR again immediately. Your comment was of course correct.
--
cheers,
Joakim

_________________
Joakim Tysseng


Last edited by tysseng on 12 Aug 2017 19:54, edited 1 time in total.

Top
 Profile  
 
PostPosted: 12 Aug 2017 19:34 
Offline

Joined: 12 Dec 2005 21:01
Posts: 73
Location: Oslo, Norway
...aaaand I found my error. I mixed up hex and binary notation.

CM1CON1 = 0x11000011;

should of course be

CM1CON1 = 0b11000011;

_________________
Joakim Tysseng


Top
 Profile  
 
PostPosted: 12 Aug 2017 20:04 
Offline

Joined: 12 Dec 2005 21:01
Posts: 73
Location: Oslo, Norway
The following code works. The interrupt triggering is one-shot, once it has been triggered (by turning the pot clockwise), the pulse wave changes duty cycle forever.

// inputs:
// PORTC.F3: center tapped potentiometer (50k linear) between 0v and 5v.

// output:
// PORTC.F2: square wave output
unsigned short shortDelay = 0;

void interrupt(){
  if(C1IF_bit){
    shortDelay = 1;
    C1IF_bit = 0;
  }
}

void main() {

  // enable interrupts
  PEIE_bit = 1;
  GIE_bit = 1;

  // dac, use as reference voltage for comparator
  DACCON0 = 0; //references are Vdd and Vss;
  DACCON1 = 0b00001111; // reference is approx 2.5V
  DAC1EN_bit = 1; // enable DAC

  // DAC on positive input
  // portc.f3 on negative input
  // interrupt on transition
  CM1CON1 = 0b10101011; // 3-, DAC

  // output is inverted to get
  // when input < DAC, output is 0
  // when input > DAC, output is 1
  C1POL_bit = 1;
 
  // high speed, normal power
  C1SP_bit = 1;
 
  // no hysteresis
  C1HYS_bit = 0;
 
  // no sync to timer 1
  C1SYNC_bit = 0;

  // turn on comparator
  C1ON_bit = 1;

  // enable interrupt for comparator
  C1IF_bit = 0;
  C1IE_bit = 1;

  TRISC.F2 = 0; // output, shows pulse, but is also connected to TRISC.F3 to
                // use as one of two comparator inputs.

  while(1){
    // shows 500Hz 50/50 square wave on portc.f2 if C1IF has not been triggered.
    // If C1IF is triggered, this changes the duty cycle, letting me see when
    // the interrupt has been triggered.
    PORTC.F2 = 1;
    if(shortDelay == 0){
      delay_us(1000);
    } else {
      delay_us(200);
    }
    PORTC.F2 = 0;
    delay_ms(1);

  }
}

_________________
Joakim Tysseng


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: Bing [Bot], leo73 and 8 guests


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 post attachments in this forum

Search for:
Jump to: