ADC 介绍
12 位 ADC 是一种高速逐次逼近型模拟数字转换器。它有多个通道。各通道的 A/D 转换可以单次、连续、
扫描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
ADC 的输入时钟不得超过 72MHz。
ADC 主要特征
支持最多 2 个 ADC,支持单端输入和差分输入,可测量 16 个外部和 3 个内部信号源
ADC1 支持 9 个外部通道,ADC2 支持 7 个外部通道
支持 12 位、10 位、8 位、6 位分辨率可配置
12bit 分辨率下最高采样速率 5.14MSPS
10bit 分辨率下最高采样速率 6MSPS
8bit 分辨率下最高采样速率 7.2MSPS
6bit 分辨率下最高采样速率 9MSPS
ADC 时钟源分为工作时钟源、采样时钟源和计时时钟源
仅可配置 AHB_CLK 作为工作时钟源,最高可到 144MHz
可配置 PLL 作为采样时钟源,最高可到 72MHz,支持分频 1,2,4,6,8,10,12,16,32, 64,128,256
可配置 AHB_CLK 作为采样时钟源,最高可到 72MHz,支持分频 1,2,4,6,8,10,12,16,32
计时时钟用于内部计时功能,频率必须配置成 1MHz
支持定时器触发 ADC 采样
转换结束、注入转换结束和发生模拟看门狗事件时产生中断
单次和连续转换模式
从通道 0 到通道 N 的自动扫描模式
支持自校准
带内嵌数据一致性的数据对齐
采样间隔可以按通道分别编程
规则转换和注入转换均有外部触发选项
间断模式
双重模式,ADC1 和 ADC2 组合
ADC 供电要求:1.8V 到 3.6V
ADC 输入范围:VREF-≤ VIN ≤ VREF+
规则通道转换期间有 DMA 请求产生。
ADC 功能描述
下图为一个 ADC 模块的框图,表 9-1 为 ADC 引脚的说明。
ADC 开关控制
用户必须等待 PowerUp 过程完成才可以进入下一步的操作,可以通过查询 ADC_CTRL3 里面的 RDY 确认
是否上电完成。
通过设置 ADC_CTRL2 寄存器的 ON 位可给 ADC 上电。当第一次设置 ON 位时,它将 ADC 从断电状态下
唤醒。ADC 上电延迟一段时间后(tSTAB),再次设置 ON 位时开始进行转换。
通过清除 ON 位可以停止转换,并将 ADC 置于断电模式。在这个模式中,ADC 几乎不耗电(仅几个 μA)。
用户可以通过查询 ADC_CTRL3 里面的 PDRDY 确认是否下电完成。
在 ADC Disable 的时候默认都是 PowerDown 模式,这个模式下只要不断电,不需要重新校正,校正值会在ADC 自动保持。为了进一步的降低功耗 ,ADC 有设计一个深睡眠模式。会在 ADC Disable 进入深睡眠模式,ADC 内部的校正值会丢失,需要重新校正。深睡眠模式可以省大概 0.2μA 的功耗 ,注意,当在双 ADC 模式时,最好双 ADC 都选同一种睡眠模式。控制 ADC 深睡眠模式的寄存器ADC_CTRL3.DPWMOD。
内部通道
温度传感器和通道 ADC1_IN16 相连接
VBAT/2 和通道 ADC1_IN17 相连接
内部参照电压 VREFINT 和 ADCx_IN18 相连接
可以按注入或规则通道对内部通道进行转换。
注意:温度传感器,VBAT/2 只能出现在主 ADC1 中。
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#include "n32g4fr.h" #include "n32g4fr_adc.h" #include "errorno.h" #include "bsp_adc.h" #define ADC_REGU_CH_SEQ_LEN 1 #define ADC_WAIT_RET_TIMEOUT 1000 #define ADC_RET_INIT_VALUE 0xAB #define ADC_VDD_POWER_MV 3299 #define ADC_DATA_MAX 4095 #define ADC_READ_INVALID_TIMES 5 /*******************************ADC1 config*****************************/ #define ADC1_MODULE ADC1 #define ADC1_IN_PORT GPIOA #define ADC1_IN_PIN (GPIO_PIN_2 | GPIO_PIN_6) #define ADC1_IN_PORT_RCC RCC_APB2_PERIPH_GPIOA #define ADC1_RCC RCC_AHB_PERIPH_ADC1 /*******************************ADC2 config*****************************/ #define ADC2_MODULE ADC2 #define ADC2_IN_PORT GPIOA #define ADC2_IN_PIN (GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_7) #define ADC2_IN_PORT_RCC RCC_APB2_PERIPH_GPIOA #define ADC2_RCC RCC_AHB_PERIPH_ADC2 typedef struct { ADC_Module* ADCx; GPIO_Module* gpio_x; uint16_t gpio_pin; uint32_t gpio_rcc; uint32_t adcx_rcc; } adc_config_t; const adc_config_t g_adc_configs[BSP_ADC_NUM] = { { .ADCx = ADC1, .gpio_x = ADC1_IN_PORT, .gpio_rcc = ADC1_IN_PORT_RCC, .gpio_pin = ADC1_IN_PIN, .adcx_rcc = ADC1_RCC, }, { .ADCx = ADC2, .gpio_x = ADC2_IN_PORT, .gpio_rcc = ADC2_IN_PORT_RCC, .gpio_pin = ADC2_IN_PIN, .adcx_rcc = ADC2_RCC, } }; void bsp_adc_io_rcc_enable(bsp_adc_t bsp_adc) { RCC_EnableAPB2PeriphClk(g_adc_configs[bsp_adc].gpio_rcc, ENABLE); } void bsp_adc_io_config(bsp_adc_t bsp_adc) { GPIO_InitType GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.Pin = g_adc_configs[bsp_adc].gpio_pin; GPIO_InitPeripheral(g_adc_configs[bsp_adc].gpio_x, &GPIO_InitStruct); } void bsp_adc_rcc_enable(bsp_adc_t bsp_adc) { RCC_EnableAHBPeriphClk(g_adc_configs[bsp_adc].adcx_rcc, ENABLE); RCC_ConfigHclk(RCC_SYSCLK_DIV1); RCC_ConfigAdcHclk(RCC_ADCHCLK_DIV32); RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8); } void bsp_adc_init(bsp_adc_t bsp_adc) { ADC_InitType ADC_InitType_data; ADC_Module* ADCx = g_adc_configs[bsp_adc].ADCx; int timeout = 0; bsp_adc_io_rcc_enable(bsp_adc); bsp_adc_io_config(bsp_adc); bsp_adc_rcc_enable(bsp_adc); ADC_InitType_data.WorkMode = ADC_WORKMODE_INDEPENDENT; ADC_InitType_data.ContinueConvEn = DISABLE; ADC_InitType_data.ChsNumber = ADC_REGU_CH_SEQ_LEN; ADC_InitType_data.DatAlign = ADC_DAT_ALIGN_R; ADC_InitType_data.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; ADC_InitType_data.MultiChEn = ENABLE; ADC_DeInit(ADCx); ADC_Init(ADCx, &ADC_InitType_data); ADC_Enable(ADCx, ENABLE); timeout = 0; while (RESET == ADC_GetFlagStatusNew(ADCx, ADC_FLAG_RDY)) { timeout ++; if (timeout > ADC_WAIT_RET_TIMEOUT) { return ; } } ADC_StartCalibration(ADCx); timeout = 0; while (SET == ADC_GetCalibrationStatus(ADCx)) { timeout ++; if (timeout > ADC_WAIT_RET_TIMEOUT) { return ; } } } uint16_t bsp_adc_get_one_data(bsp_adc_t bsp_adc, uint8_t ADC_Channel) { int32_t timeout = 0; uint32_t adc_data = ADC_RET_INIT_VALUE; ADC_Module* ADCx = g_adc_configs[bsp_adc].ADCx; ADC_ConfigRegularChannel(ADCx, ADC_Channel, 1, ADC_SAMP_TIME_239CYCLES5); ADC_ClearFlag(ADCx, ADC_FLAG_ENDC); //ADC_Enable(ADCx,ENABLE) ADC_EnableSoftwareStartConv(ADCx, ENABLE); timeout = 0; while (RESET == ADC_GetFlagStatus(ADCx, ADC_FLAG_ENDC)) { timeout ++; if (timeout > ADC_WAIT_RET_TIMEOUT) { return adc_data; } } adc_data = ADC_GetDat(ADCx); ADC_ClearFlag(ADCx, ADC_FLAG_ENDC); return adc_data; } uint16_t bsp_adc_get_data(bsp_adc_t bsp_adc, uint8_t ADC_Channel) { uint32_t invalid_read_times = 0; for (invalid_read_times = 0;invalid_read_times < ADC_READ_INVALID_TIMES;invalid_read_times++) { bsp_adc_get_one_data(bsp_adc, ADC_Channel); } return bsp_adc_get_one_data(bsp_adc, ADC_Channel); } uint16_t bsp_adc_convert_to_mvoltage(bsp_adc_t bsp_adc, uint16_t adc_data) { uint16_t adc_vref = bsp_adc_get_data(bsp_adc, ADC_CH_0); if(adc_vref != 0) { return adc_data * ADC_VDD_POWER_MV / adc_vref; } else { return adc_data * ADC_VDD_POWER_MV / ADC_DATA_MAX; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef __BSP_ADC_H__ #define __BSP_ADC_H__ #include "typedefs.h" typedef enum { BSP_ADC_1 = 0, BSP_ADC_2, BSP_ADC_NUM } bsp_adc_t; void bsp_adc_init(bsp_adc_t bsp_adc); uint16_t bsp_adc_get_data(bsp_adc_t bsp_adc, uint8_t ADC_Channel); uint16_t bsp_adc_convert_to_mvoltage(bsp_adc_t bsp_adc, uint16_t adc_data); #endif
最后
以上就是动听糖豆最近收集整理的关于[单片机框架][bsp层][N32G4FR][bsp_adc] ADC配置和使用的全部内容,更多相关[单片机框架][bsp层][N32G4FR][bsp_adc]内容请搜索靠谱客的其他文章。
发表评论 取消回复