PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ledtoggle_timer.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "pic24_all.h"
31 
32 /** \file
33 Demonstrates the use of a period interrupt to sample a switch
34 input, removes the need for debounce delays.
35 */
36 
37 /// LED1
38 #define CONFIG_LED1() CONFIG_RB14_AS_DIG_OUTPUT()
39 #define LED1 _LATB14 //led1 state
40 
41 /// Switch1 configuration
42 inline void CONFIG_SW1() {
43  CONFIG_RB13_AS_DIG_INPUT(); //use RB13 for switch input
44  ENABLE_RB13_PULLUP(); //enable the pullup
45 }
46 
47 #define SW1_RAW _RB13 //raw switch value
48 #define SW1 u8_valueSW1 //switch state
49 #define SW1_PRESSED() (SW1==0) //switch test
50 #define SW1_RELEASED() (SW1==1) //switch test
51 
52 //debounced switch value that is set in the timer ISR
53 //any variable written by an ISR should be declared volatile
54 volatile uint8_t u8_valueSW1 = 1; //initially high
55 
56 //Interrupt Service Routine for Timer3
57 void _ISRFAST _T3Interrupt (void) {
58  u8_valueSW1 = SW1_RAW; //sample the switch
59  _T3IF = 0; //clear the timer interrupt bit
60 }
61 
62 typedef enum {
63  STATE_RESET = 0,
64  STATE_WAIT_FOR_PRESS,
65  STATE_WAIT_FOR_RELEASE
66 } STATE;
67 
68 STATE e_LastState = STATE_RESET;
69 //print debug message for state when it changes
70 void printNewState (STATE e_currentState) {
71  if (e_LastState != e_currentState) {
72  switch (e_currentState) {
73  case STATE_WAIT_FOR_PRESS:
74  outString("STATE_WAIT_FOR_PRESS\n");
75  break;
76  case STATE_WAIT_FOR_RELEASE:
77  outString("STATE_WAIT_FOR_RELEASE\n");
78  break;
79  default:
80  break;
81  }
82  }
83  e_LastState = e_currentState; //remember last state
84 }
85 
86 #define ISR_PERIOD 15 // in ms
87 void configTimer3(void) {
88  //ensure that Timer2,3 configured as separate timers.
89  T2CONbits.T32 = 0; // 32-bit mode off
90  //T3CON set like this for documentation purposes.
91  //could be replaced by T3CON = 0x0020
92  T3CON = T3_OFF |T3_IDLE_CON | T3_GATE_OFF
93  | T3_SOURCE_INT
94  | T3_PS_1_64 ; //results in T3CON= 0x0020
95  PR3 = msToU16Ticks (ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
96  TMR3 = 0; //clear timer3 value
97  _T3IF = 0; //clear interrupt flag
98  _T3IP = 1; //choose a priority
99  _T3IE = 1; //enable the interrupt
100  T3CONbits.TON = 1; //turn on the timer
101 }
102 
103 int main (void) {
104  STATE e_mystate;
105 
106  configBasic(HELLO_MSG);
107  /** PIO config ****/
108  CONFIG_SW1(); //configure switch
109  CONFIG_LED1(); //config the LED
110  /* Timer configuration */
111  configTimer3();
112  /*****Toggle LED each time switch is pressed and released ************/
113  e_mystate = STATE_WAIT_FOR_PRESS;
114 
115  /* Observe that use of a periodic interrupt for sampling the
116  switch value means that the debounce delay at the loop bottom
117  is removed.
118  */
119  while (1) {
120  printNewState(e_mystate); //debug message when state changes
121  switch (e_mystate) {
122  case STATE_WAIT_FOR_PRESS:
123  if (SW1_PRESSED()) {
124  e_mystate = STATE_WAIT_FOR_RELEASE;
125  }
126  break;
127  case STATE_WAIT_FOR_RELEASE:
128  if (SW1_RELEASED()) {
129  LED1 = !LED1; //toggle LED
130  e_mystate = STATE_WAIT_FOR_PRESS;
131  }
132  break;
133  default:
134  e_mystate = STATE_WAIT_FOR_PRESS;
135  }//end switch(e_mystate)
136  doHeartbeat(); //ensure that we are alive
137  } // end while (1)
138 
139 }