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

ACMP.cpp

Committer:
okini3939
Date:
2015-11-16
Revision:
0:6ad2528ba3cc

File content as of revision 0:6ad2528ba3cc:

/**
 * 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;
}