1 year, 8 months ago.

Can anybody help me out on reading a Tach signal from DC fan and controlling an LED on/off.


See my code, which is not counting/reading external pulse from fan. checking with different fan types but did not get pulse.

Please help me to resolve.

  1. include <lpc17xx.h>
  2. include "uart.h"
  3. include "delay.h"
  1. define LED 0

volatile uint32_t Freq, Freq2;

int main (void) { UART0_Init(9600); LPC_SC->PCONP |= ( 1 << 15 ); power up GPIO LPC_GPIO0->FIODIR |= 1 << LED; puts P0.0 into output mode.

Initialization of the counter on P1.19 as CAP1.1 LPC_SC->PCONP |= 1 << 2; Power up TimerCounter1 LPC_TIM1->TCR |= 1 << 0; Counter mode LPC_TIM1->CTCR |= 3; Count on falling edges LPC_TIM1->CTCR |= 1 << 2; CAP1.1 is the input pin for which the input signal needs to be connected. LPC_PINCON->PINSEL3 |= ((1 << 7) | (1 << 6));; Make P1.19 as CAP1.1

LPC_TIM1->TCR = 0x1; Enable counter

Initialization of the timer which generates interrupt once in a second LPC_SC->PCONP |= 1 << 1; Power up Timer0

LPC_TIM0->MR0 = 12499999; Assuming that clk freq = 100 MHz, this value is calculated to generate an interrupt once in a second. LPC_TIM0->MCR = 3; interrupt and reset control

NVIC_EnableIRQ(TIMER0_IRQn); enable timer0 interrupt

LPC_TIM0->TCR = 1; enable Timer0

while(1) { UART0_TxFloatNumber(Freq); UART0_Printf("\n"); DELAY_ms(500); UART0_TxFloatNumber(Freq2); UART0_Printf("\n"); }


void TIMER0_IRQHandler (void) { LPC_TIM1->TCR = 1;

if((LPC_TIM0->IR & 0x01) == 0x01) if MR0 interrupt {

LPC_TIM0->IR |= 1 << 0; Clear MR0 interrupt flag

Freq = LPC_TIM1->TC; Read the counter value Freq2 = LPC_TIM0->TC;

LPC_TIM1->TCR |= 1 << 1 ; Reset the counter LPC_GPIO0->FIOPIN ^= (1<<LED); /* Toggle the LED (P0_0) */



Question relating to:

Rapid Prototyping for general microcontroller applications, Ethernet, USB and 32-bit ARM® Cortex™-M3 based designs

Please edit your post to use

your code

so that it's readable.

posted by Andy A 01 Aug 2019

1 Answer

1 year, 8 months ago.

Hello Narsimharaju,

The provided code does not seem to utilize the abstraction layer provided by Mbed and to understand it requires deeper knowledge of LPC1768's registers and timers. Unfortunately I'm not able to help you with that. But here you can find a simple pulse counter. The code is based exclusively on Mbed API's (no low level hardware specific functions are called). The input signal is expected at pin p9. But that can be changed easily. You can also play with the GATE_TIME to suit your needs. The counter counts on rising edge. But it can be changed to falling edge if you like so as follows:

int main(void) {
    //input.rise(callback(&onPulse)); // count pulses on rising edge
    input.fall(callback(&onPulse)); // count pulses on falling edge




Make sure the input pulses at LPC1768's input do not exceed 3.3V (e.g. by using a voltage level converter)! LPC1768's inputs are not 5V tolerant.