chipKIT® Development Platform

Inspired by Arduino™

How to use the ChipKit comparators?

Created Sat, 08 Sep 2012 19:28:54 +0000 by ricklon


ricklon

Sat, 08 Sep 2012 19:28:54 +0000

This example code show the comparator in use for Arduino using the AVR code. How can I use the comparator with ChipKit? ChipKit actually has two of these.

int num = 0;
float rpm = 0;
unsigned long times[2];
void setup(){
  pinMode(7,INPUT);
  Serial.begin(9600);
  ACSR = B01011010; // comparator interrupt enabled and tripped on falling edge.
}

void loop(){
}

ISR(ANALOG_COMP_vect) {
  times[1] = times[0];
  times[0] = millis();
  num++;
  
  rpm = (0.0625)/(times[0]-times[1])*1000*60;
  Serial.println(rpm);
}

majenko

Sun, 09 Sep 2012 11:52:45 +0000

The first step is to read the data sheet for the chip you're using.

Then, you also want to study the comparator manual:

[url]http://ww1.microchip.com/downloads/en/DeviceDoc/61110E.pdf[/url]

That details all the registers, what they do, and how to configure it for the way you want it to work.


ricklon

Wed, 03 Oct 2012 20:37:53 +0000

The code on page 19-12 of the PDF won't remotely compile.

I'm at the point where I can attachInterupts, and use the coreTimer library without problem. Using pic32 code isn't something I've done a lot of.

Anyone tried using a comparator?


ricklon

Wed, 03 Oct 2012 21:02:50 +0000

Here's what almost compiles: I get the following error:

ComparatorTest.cpp:33:11: error: variable or field '__ISR' declared void ComparatorTest.cpp:38:11: error: variable or field '__ISR' declared void

int ipl4;

void setup() {
  
  
CM1CON = 0xC0D0;    // Initialize Comparator 1
// Comparator enabled, output enabled, interrupt on any output 
// change, inputs: CVref, C1IN- 
CM2CON = 0xA0C2; // Initialize Comparator 2
// Comparator enabled, output enabled, interrupt on any output 
// change, inputs: C2IN+, C1IN+ 
// Enable interrupts for Comparator modules and set priorities
// Set priority to 7 and subpriority to 3
IPC7SET = 0x00000700; // Set CMP1 interrupt subpriority
IFS1CLR = 0x00000008; // Clear the CMP1 interrupt flag
IEC1SET = 0x00000008; // Enable CMP1 interrupt
IPC7SET = 0x00070000; // Set CMP2 interrupt sub priority 
IFS1CLR = 0x000000010; // Clear the CMP2 interrupt flag
IEC1SET = 0x000000010; // Enable CMP2 interrupt
}

void loop() {
  
}

// Insert user code here
void __ISR(_COMPARATOR_2_VECTOR, ipl4) Cmp2_IntHandler(void)
{
// Insert user code here
IFS1CLR = 0x00000010; // Clear the CMP2 interrupt flag
}
void __ISR(_COMPARATOR_1_VECTOR, ipl4) Cmp1_IntHandler(void)
{
// Insert code user here
IFS1CLR = 0x00000008; // Clear the CMP1 interrupt flag
}

majenko

Thu, 04 Oct 2012 14:21:28 +0000

Try wrapping the ISR functions in

extern "C" {
...
}

ricklon

Mon, 08 Oct 2012 23:08:02 +0000

I worked with my friend Jason D, and he got it working. So first thanks for the extern "C" {}.

The next issue was it still didn't work. however, included plib.h fixed the remaining compile issue. So here's the workable code.

#include <plib.h>


int num = 0;

void setup() {
  Serial.begin(9600);
  
CM1CON = 0xC0D0;    // Initialize Comparator 1
// Comparator enabled, output enabled, interrupt on any output 
// change, inputs: CVref, C1IN- 

IPC7SET = 0x00000700; // Set CMP1 interrupt subpriority
IFS1CLR = 0x00000008; // Clear the CMP1 interrupt flag
IEC1SET = 0x00000008; // Enable CMP1 interrupt

}

void loop() {
  Serial.println(num);
}

extern "C"
{
void __ISR(_COMPARATOR_1_VECTOR, ipl4) Cmp1_IntHandler(void)
{
num++;
IFS1CLR = 0x00000008; // Clear the CMP1 interrupt flag

}

}

Couple of notes from my email conversation:

I couldn't get comparator2 to work though. It will compile but nothing prints to the screen which makes me think there's a typo in the setup instructions.

For comparator1 though, you can convert CM1CON = 0xC090; to binary and get 1100000011010000 which are all of the bits that set up the comparator. For example bits 6-7 (start counting from the right starting at zero) are 11 which tells it to change on any output (high to low, and low to high). I think you can change some of the bits to specify what I/O pin to use for the input too.