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

Files at this revision

API Documentation at this revision

Comitter:
okini3939
Date:
Mon Nov 16 03:45:24 2015 +0000
Commit message:
1st build

Changed in this revision

ACMP.cpp Show annotated file Show diff for this revision Revisions of this file
ACMP.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 6ad2528ba3cc ACMP.cpp
--- /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;
+}
diff -r 000000000000 -r 6ad2528ba3cc ACMP.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ACMP.h	Mon Nov 16 03:45:24 2015 +0000
@@ -0,0 +1,82 @@
+/**
+ * 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
+ */
+
+#ifndef _ACMP_H_
+#define _ACMP_H_
+
+#include "mbed.h"
+
+#if !defined(TARGET_LPC81X) && !defined(TARGET_LPC82X)
+#error "supported for LPC8xx"
+#endif
+
+/** ACMP class
+ */
+class ACMP {
+public:
+    enum VSEL {
+        LADDER  = 0, // voltage ladder
+        ACMP_I1 = 1, // P0.0
+        ACMP_I2 = 2, // P0.1
+#if defined(TARGET_LPC81X)
+        BANDGAP = 6,
+#elif defined(TARGET_LPC82X)
+        ACMP_I3 = 3, // P0.14
+        ACMP_I4 = 4, // P0.23
+        BANDGAP = 5,
+        ADC_0   = 6,
+#endif
+    };
+    enum HYS {
+        NONE    = 0,
+        HYS5mV  = 1,
+        HYS10mV = 2,
+        HYS20mV = 3,
+    };
+
+    static ACMP *_acmp;
+
+    /** 
+     * @param ain1 Selects positive voltage input
+     * @param ain2 Selects negative voltage input
+     * @param hys Selects hysteresis of the comparator
+     * @param lad Selects voltage ladder (0-31)
+     */
+    ACMP (VSEL ain1, VSEL ain2, HYS hys = NONE, int lad = -1);
+
+    void isrAcmp ();
+
+    int read ();
+
+    void rise (void(*fptr)() = NULL) {
+        _rise.attach(fptr);
+    }
+    template<typename T>
+    void rise (T* tptr, void (T::*mptr)()) {
+        if ((mptr != NULL) && (tptr != NULL)) {
+            _rise.attach(tptr, mptr);
+        }
+    }
+
+    void fall (void(*fptr)() = NULL) {
+        _fall.attach(fptr);
+    }
+    template<typename T>
+    void fall (T* tptr, void (T::*mptr)()) {
+        if ((mptr != NULL) && (tptr != NULL)) {
+            _fall.attach(tptr, mptr);
+        }
+    }
+
+protected:
+    FunctionPointer _rise, _fall;
+
+};
+
+#endif