Lucas Tai-MacArthur
/
mbed_timer
Penn CIS 441/541 Assignment. Fall 2015
main.cpp@0:068ad2e1c21d, 2015-10-11 (annotated)
- Committer:
- lucastai
- Date:
- Sun Oct 11 18:21:22 2015 +0000
- Revision:
- 0:068ad2e1c21d
Final Version;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lucastai | 0:068ad2e1c21d | 1 | #include "mbed.h" |
lucastai | 0:068ad2e1c21d | 2 | #include "LPC17xx.h" |
lucastai | 0:068ad2e1c21d | 3 | #include "TextLCD.h" |
lucastai | 0:068ad2e1c21d | 4 | |
lucastai | 0:068ad2e1c21d | 5 | // declare hardware you're going to use, mostly copied from example code in previous assignments / Dagens piazza post |
lucastai | 0:068ad2e1c21d | 6 | volatile unsigned short timer_count; |
lucastai | 0:068ad2e1c21d | 7 | Serial pc(USBTX, USBRX); |
lucastai | 0:068ad2e1c21d | 8 | TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7 |
lucastai | 0:068ad2e1c21d | 9 | |
lucastai | 0:068ad2e1c21d | 10 | // declare constants used for counting |
lucastai | 0:068ad2e1c21d | 11 | int running = 0; |
lucastai | 0:068ad2e1c21d | 12 | char mins_tens = '0'; |
lucastai | 0:068ad2e1c21d | 13 | char mins_ones = '0'; |
lucastai | 0:068ad2e1c21d | 14 | char seconds_tens = '0'; |
lucastai | 0:068ad2e1c21d | 15 | char seconds_ones = '0'; |
lucastai | 0:068ad2e1c21d | 16 | char ms_tens = '0'; |
lucastai | 0:068ad2e1c21d | 17 | char ms_ones = '0'; |
lucastai | 0:068ad2e1c21d | 18 | |
lucastai | 0:068ad2e1c21d | 19 | |
lucastai | 0:068ad2e1c21d | 20 | // hardware interrupt handler, adapted from code in piazza post by Dagaen |
lucastai | 0:068ad2e1c21d | 21 | extern "C" void TIMER0_IRQHandler (void) |
lucastai | 0:068ad2e1c21d | 22 | { |
lucastai | 0:068ad2e1c21d | 23 | if((LPC_TIM0->IR & 0x01) == 0x01) // if MR0 interrupt, proceed |
lucastai | 0:068ad2e1c21d | 24 | { |
lucastai | 0:068ad2e1c21d | 25 | LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag |
lucastai | 0:068ad2e1c21d | 26 | timer_count++; //increment timer_count |
lucastai | 0:068ad2e1c21d | 27 | } |
lucastai | 0:068ad2e1c21d | 28 | } |
lucastai | 0:068ad2e1c21d | 29 | |
lucastai | 0:068ad2e1c21d | 30 | // init the hardware interrupt (timer0), adapted same as above |
lucastai | 0:068ad2e1c21d | 31 | void timer0_init(void) |
lucastai | 0:068ad2e1c21d | 32 | { |
lucastai | 0:068ad2e1c21d | 33 | LPC_SC->PCONP |=1<1; //timer0 power on |
lucastai | 0:068ad2e1c21d | 34 | LPC_SC-> PCLKSEL0 |= 1 << 2; // set timer clock to CCLCK nondivided (1 clock cycle = 1 increment) |
lucastai | 0:068ad2e1c21d | 35 | LPC_TIM0->MR0 = 1000000; //100mhz clock cycle, 1 cycle = 10ns, 10ms = 10 000 000 ns = 1M cycles |
lucastai | 0:068ad2e1c21d | 36 | LPC_TIM0->MCR = 3; //interrupt and reset control |
lucastai | 0:068ad2e1c21d | 37 | //3 = Interrupt & reset timer0 on match (111) sets all three bits |
lucastai | 0:068ad2e1c21d | 38 | NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt |
lucastai | 0:068ad2e1c21d | 39 | } |
lucastai | 0:068ad2e1c21d | 40 | |
lucastai | 0:068ad2e1c21d | 41 | // update the display with the global timer values |
lucastai | 0:068ad2e1c21d | 42 | void update_display(void){ |
lucastai | 0:068ad2e1c21d | 43 | // initialize the display, start at 0, paused |
lucastai | 0:068ad2e1c21d | 44 | // first MM |
lucastai | 0:068ad2e1c21d | 45 | lcd.locate(0,0); |
lucastai | 0:068ad2e1c21d | 46 | lcd.putc(mins_tens); |
lucastai | 0:068ad2e1c21d | 47 | lcd.locate(1,0); |
lucastai | 0:068ad2e1c21d | 48 | lcd.putc(mins_ones); |
lucastai | 0:068ad2e1c21d | 49 | // then : |
lucastai | 0:068ad2e1c21d | 50 | lcd.locate(2,0); |
lucastai | 0:068ad2e1c21d | 51 | lcd.putc(':'); |
lucastai | 0:068ad2e1c21d | 52 | // then SS |
lucastai | 0:068ad2e1c21d | 53 | lcd.locate(3,0); |
lucastai | 0:068ad2e1c21d | 54 | lcd.putc(seconds_tens); |
lucastai | 0:068ad2e1c21d | 55 | lcd.locate(4,0); |
lucastai | 0:068ad2e1c21d | 56 | lcd.putc(seconds_ones); |
lucastai | 0:068ad2e1c21d | 57 | // then : |
lucastai | 0:068ad2e1c21d | 58 | lcd.locate(5,0); |
lucastai | 0:068ad2e1c21d | 59 | lcd.putc(':'); |
lucastai | 0:068ad2e1c21d | 60 | // then mS |
lucastai | 0:068ad2e1c21d | 61 | lcd.locate(6,0); |
lucastai | 0:068ad2e1c21d | 62 | lcd.putc(ms_tens); |
lucastai | 0:068ad2e1c21d | 63 | lcd.locate(7,0); |
lucastai | 0:068ad2e1c21d | 64 | lcd.putc(ms_ones); |
lucastai | 0:068ad2e1c21d | 65 | } |
lucastai | 0:068ad2e1c21d | 66 | |
lucastai | 0:068ad2e1c21d | 67 | // reset global values to 0 |
lucastai | 0:068ad2e1c21d | 68 | void reset(void){ |
lucastai | 0:068ad2e1c21d | 69 | mins_tens = '0'; |
lucastai | 0:068ad2e1c21d | 70 | mins_ones = '0'; |
lucastai | 0:068ad2e1c21d | 71 | seconds_tens = '0'; |
lucastai | 0:068ad2e1c21d | 72 | seconds_ones = '0'; |
lucastai | 0:068ad2e1c21d | 73 | ms_tens = '0'; |
lucastai | 0:068ad2e1c21d | 74 | ms_ones = '0'; |
lucastai | 0:068ad2e1c21d | 75 | } |
lucastai | 0:068ad2e1c21d | 76 | |
lucastai | 0:068ad2e1c21d | 77 | // hw interrupt callback, deal with the keyboard input from PC |
lucastai | 0:068ad2e1c21d | 78 | void kb_interrupt() { |
lucastai | 0:068ad2e1c21d | 79 | |
lucastai | 0:068ad2e1c21d | 80 | // get the char, put it on the PC command line |
lucastai | 0:068ad2e1c21d | 81 | char a = pc.getc(); |
lucastai | 0:068ad2e1c21d | 82 | pc.putc(a); |
lucastai | 0:068ad2e1c21d | 83 | // if the char is S, make sure TCR's relevant bit is set |
lucastai | 0:068ad2e1c21d | 84 | if(a == 's'){ |
lucastai | 0:068ad2e1c21d | 85 | // start timer |
lucastai | 0:068ad2e1c21d | 86 | running = 1; |
lucastai | 0:068ad2e1c21d | 87 | LPC_TIM0->TCR |= 1 << 0; |
lucastai | 0:068ad2e1c21d | 88 | // if the char is p, clear TCR, pausing the timer |
lucastai | 0:068ad2e1c21d | 89 | }else if (a == 'p'){ |
lucastai | 0:068ad2e1c21d | 90 | LPC_TIM0->TCR = 0; |
lucastai | 0:068ad2e1c21d | 91 | running = 0; |
lucastai | 0:068ad2e1c21d | 92 | // if the char is r, reset the timer, potentially update display independent of clk interrupt if stopped |
lucastai | 0:068ad2e1c21d | 93 | }else if (a == 'r'){ |
lucastai | 0:068ad2e1c21d | 94 | reset(); |
lucastai | 0:068ad2e1c21d | 95 | if(!running){ |
lucastai | 0:068ad2e1c21d | 96 | update_display(); |
lucastai | 0:068ad2e1c21d | 97 | } |
lucastai | 0:068ad2e1c21d | 98 | }else{ |
lucastai | 0:068ad2e1c21d | 99 | // do nothing for invalid char |
lucastai | 0:068ad2e1c21d | 100 | } |
lucastai | 0:068ad2e1c21d | 101 | } |
lucastai | 0:068ad2e1c21d | 102 | |
lucastai | 0:068ad2e1c21d | 103 | |
lucastai | 0:068ad2e1c21d | 104 | int main (void) |
lucastai | 0:068ad2e1c21d | 105 | { |
lucastai | 0:068ad2e1c21d | 106 | |
lucastai | 0:068ad2e1c21d | 107 | // connect the serial device (PC keybd) to the interrupt |
lucastai | 0:068ad2e1c21d | 108 | pc.attach(&kb_interrupt); |
lucastai | 0:068ad2e1c21d | 109 | |
lucastai | 0:068ad2e1c21d | 110 | // reset the counters, display the original 00:00:00 state |
lucastai | 0:068ad2e1c21d | 111 | reset(); |
lucastai | 0:068ad2e1c21d | 112 | update_display(); |
lucastai | 0:068ad2e1c21d | 113 | |
lucastai | 0:068ad2e1c21d | 114 | |
lucastai | 0:068ad2e1c21d | 115 | //init vars, start timer |
lucastai | 0:068ad2e1c21d | 116 | timer_count = 0; |
lucastai | 0:068ad2e1c21d | 117 | timer0_init(); |
lucastai | 0:068ad2e1c21d | 118 | |
lucastai | 0:068ad2e1c21d | 119 | // main program loop |
lucastai | 0:068ad2e1c21d | 120 | while(true){ |
lucastai | 0:068ad2e1c21d | 121 | // on 10ms interrupt |
lucastai | 0:068ad2e1c21d | 122 | if(timer_count){ |
lucastai | 0:068ad2e1c21d | 123 | // set timer count to 0 every 10ms |
lucastai | 0:068ad2e1c21d | 124 | timer_count = 0; |
lucastai | 0:068ad2e1c21d | 125 | |
lucastai | 0:068ad2e1c21d | 126 | // count up on 10ms interrupt, make sure counter updates properly |
lucastai | 0:068ad2e1c21d | 127 | |
lucastai | 0:068ad2e1c21d | 128 | // update ms ones |
lucastai | 0:068ad2e1c21d | 129 | int msones_carry_flag = 0; |
lucastai | 0:068ad2e1c21d | 130 | if(ms_ones == '9'){ |
lucastai | 0:068ad2e1c21d | 131 | ms_ones = '0'; |
lucastai | 0:068ad2e1c21d | 132 | msones_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 133 | }else{ |
lucastai | 0:068ad2e1c21d | 134 | ms_ones++; |
lucastai | 0:068ad2e1c21d | 135 | } |
lucastai | 0:068ad2e1c21d | 136 | |
lucastai | 0:068ad2e1c21d | 137 | // update ms tens |
lucastai | 0:068ad2e1c21d | 138 | int mstens_carry_flag = 0; |
lucastai | 0:068ad2e1c21d | 139 | if(msones_carry_flag){ |
lucastai | 0:068ad2e1c21d | 140 | if(ms_tens == '9'){ |
lucastai | 0:068ad2e1c21d | 141 | ms_tens = '0'; |
lucastai | 0:068ad2e1c21d | 142 | mstens_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 143 | }else{ |
lucastai | 0:068ad2e1c21d | 144 | ms_tens++; |
lucastai | 0:068ad2e1c21d | 145 | } |
lucastai | 0:068ad2e1c21d | 146 | } |
lucastai | 0:068ad2e1c21d | 147 | |
lucastai | 0:068ad2e1c21d | 148 | // update sec ones |
lucastai | 0:068ad2e1c21d | 149 | int seconds_ones_carry_flag = 0; |
lucastai | 0:068ad2e1c21d | 150 | if(mstens_carry_flag){ |
lucastai | 0:068ad2e1c21d | 151 | if(seconds_ones == '9'){ |
lucastai | 0:068ad2e1c21d | 152 | seconds_ones = '0'; |
lucastai | 0:068ad2e1c21d | 153 | seconds_ones_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 154 | }else{ |
lucastai | 0:068ad2e1c21d | 155 | seconds_ones++; |
lucastai | 0:068ad2e1c21d | 156 | } |
lucastai | 0:068ad2e1c21d | 157 | } |
lucastai | 0:068ad2e1c21d | 158 | |
lucastai | 0:068ad2e1c21d | 159 | // update sec tens |
lucastai | 0:068ad2e1c21d | 160 | int seconds_tens_carry_flag = 0; |
lucastai | 0:068ad2e1c21d | 161 | if(seconds_ones_carry_flag){ |
lucastai | 0:068ad2e1c21d | 162 | if(seconds_tens == '5'){ |
lucastai | 0:068ad2e1c21d | 163 | seconds_tens = '0'; |
lucastai | 0:068ad2e1c21d | 164 | seconds_tens_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 165 | }else{ |
lucastai | 0:068ad2e1c21d | 166 | seconds_tens++; |
lucastai | 0:068ad2e1c21d | 167 | } |
lucastai | 0:068ad2e1c21d | 168 | } |
lucastai | 0:068ad2e1c21d | 169 | |
lucastai | 0:068ad2e1c21d | 170 | // update mins ones |
lucastai | 0:068ad2e1c21d | 171 | int mins_ones_carry_flag = 0; |
lucastai | 0:068ad2e1c21d | 172 | if(seconds_tens_carry_flag){ |
lucastai | 0:068ad2e1c21d | 173 | if(mins_ones == '9'){ |
lucastai | 0:068ad2e1c21d | 174 | mins_ones = '0'; |
lucastai | 0:068ad2e1c21d | 175 | mins_ones_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 176 | }else{ |
lucastai | 0:068ad2e1c21d | 177 | mins_ones++; |
lucastai | 0:068ad2e1c21d | 178 | } |
lucastai | 0:068ad2e1c21d | 179 | } |
lucastai | 0:068ad2e1c21d | 180 | |
lucastai | 0:068ad2e1c21d | 181 | // update mins tens |
lucastai | 0:068ad2e1c21d | 182 | if(mins_ones_carry_flag){ |
lucastai | 0:068ad2e1c21d | 183 | if(mins_ones == '9'){ |
lucastai | 0:068ad2e1c21d | 184 | mins_ones = '0'; |
lucastai | 0:068ad2e1c21d | 185 | mins_ones_carry_flag = 1; |
lucastai | 0:068ad2e1c21d | 186 | }else{ |
lucastai | 0:068ad2e1c21d | 187 | mins_ones++; |
lucastai | 0:068ad2e1c21d | 188 | } |
lucastai | 0:068ad2e1c21d | 189 | } |
lucastai | 0:068ad2e1c21d | 190 | |
lucastai | 0:068ad2e1c21d | 191 | // update display with new vals |
lucastai | 0:068ad2e1c21d | 192 | update_display(); |
lucastai | 0:068ad2e1c21d | 193 | |
lucastai | 0:068ad2e1c21d | 194 | } |
lucastai | 0:068ad2e1c21d | 195 | |
lucastai | 0:068ad2e1c21d | 196 | } |
lucastai | 0:068ad2e1c21d | 197 | } |