-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
108 lines (85 loc) · 3.16 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*******************************************************************************
* MSP432 Encoder *
* *
* Author: Long Tran *
* Device: MSP432P401R LaunchPad *
* Program: Display encoder turn count on 7-segment display *
* *
* Demo: https://www.youtube.com/watch?v=BwOXYYQE5To *
*******************************************************************************/
#include "msp.h"
#include "stdlib.h"
void sseg_modulo( uint16_t counter); // divide counter into digits using modulo operator
void sseg_display(void); // display counter digits on 7-segment display
void wait(uint32_t t);
const uint8_t look_up[10] = { // 7-segment display look up table
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
volatile int16_t counter; // encoder angle counter
uint8_t display[4] = {0,0,0,0}; // 7-seg display array
void main(void)
{
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
//-- Configure NVIC
NVIC->ISER[1] = 1 << ((PORT3_IRQn) & 31); //enable P3 interrupt
//-- Configure Encoder
P3->DIR &= ~BIT6; // phaseA input
P3->IE |= BIT6; // enable P3.6 interrupt
P3->IES &= ~BIT6; // rising edge
P5->DIR &= ~BIT3; // phaseB input
//-- Configure 7-Seg Display
P4->DIR = 0xFF; // P4 is 7-segment LED output
P8->DIR = 0xFF; // P8 is display output
P5->DIR |= BIT0; // P5.0 is red LED angle polarity indicator
while(1){
if(counter > 0){
P5->OUT &= ~BIT0; // red LED off, positive angle (CW)
}else{
P5->OUT |= BIT0; // red LED on, negative angle (CCW)
}
sseg_modulo( abs(counter)%9999 );
sseg_display();
}
}
//-- Functions
void sseg_modulo( uint16_t counter){
display[0] = counter/1000;
display[1] = (counter/100)%10;
display[2] = (counter/10)%10;
display[3] = counter%10;
}
void sseg_display(void){
static uint8_t k = 0;
// Display digit-k
P4->OUT = 0xFF; // blank 7-seg display
P8->OUT = 0xFF & ~(BIT5 >> k); // enable k-th digit in 7-seg display
P4->OUT = look_up[display[k]]; // display k-th digit in 7-seg display
// increment k index
k++;
if (k >= 4){k = 0;}
// reduce flickering
wait(1000);
}
void wait(uint32_t t){
while(t > 0){t--;}
}
//-- Interrupts
void PORT3_IRQHandler(void)
{
if(P3->IV & 0x0E){ // if phaseA is interrupt source (rising edge)
if(P5->IN & BIT3){ // if phaseB is high
counter--; // decrement counter (CCW)
}else{ // else
counter++; // increment counter (CW)
}
}
}