-
Notifications
You must be signed in to change notification settings - Fork 4
/
ex1.c
80 lines (60 loc) · 2.04 KB
/
ex1.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
#include "common.h"
static void configure_polled_adc(void);
static uint16_t polled_adc(void);
int main(void)
{
// Setup: caches, clocks, LED and button GPIOs, ST-Link USART.
common_init(true);
usart_print("START\r\n");
// Set up for polled ADC of single input channel.
configure_polled_adc();
char buff[64];
uint32_t blink_start = systick_count;
uint32_t adc_blink_start;
bool adc_blink_on = false;
while (1) {
// "I'm alive" blinky.
if (systick_count - blink_start >= 100) {
LED1_PORT->ODR ^= 1 << LED1_PIN;
blink_start = systick_count;
}
// "ADC in progress" blinky.
if (adc_blink_on && systick_count - adc_blink_start > 250) {
CLEAR_BIT(LED2_PORT->ODR, 1 << LED2_PIN);
adc_blink_on = false;
}
// Handle button press: start "ADC in progress" blinky, do polled
// ADC and print result.
if (button_pressed) {
button_pressed = false;
usart_print("BUTTON\r\n");
SET_BIT(LED2_PORT->ODR, 1 << LED2_PIN);
adc_blink_on = true;
adc_blink_start = systick_count;
SET_BIT(ADC1->CR2, ADC_CR2_ADON);
uint16_t sample = polled_adc();
CLEAR_BIT(ADC1->CR2, ADC_CR2_ADON);
sprintf(buff, "ADC: %d\r\n", sample);
usart_print(buff);
}
}
}
static void configure_polled_adc(void) {
configure_common_adc(1, false);
// Set ADC group regular trigger source: software trigger.
MODIFY_REG(ADC1->CR2, ADC_CR2_EXTEN, 0);
// Set ADC group regular sequencer length: one channel.
MODIFY_REG(ADC1->SQR1, ADC_SQR1_L, 0);
// Set ADC group regular sequence: channel 4 @ rank 0.
MODIFY_REG(ADC1->SQR3, 0x0000001FU, 0x04);
// Set ADC channel 4 sample time: 56 cycles.
MODIFY_REG(ADC1->SMPR2, ADC_SMPR2_SMP4, 0x03 << ADC_SMPR2_SMP4_Pos);
}
static uint16_t polled_adc(void) {
// Manually start ADC conversion.
SET_BIT(ADC1->CR2, ADC_CR2_SWSTART);
// Wait for conversion complete.
while (!READ_BIT(ADC1->SR, ADC_SR_EOC)) { __asm("nop"); }
// Read converted data (clears EOC flag).
return (uint16_t)(READ_BIT(ADC1->DR, ADC_DR_DATA));
}