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 "my_adc.h"
__IO uint16_t ADC_ConvertedValue[ADC_BUFF_SIZE][NOFCHANEL] = {0};
/**
* @brief 中断配置
* @param 无
* @retval 无
*/
static void ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = ADC_DMA_IRQ;
// 设置主优先级为 0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief ADC GPIO 初始化
* @param 无
* @retval 无
*/
static void ADCx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// ADC GPIO 初始化
ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(ADC_PORT, &GPIO_InitStructure);
}
/**
* @brief 时间初始化
* @param 无
* @retval 无
*/
static void ADC_Time_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
ADC_TIM_APBxClock_FUN(ADC_TIM_CLK, ENABLE); //时钟使能
//定时器TIM4初始化
/*--------------------时基结构体初始化-------------------------*/
TIM_TimeBaseStructure.TIM_Period = ADC_TIM_Period; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =ADC_TIM_Prescaler; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(ADC_TIM, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
/*--------------------输出比较结构体初始化-------------------*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = (ADC_TIM_Period+1)/2;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
ADC_TIM_OCInit(ADC_TIM, & TIM_OCInitStructure); //初始化外设TIM4 C4
//使能TIMx
TIM_Cmd(ADC_TIM,ENABLE);
}
/**
* @brief 配置ADC工作模式
* @param 无
* @retval 无
*/
static void ADCx_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
// 打开DMA时钟
RCC_AHBPeriphClockCmd(ADC_DMA_CLK, ENABLE);
// 打开ADC时钟
ADC_APBxClock_FUN( ADC_CLK, ENABLE);
// ADC 模式配置
// 只使用一个ADC,属于单模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
// 扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
// 连续转换模式
// 修改为不连续转换
// ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
// 不用外部触发转换,软件开启即可
// 修改为定时触发
//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_ExternalTrigConv =ADC_TIM_Conv ;
// 转换结果右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
// 转换通道个数
ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;
// 初始化ADC
ADC_Init(ADC_x, &ADC_InitStructure);
// 配置ADC时钟RCC_PCLK2的8分频,即9MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
// 配置ADC 通道的转换顺序和采样时间
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL1, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL2, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL3, 3, ADC_SampleTime_239Cycles5);
//使能温度传感器和内部参考电压
ADC_TempSensorVrefintCmd(ENABLE);
// 使能ADC DMA 请求
ADC_DMACmd(ADC_x, ENABLE);
// 开启ADC ,并开始转换
ADC_Cmd(ADC_x, ENABLE);
// 初始化ADC 校准寄存器
ADC_ResetCalibration(ADC_x);
// 等待校准寄存器初始化完成
while(ADC_GetResetCalibrationStatus(ADC_x));
// ADC开始校准
ADC_StartCalibration(ADC_x);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADC_x));
// 由于没有采用外部触发,所以使用软件触发ADC转换
// 修改为外部触发
//ADC_SoftwareStartConvCmd(ADC_x, ENABLE);
ADC_ExternalTrigConvCmd(ADC_x,ENABLE);
// 复位DMA控制器
DMA_DeInit(ADC_DMA_CHANNEL);
// 配置 DMA 初始化结构体
// 外设基址为:ADC 数据寄存器地址
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;
// 存储器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
// 数据源来自外设
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
// 缓冲区大小,应该等于数据目的地的大小
//DMA_InitStructure.DMA_BufferSize = NOFCHANEL;
// 修改缓冲区大小
DMA_InitStructure.DMA_BufferSize = ADC_BUFF_SIZE*NOFCHANEL;
// 外设寄存器只有一个,地址不用递增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 存储器地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据大小为半字,即两个字节
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
// 内存数据大小也为半字,跟外设数据大小相同
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
// 循环传输模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
// 禁止存储器到存储器模式,因为是从外设到存储器
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// 初始化DMA
DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);
//使能传输完成中断
DMA_ITConfig(ADC_DMA_CHANNEL,DMA_IT_TC, ENABLE);
// 使能 DMA 通道
DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);
}
/**
* @brief ADC初始化
* @param 无
* @retval 无
*/
void ADCx_Init(void)
{
ADC_NVIC_Config();
ADCx_GPIO_Config();
ADC_Time_Config();
ADCx_Mode_Config();
}
|