-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimerA.c
165 lines (139 loc) · 4.66 KB
/
TimerA.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// TimerA.c
/* LJBeato
2021
TimerA functionality to drive DC motor
and Servo Motor
*/
#include "msp.h"
#include <stdint.h>
#include <stdio.h>
#include "TimerA.h"
#include "uart.h"
// Make these arrays 5 deep, since we are using indexes 1-4 for the pins
static uint32_t DEFAULT_PERIOD_A0[5] = {0,0,0,0,0};
static uint32_t DEFAULT_PERIOD_A2[5] = {0,0,0,0,0};
static uint16_t dutyCycle_A0;
static uint16_t dutyCycle_A2;
//***************************PWM_Init*******************************
// PWM output on P2.4, P2.5, P2.6, P2.7
// Inputs: period of P2.4...P2.7 is number of counts before output changes state
// percentDutyCycle (0 -> 1.0)
// pin number (1,2,3,4)
// Outputs: none
int TIMER_A0_PWM_Init(uint16_t period, double percentDutyCycle, uint16_t pin)
{
// Timer A0.1
if (pin == 1)
{
P2->SEL0 |= BIT4; // Initailize for GPIO
P2->SEL1 &= ~BIT4;
P2->DIR |= BIT4; // Set direction to output
P2->DS |= BIT4; // High Drive stregnth
}
// Timer A0.2
else if (pin == 2)
{
P2->SEL0 |= BIT5; // Initailize for GPIO
P2->SEL1 &= ~BIT5;
P2->DIR |= BIT5; // Set direction to output
P2->DS |= BIT5; // High Drive stregnth
}
// Timer A0.3
else if (pin == 3)
{
P2->SEL0 |= BIT6; // Initailize for GPIO
P2->SEL1 &= ~BIT6;
P2->DIR |= BIT6; // Set direction to output
P2->DS |= BIT6; // High Drive stregnth
}
// Timer A0.4
else if (pin == 4)
{
P2->SEL0 |= BIT7; // Initailize for GPIO
P2->SEL1 &= ~BIT7;
P2->DIR |= BIT7; // Set direction to output
P2->DS |= BIT7; // High Drive stregnth
}
else return -2;
// save the period for this timer instance
// DEFAULT_PERIOD_A0[pin] where pin is the pin number
DEFAULT_PERIOD_A0[pin] = period;
// Stop the Timer For Initialization
TIMER_A0->CCR[0] = 0;
// set the duty cycle
dutyCycle_A0 = (uint16_t) (percentDutyCycle * (double)DEFAULT_PERIOD_A0[pin]);
// CCR[n] contains the dutyCycle just calculated, where n is the pin number
//TIMER_A0->CCR[pin]
TIMER_A0->CCR[pin] = dutyCycle_A0;
// TIMER_A0->CCTL[pin]
// Sync compare input high, Output mode Reset/Set
TIMER_A0->CCTL[pin] = 0x04e1;
// Timer CONTROL register
// TIMER_A0->CTL
TIMER_A0->CTL = 0x210;
// Start the timer by inputting the counter value
TIMER_A0->CCR[0] = DEFAULT_PERIOD_A0[pin];
return 0;
}
//***************************PWM_Duty1*******************************
// change duty cycle of PWM output on pin
// Inputs: dutycycle, pin
// Outputs: none
// percentDutyCycle is a number between 0 and 1 (ie. 0.5 = 50%)
void TIMER_A0_PWM_DutyCycle(double percentDutyCycle, uint16_t pin)
{
uint16_t dutyCycle = (uint16_t) (percentDutyCycle * (double)DEFAULT_PERIOD_A0[pin]); // Find period that the duty cycle will be high for.
TIMER_A0->CCR[pin] = dutyCycle;
}
//***************************PWM_Init*******************************
// PWM output on P5.6
// Inputs: period of P5.6 is number of counts before output changes state
// percentDutyCycle (0 -> 1.0)// duty cycle
// pin number (1,2,3,4), but always 1
// Outputs: none
int TIMER_A2_PWM_Init(uint32_t period, double percentDutyCycle, uint16_t pin)
{
// NOTE: Timer A2 only exposes 1 PWM pin
// TimerA2.1
if (pin == 1)
{
P5->SEL0 |= BIT6; // Initailize for GPIO
P5->SEL1 &= ~BIT6;
P5->DIR |= BIT6; // Set direction to output
P5->DS |= BIT6; // High Drive stregnth
}
else return -2;
// save the period for this timer instance
// DEFAULT_PERIOD_A0[pin] where pin is the pin number
DEFAULT_PERIOD_A2[pin] = period;
// Stop the Timer For Initialization
if (pin == 1)
TIMER_A2->CCR[0] = 0;
// TIMER_A0->CCTL[pin]
// Sync compare input high, Output mode Reset/Set
TIMER_A2->CCTL[pin] = 0x04e1;
// set the duty cycle
dutyCycle_A2 = (uint16_t) (percentDutyCycle * (double)DEFAULT_PERIOD_A2[pin]);
// CCR[n] contains the dutyCycle just calculated, where n is the pin number
//TIMER_A0->CCR[pin]
TIMER_A2->CCR[pin] = dutyCycle_A2;
// Timer CONTROL register
// TIMER_A0->CTL
TIMER_A2->CTL |= 0x261;
TIMER_A2->EX0 |= 0x6;
// Start the timer by inputting the counter value
if (pin == 1)
TIMER_A2->CCR[0] = DEFAULT_PERIOD_A2[pin];
return 0;
}
//***************************PWM_Duty1*******************************
// change duty cycle of PWM output on P5.6
// Inputs: percentDutyCycle, pin (should always be 1 for TimerA2.1)
//
// Outputs: none
//
void TIMER_A2_PWM_DutyCycle(double percentDutyCycle, uint16_t pin)
{
uint16_t dutyCycle = (uint16_t) (percentDutyCycle * (double)DEFAULT_PERIOD_A2[pin]); // Find period that the duty cycle will be high for. // Find period that the duty cycle will be high for.
TIMER_A2->CCR[pin] = dutyCycle;
}