LPC8xx Internal Analog Comparator library

Dependents:   ACMP_sample

LPC8xx Internal Analog Comparator library

LPC800シリーズ(LPC812, LPC824等)に内蔵されているコンパレーター(比較器)を使うライブラリです。

使い方

初期化

ACMP acmp(vp, vn, hys, lad);

  • vp = コンパレーター正入力(ACMP::LADDER / ACMP_I1~3 / BANDGAP)
  • vn = コンパレーター負入力(ACMP::LADDER / ACMP_I1~3 / BANDGAP)
  • hys = ヒステリシス選択(ACMP::NONE / HYS5mV / HYS10mV / HYS20mV)
  • lad = 電圧ラダー選択(0~31)

コンパレーター入力に使えるピンは決まっています。(スイッチマトリクスで変更できません)
(LPC81x/82x) ACMP_I1=P0.0 / ACMP_I2=P0.1 / (LPC82x) ACMP_I3=P0.14 / ACMP_I4=P0.23

読み取り

acmp.read();

  • 返り値
  • 1: vp > vn
  • 0: vp < vn

割込み

acmp.rise(*func);

  • vp > vn を検出した時 func を呼び出す

acmp.fall(*func);

  • vp < vn を検出した時 func を呼び出す

Sample

Import programACMP_sample

LPC8xx Internal Analog Comparator

Revision:
0:6ad2528ba3cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ACMP.cpp	Mon Nov 16 03:45:24 2015 +0000
@@ -0,0 +1,79 @@
+/**
+ * LPC8xx Internal Analog Comparator library for mbed
+ * Copyright (c) 2015 Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+/** @file
+ * @brief LPC8xx Internal Analog Comparator library for mbed
+ */
+
+#include "ACMP.h"
+
+ACMP *ACMP::_acmp;
+
+ACMP::ACMP (VSEL vp, VSEL vn, HYS hys, int lad) {
+
+    _acmp = this;
+
+    LPC_SYSCON->PDRUNCFG      &= ~(1<<3);   // Enable power to BOD block
+    LPC_SYSCON->PDRUNCFG      &= ~(1<<15);   // Enable power to CMP block
+    LPC_SYSCON->SYSAHBCLKCTRL |=  (1<<19);   // Enable clock to CMP block
+    LPC_SYSCON->PRESETCTRL    &= ~(1<<12);   // reset CMP
+    LPC_SYSCON->PRESETCTRL    |=  (1<<12);
+
+    if (vp == ACMP_I1 || vn == ACMP_I1) {
+        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7)|(1<<6); // enable clock for SWM, GPIO
+        LPC_IOCON->PIO0_0   &= ~(3<<3); // no pull up/down
+        LPC_GPIO_PORT->DIR0 &= ~(1<<0); // configure GPIO as input
+        LPC_SWM->PINENABLE0 &= ~(1<<0); // P0.0 is ACMP_I1
+        
+    }
+    if (vp == ACMP_I2 || vn == ACMP_I2) {
+        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7)|(1<<6); // enable clock for SWM, GPIO
+        LPC_IOCON->PIO0_1   &= ~(3<<3); // no pull up/down
+        LPC_GPIO_PORT->DIR0 &= ~(1<<1); // configure GPIO as input
+        LPC_SWM->PINENABLE0 &= ~(1<<1); // P0.1 is ACMP_I2
+    }
+#if defined(TARGET_LPC82X)
+    if (vp == ACMP_I3 || vn == ACMP_I3) {
+        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7)|(1<<6); // enable clock for SWM, GPIO
+        LPC_IOCON->PIO0_14  &= ~(3<<3); // no pull up/down
+        LPC_GPIO_PORT->DIR0 &= ~(1<<14); // configure GPIO as input
+        LPC_SWM->PINENABLE0 &= ~(1<<2); // P0.14 is ACMP_I3
+    }
+    if (vp == ACMP_I4 || vn == ACMP_I4) {
+        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7)|(1<<6); // enable clock for SWM, GPIO
+        LPC_IOCON->PIO0_23  &= ~(3<<3); // no pull up/down
+        LPC_GPIO_PORT->DIR0 &= ~(1<<23); // configure GPIO as input
+        LPC_SWM->PINENABLE0 &= ~(1<<3); // P0.23 is ACMP_I4
+    }
+#endif
+    if (lad >= 0) {
+        LPC_CMP->LAD = ((lad & 0x1f) << 1) | (1<<0); // Vref=VDD
+    }
+
+    LPC_CMP->CTRL = (hys << 25) | (vn << 11)| (vp << 8) | (2 << 3); // Both edges
+
+    LPC_CMP->CTRL |= (1<<20); // EDGECLR
+    LPC_CMP->CTRL &= ~(1<<20); // EDGECLR
+    NVIC_EnableIRQ(CMP_IRQn);
+}
+
+extern "C"
+void CMP_IRQHandler (void) {
+    ACMP::_acmp->isrAcmp();
+}
+
+void ACMP::isrAcmp () {
+    if (read()) {
+        _rise.call();
+    } else {
+        _fall.call();
+    }
+    LPC_CMP->CTRL |= (1<<20); // EDGECLR
+    LPC_CMP->CTRL &= ~(1<<20); // EDGECLR
+}
+
+int ACMP::read () {
+    return LPC_CMP->CTRL & (1<<21) ? 1 : 0;
+}