-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLab02_REG1&2.c
219 lines (180 loc) · 4.98 KB
/
Lab02_REG1&2.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//----------------------------------
// Lab 2 - Timer Interrupts - Lab02.c
//----------------------------------
// Objective:
// Build a small game that records user's reaction time.
//
//
//
// -- Imports ---------------
//
#include "init.h"
//
//
// -- Prototypes ------------
//
void blinkScreen();
void Init_GPIO();
void Init_Timer();
//
//
// -- Code Body -------------
//
volatile uint8_t timeUpdated = 0;
volatile uint8_t buttonPressed = 0;
volatile uint8_t buttonReleased = 0;
volatile uint32_t elapsed = 0;
int flag_1 = 0;//EXTI0 flag
int flag_2 = 0;//timer 6 flag
int count_ten = 0;//increment every 10 sec
int trigger = 0;//EXTI8 flag
int main() {
Sys_Init();
Init_Timer();
Init_GPIO();
printf("\033[2J\r\n");
printf("TEST!\r\n");
while (1) {
// Main loop code goes here
//printf("\033c\033[36m\033[2J");
if (flag_2) //if 10 sec has passed
{
printf("\r\033[8;1H Tenth sec have passed: %d.\r\n", count_ten);
count_ten ++;
flag_2 = 0;
}
if (trigger)//if C8 is rising edge
{
printf("\r\033[6;1HPushbutton 2 is pressed \r\n");
trigger = 0;
}
else
printf("\r\033[6;1HPushbutton 2 is not pressed\r\n");
if (flag_1) //if J0 is falling edge
{
printf("\r\033[5;1HPushbutton 1 is pressed \r\n");
flag_1 = 0;
}
else
printf("\r\033[5;1HPushbutton 1 is not pressed\r\n");
HAL_Delay(1000);
}
}
//
//
// -- Utility Functions ------
//
void blinkScreen(){
printf("\033[30;47m");
// Clear and redraw display (flash it & sound the bell).
printf("\a\033[s\033[2J\033[u");
fflush(stdout);
HAL_Delay(100);
printf("\033[37;40m");
// Clear and redraw display (flash it).
printf("\033[s\033[2J\033[u");
fflush(stdout);
}
//
//
// -- Init Functions ----------
//
void Init_Timer() {
// Enable the TIM6 interrupt.
// Looks like HAL hid this little gem, this register isn't mentioned in
// the STM32F7 ARM Reference Manual....
//NVIC->ISER[IRQ6 / 32] = (uint32_t) 1 << (IRQ6 % 32); //EXIT0
NVIC->ISER[54 / 32] = (uint32_t) 1 << (54 % 32); //Timer6
// Enable TIM6 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
asm ( "nop" );
asm ( "nop" );
// Set pre-scaler to slow down ticlks
TIM6->PSC = 0x405FU;
// Set the Auto-reload Value for 10Hz overflow
TIM6->ARR = 0xFFFEU;
// Generate update events to auto reload.
TIM6->EGR = 0x0001;
// Enable Update Interrupts.
TIM6->DIER = 0x0001;
// Start the timer.
TIM6->CR1 = 0x0001;
}
void Init_GPIO() {
// Enable GPIO clocks?
// Looks like GPIO reg updates are synced to a base clock.
// for any changes to appear the clocks need to be running.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOJEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
// Enable clock to SYSCONFIG module to enable writing of EXTICRn registers
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
// or __HAL_RCC_SYSCFG_CLK_ENABLE();
// Delay after an RCC peripheral clock enabling
asm ("nop");
asm ("nop");
// Set C8 J0 to input mode
GPIOJ->MODER &= 0x00000000U;
GPIOC->MODER &= 0x00000000U;
// GPIO Interrupt
// By default pin PA0 will trigger the interrupt, change EXTICR1 to route proper pin
SYSCFG->EXTICR[0] |= 0x00000009U; // EXTICR1-4 are confusingly an array [0-3]. Route the EXTICR to C8 and J0
SYSCFG->EXTICR[2] |= 0x00000002U;
// Set C8 J0 as input (button) with pull-down.
GPIOJ->PUPDR |= 0x00000002U;
GPIOC->PUPDR |= 0x00020000U;
// Set interrupt enable for EXTI0,8
NVIC->ISER[6 / 32] = (uint32_t) 1 << (6 % 32); //EXIT0
NVIC->ISER[23 / 32] = (uint32_t) 1 << (23 % 32); //EXIT8
// Unmask interrupt line 0 and 8.
EXTI->IMR |= 0x00000001U;
EXTI->IMR |= 0x00000100U;
// Register for rising edge.
// EXTI->RTSR |= 0x00000001U;
// EXTI->RTSR |= 0x00000100U;
// And register for the falling edge.
EXTI->FTSR |= 0x00000001U;
EXTI->FTSR |= 0x00000100U;
GPIO_InitTypeDef gpio_init;
gpio_init.Pin = GPIO_PIN_8;
gpio_init.Mode = GPIO_MODE_IT_RISING;
gpio_init.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOC, &gpio_init);
//enable the IRQ
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
//
//
// -- ISRs (IRQs) -------------
//
void TIM6_DAC_IRQHandler() {
// Clear Interrupt Bit
TIM6->SR &= 0x0000;
// Other code here:
flag_2 = 1;
}
// Non-HAL GPIO/EXTI Handler
void EXTI0_IRQHandler() {
// Clear Interrupt Bit by setting it to 1. ******Q:why clear PR firstly?**********
EXTI->PR |= 0x00000001U;
// Other code here:
flag_1 = 1;
}
//HAL - GPIO/EXTI Handler
void EXTI9_5_IRQHandler(void) {
//point to IRQ of EXTI8
HAL_GPIO_EXTI_IRQHandler(8);
if(__HAL_GPIO_EXTI_GET_FLAG(EXTI_PR_PR8) )//if interrupt flag is true
{
trigger = 1;//set global flag
__HAL_GPIO_EXTI_CLEAR_FLAG(EXTI_PR_PR8);//clear
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin_8){
// ISR code here.
}
// For the HAL timer interrupts, all of the associated Callbacks need to exist,
// otherwise during assembly, they will generate compiler errors as missing symbols
// Below are the ones that are not used.
// void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim){};
// void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim){};