testing Teensy comparator

Status
Not open for further replies.

NikoTeen

Well-known member
Hi,
for a project I needed a comparator with some filtering features. Teensy 3.2 comparators are matching this requirement very well.

To check the necessary settings I made a test setup with a simple circuit, see attachment, and the following sketch:

void setup() {
byte cnt=1;
char cin;
char cmd[12];
byte cidx=0;
byte p1, p2;

Serial.begin(38400);
while ( !Serial ) ;

Serial.println("Start");

Serial.print(F("CORE_PIN10_CONFIG="));Serial.println(CORE_PIN10_CONFIG,HEX);
CORE_PIN10_CONFIG = PORT_PCR_MUX(6); // CMP1_OUT auf Pin 10
Serial.print(F("CORE_PIN10_CONFIG="));Serial.println(CORE_PIN10_CONFIG,HEX);

CMP1_Init();
Comp1SetOn(0, 7);

Serial.print("CR0="); Serial.println(CMP1_CR0, HEX);
Serial.print("CR1="); Serial.println(CMP1_CR1, HEX);
Serial.print("FPR="); Serial.println(CMP1_FPR, HEX);
Serial.print("SCR="); Serial.println(CMP1_SCR, HEX);
Serial.print("DACCR="); Serial.println(CMP1_DACCR, HEX);
Serial.print("MUXCR="); Serial.println(CMP1_MUXCR, HEX);

pinMode(18,OUTPUT);
tone(18,5000);
pinMode(6,OUTPUT); // PWM
pinMode(7,OUTPUT); // Test INtr.

while (1) {
if (CMP1_SCR & 1) digitalWrite(11,HIGH);
else digitalWrite(11,LOW);

if (Serial.available()) {
cin=Serial.read();
if (cin>20) {
cmd[cidx++]=cin;
}
else if (cin==10) { // fertig
cmd[cidx]=0;
cidx=0;
Serial.print("cmd=");Serial.println(cmd);
switch (cmd[0]) {
case 'C': // CRO oder CR1
p1=byte(atoi((char*)(&cmd[4])));
p2=byte(atoi((char*)(&cmd[6])));
if (cmd[2] == '0') { // p1=Filter_cnt, p2=Hysterese
if (p1 >7) p1=7;
if (p2 >3) p2=3;
CMP1_CR0 = (p1<<4) | p2;
Serial.print("CR0=");Serial.println(CMP1_CR0,HEX);
}
else { // p1=COS, p2=OPE
CMP1_CR1 = B00010001 | ((p1 & 1)<<2) | ((p2 & 1)<<1);
Serial.print("CR1=");Serial.println(CMP1_CR1,HEX);
}
break;
case 'F': // FPR
p1=byte(atoi((char*)(&cmd[4])));
CMP1_FPR = p1;
Serial.print("FPR=");Serial.println(CMP1_FPR,HEX);
break;
case 'D': // DAC
p1=byte(atoi((char*)(&cmd[4]))); // VRSEL
p2=byte(atoi((char*)(&cmd[6]))); // VOSEL (0..63)
CMP1_DACCR = B10000000 | ((p1 & 1)<<6) | (p2 & 63);
Serial.print("DAC=");Serial.println(CMP1_DACCR,HEX);
break;
case 'M': // MUX
p1=byte(atoi((char*)(&cmd[4]))); // PSEL
p2=byte(atoi((char*)(&cmd[6]))); // MSEL
CMP1_MUXCR = ((p1 & 7)<<3) | (p2 & 7);
Serial.print("MUX=");Serial.println(CMP1_MUXCR,HEX);
break;
case 'a': // aW, analogWrite
p1=byte(atoi((char*)(&cmd[3]))); // analogWrite(..)
analogWrite(6,p1);
Serial.print("aW=");Serial.println(p1);
break;
case 'I': // Interrupt on=1, off=0
if (cmd[4] == '1') Comp1EnableIntrpt(CHANGE);
else Comp1DisableIntrpt();
break;
} // switch
}
}

}

}
In the same directory as the sketch there is a .h and a .cpp file, see attachment. These files have been derived from the library analogComp which is available on GitHub, https://github.com/leomil72/analogComp.
For my project I needed comparator 1. Therefore the software is written for CMP1. But it can easily be adapted to the other comparators.

To avoid the tedious loops with editing, compiling and upload the sketch provides some commands via the Serial Monitor to vary comparator settings:
CR0 FILTER_CNT HYSTCTRL
CR1 COS OPE
FPR value (0..255)
DAC VRSEL VOSEL
MUX PSEL MSEL
aW value (0..255)
INT en (1 or 0)

The statement CORE_PIN10_CONFIG = PORT_PCR_MUX(6); at the beginning of setup() activates pin 10 as output of the comparator, see K20P64M72SF1RM_Manual.pdf, chapter 10.3.1.
The output of the comparator can be observed
- on pin 10, CMP1 output linked to pin 10
- on pin 7, if interrupts are enabled, see cmp1_isr() in COMP1.cpp
- on pin 11, the sketch is checking the CMP1_SCR register

With a dual channel oscilloscope it is easy to observe the behaviour of the comparator (ch1 at M1, ch2 at pin 10 or 7 or 11 - see circuit in the attachment) when varying the settings via the commands.

For my project I needed to suppress small pulses on the comparator input. With FILTER_CNT=7 and CMP1_SCR=255 pulses up to 46 usec width will be suppressed. This can be tested by linking pin 6 to pin 23 (of course after removing connection to M1) and varying the pulse width on pin 6 with the command "aW value".

This test setup proved very usefull for my objectives.
Hopefully somebody else can use it successfully too.

NikoTeen
 

Attachments

  • Diagramm1.png
    Diagramm1.png
    4.2 KB · Views: 55
  • COMP1.cpp
    2.4 KB · Views: 68
  • COMP1.h
    230 bytes · Views: 62
Status
Not open for further replies.
Back
Top