Simple revolution counter with custom IRQ handler and IO macros

Dependencies:   TextLCD mbed SimpleIOMacros

Committer:
tlunzer
Date:
Wed Jun 01 09:36:16 2011 +0000
Revision:
0:2352ac8d6438
V 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tlunzer 0:2352ac8d6438 1 /*
tlunzer 0:2352ac8d6438 2 Simple revolution counter, works stable for 1 - 50000 rpm's
tlunzer 0:2352ac8d6438 3 Uses 1 pulse/revolution at pin 10
tlunzer 0:2352ac8d6438 4 */
tlunzer 0:2352ac8d6438 5 #include "mbed.h"
tlunzer 0:2352ac8d6438 6 #include "TextLCD.h"
tlunzer 0:2352ac8d6438 7 #include "IOMacros.h"
tlunzer 0:2352ac8d6438 8
tlunzer 0:2352ac8d6438 9 Ticker timer;
tlunzer 0:2352ac8d6438 10 Timer t;
tlunzer 0:2352ac8d6438 11 DigitalOut led(LED1);
tlunzer 0:2352ac8d6438 12 volatile float count,oldcount, revf;
tlunzer 0:2352ac8d6438 13 int rev;
tlunzer 0:2352ac8d6438 14
tlunzer 0:2352ac8d6438 15 TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x1);
tlunzer 0:2352ac8d6438 16
tlunzer 0:2352ac8d6438 17
tlunzer 0:2352ac8d6438 18 // Function prototype/forward declaration for ISR.
tlunzer 0:2352ac8d6438 19 void atint();
tlunzer 0:2352ac8d6438 20
tlunzer 0:2352ac8d6438 21 /** EINT3_IRQHandler
tlunzer 0:2352ac8d6438 22 */
tlunzer 0:2352ac8d6438 23 extern "C" void EINT3_IRQHandler (void) {
tlunzer 0:2352ac8d6438 24
tlunzer 0:2352ac8d6438 25 // The "event" is connected to pin p10 which is LPC1768 P0_1
tlunzer 0:2352ac8d6438 26 // so lets trap that and ignore all other GPIO interrupts.
tlunzer 0:2352ac8d6438 27 // Test for IRQ on Port0.
tlunzer 0:2352ac8d6438 28 if (LPC_GPIOINT->IntStatus & 0x1) {
tlunzer 0:2352ac8d6438 29 // If P0_1/p10 rises, call atint()
tlunzer 0:2352ac8d6438 30 if (LPC_GPIOINT->IO0IntStatR & (1 << 1)) atint();
tlunzer 0:2352ac8d6438 31 }
tlunzer 0:2352ac8d6438 32
tlunzer 0:2352ac8d6438 33 // Clear this and all other possible GPIO generated interrupts as they don't concern us.
tlunzer 0:2352ac8d6438 34 LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
tlunzer 0:2352ac8d6438 35 LPC_GPIOINT->IO0IntClr = (LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF);
tlunzer 0:2352ac8d6438 36 }
tlunzer 0:2352ac8d6438 37
tlunzer 0:2352ac8d6438 38 void event_irq_init(void) {
tlunzer 0:2352ac8d6438 39 // Use macro to set p10 as an input.
tlunzer 0:2352ac8d6438 40 p10_AS_INPUT;
tlunzer 0:2352ac8d6438 41 // Enable P0_1/p10 for rising edge interrupt generation.
tlunzer 0:2352ac8d6438 42 LPC_GPIOINT->IO0IntEnR |= (1UL << 1);
tlunzer 0:2352ac8d6438 43 // Enable the interrupt.
tlunzer 0:2352ac8d6438 44 NVIC_EnableIRQ(EINT3_IRQn);
tlunzer 0:2352ac8d6438 45 }
tlunzer 0:2352ac8d6438 46
tlunzer 0:2352ac8d6438 47 void atint() {
tlunzer 0:2352ac8d6438 48 count = t.read();
tlunzer 0:2352ac8d6438 49 t.reset();
tlunzer 0:2352ac8d6438 50 }
tlunzer 0:2352ac8d6438 51
tlunzer 0:2352ac8d6438 52 void attim() {
tlunzer 0:2352ac8d6438 53 LED1_TOGGLE; // Use macro instead of led =!led;
tlunzer 0:2352ac8d6438 54 if (count!=oldcount) {
tlunzer 0:2352ac8d6438 55 oldcount = count;
tlunzer 0:2352ac8d6438 56 rev= (60/count);
tlunzer 0:2352ac8d6438 57 if (rev >= 15000) // Reduce resolution to 100 rpm
tlunzer 0:2352ac8d6438 58 rev = (rev/100)*100;
tlunzer 0:2352ac8d6438 59 else if (rev >= 1000) // Reduce resolution to 10 rpm
tlunzer 0:2352ac8d6438 60 rev = (rev/10)*10;
tlunzer 0:2352ac8d6438 61 lcd.cls();
tlunzer 0:2352ac8d6438 62 lcd.printf("U/m %5d ",rev);
tlunzer 0:2352ac8d6438 63 }
tlunzer 0:2352ac8d6438 64 }
tlunzer 0:2352ac8d6438 65
tlunzer 0:2352ac8d6438 66 int main() {
tlunzer 0:2352ac8d6438 67 count = 0;
tlunzer 0:2352ac8d6438 68 lcd.printf("Revolution counter",rev);
tlunzer 0:2352ac8d6438 69 wait(0.5);
tlunzer 0:2352ac8d6438 70 lcd.cls();
tlunzer 0:2352ac8d6438 71 timer.attach(&attim,1);
tlunzer 0:2352ac8d6438 72 event_irq_init();
tlunzer 0:2352ac8d6438 73 t.start();
tlunzer 0:2352ac8d6438 74 while (1) {
tlunzer 0:2352ac8d6438 75 }
tlunzer 0:2352ac8d6438 76 }