在做有AD模块项目的时候遇到几个问题:
1, ADC配合DMA采样规则是怎样的。
2, ADC在DMA采可否不连续采样,以提高有效采样使用率和降低功耗。
3, 如何提高有效利用率和降低功耗,并减少CPU的占用时间。
4, ADC的如何多通道采样。
针对以上几个问题做解答。
ADC的采样模式主要分两个:规则采样和注入采样。规则模式可采样16个通道,注入模式最多只能4个通道。
配合DMA使用时主要是用规则采样模式。在初始化时配置采样端口为规则采样通道即可如下:
列:DC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
端口1为规则采样的第一位,239.5的ADC时钟采样周期。
ADC在DMA下可以不连续采样,既采样一定数据后,关闭ADC及DMA通道。但是这样子存在一些问题。DMA的存储的变量数组中的数据会出现错位问题。
测试过很多方法,包括ADC和DMA一起重新初始化,依然无法解决这个问题。系统只进行一次初始化时,DMA数据无错位现象。 但是对于长时间不关机的产品来说,缺少了几分可靠性。网上也有相关的评测,ADC用DMA工作在强电磁的环境中可能会输出丢失部分数据的可能。
这里就想到了用中断的方式,进行采样。无法用规则模式,因为只能用单次采样触发中断。由于无法确定第一个通道,这样同样会遇到数据错位的现象。所以这里使用注入模式进行中断出发。
有以下几个优点:
1,可以最多4路为一组采样,每组采样结束后才产生一次中断,减少了进中断的次数。
2,在读取数据时几路通道都是预先配置好的。某个变量存放指定某个指定通道。这样永远不可能出现错位现象。
由以总结 在4路及以下通道进行采样时,首选注入模式进行中断采样。超过4路及不是长时间工作的产品(几天以上不断电)可以考虑。
单路采样时,这两种方法都很可靠。
最近刚好在学习uCosII系统,并参考了下通用驱动程序开发。附上ADC驱动代码,希望有所帮助。
提示,在使用某路通道 只要 该通道宏定义置1就可以了。
#define ADCx_CHANNEL0_EN 1 //ADCx通道1 1:便能,0:失能
注意: 在使用注入模式时 最多使能4个通道。
1 /*
2 ********************************************************************************
3 * uC/OS-II
4 * AD采样驱动程序设计
5 * ARM Cortex-M3 Port
6 *
7 * File : ADCxDrv.C
8 * Version : V1.0
9 * By : 王宏强
10 *
11 * For : Stm32f10x
12 * Mode : Thumb2
13 * Toolchain :
14 * RealView Microcontroller Development Kit (MDK)
15 * Keil uVision
16 * Description : 定时器驱动
17 * 占用ADCx(ADC1,ADC2)
18 *
19 * 1,DMA规则模式(可靠性低,多路用此模式) 加宏定义 #define ADC_DMA
20 * 2,4路以下,用注入模式(可靠性高,占资源少)
21 *
22 * ADCxOpen
23 * ADCxClose
24 * ADCxWrite
25 * ADCxRead
26 * ADCxIoCtl
27 * ADCxInstall
28 * ADCxNuinstall
29 * Date : 2012.05.22
30 *******************************************************************************/
31
32 #include "ADCxDrv.h"
33
34 //DMA采样缓冲区
35 static volatile INT16U ADC_ConvertedValueTab[MAX_AD_SAMPLE_COUNTER] = {0};
36 static INT16U ADCxBuff[CHANNEL_COUNT] = {0}; //缓冲区数据平均值
37 static INT16U index = 0;
38
39 #ifdef UCOSII
40 static OS_EVENT *adcSem;
41 static INT8U err;
42 #endif
43
44 //总采样时间(单位ms) = 读样个数 * 采样1个值所用时间 / 72mHz * 1000
45 //static INT16U sampingTime = (INT16U)(CHANNEL_COUNT * ADCx_SAMPLE_COUNT *
46 // 239 * 5 / 9e3 + 1);
47
48 /* Private macro -------------------------------------------------------------*/
49 /* Private variables ---------------------------------------------------------*/
50 ADC_InitTypeDef ADC_InitStructure;
51 DMA_InitTypeDef DMA_InitStructure;
52 NVIC_InitTypeDef NVIC_InitStructure;
53
54
55
56 /*******************************************************************************
57 * Function Name :INT16U GetSampleTemp(INT16U order)
58 * Description :获取采样到的数据,并进行平均
59 * Input :order:通道序列号
60 * Output :返回本通道 采样平均值
61 * Other :
62 * Date :2012.05.23 14:48:23
63 *******************************************************************************/
64 static INT16U GetSampleValue(INT16U order)
65 {
66 u32 sum = 0;
67 u16 i = order;
68
69 if (order >= CHANNEL_COUNT) return 0; //序列号超出范围
70
71 for (i = order; i < MAX_AD_SAMPLE_COUNTER; i+=CHANNEL_COUNT)
72 {
73 sum += ADC_ConvertedValueTab[i];
74 }
75 sum /= ADCx_SAMPLE_COUNT;
76
77 return (u16)sum;
78 }
79
80 void StartAdc(FunctionalState stat)
81 {
82 if (stat == ENABLE) index = 0;
83
84 ADC_ITConfig(ADCx, ADC_IT_JEOC, stat);
85 ADC_Cmd(ADCx, stat);
86 }
87
88
89 /*******************************************************************************
90 * Function Name :static INT32S ADCxOpen(void *pd)
91 * Description :
92 * Input :
93 * Output :
94 * Other :
95 * Date :2012.05.23 10:25:06
96 *******************************************************************************/
97 static INT32S ADCxOpen(void *pd)
98 {
99 GPIO_InitTypeDef GPIO_InitStructure;
100 INT32U rccApb = 0;
101 INT16U gpioPin = 0;
102
103 /* Enable peripheral clocks ----------------------------------------------*/
104 /* Enable DMA1 and DMA2 clocks */
105 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx, ENABLE);
106
107
108 #if ADCx_GPIOX_1_EN
109 rccApb |= RCC_APBXPeriph_GPIOX_1;
110 #endif
111
112 #if ADCx_GPIOX_2_EN
113 rccApb |= RCC_APBXPeriph_GPIOX_2;
114 #endif
115
116 #if ADCx_GPIOX_3_EN
117 rccApb |= RCC_APBXPeriph_GPIOX_3;
118 #endif
119
120 rccApb |= RCC_APBXPeriph_ADCx;
121 RCC_APB2PeriphClockCmd(rccApb, ENABLE);
122 RCC_ADCCLKConfig(RCC_PCLK2_Div8);
123
124
125 #if ADCx_GPIOX_1_EN
126 gpioPin = 0;
127 #if ADCx_CHANNEL0_EN
128 gpioPin |= ADCx_GPIOX_PIN_CH0;
129 #endif
130 #if ADCx_CHANNEL1_EN
131 gpioPin |= ADCx_GPIOX_PIN_CH1;
132 #endif
133 #if ADCx_CHANNEL2_EN
134 gpioPin |= ADCx_GPIOX_PIN_CH2;
135 #endif
136 #if ADCx_CHANNEL3_EN
137 gpioPin |= ADCx_GPIOX_PIN_CH3;
138 #endif
139 #if ADCx_CHANNEL4_EN
140 gpioPin |= ADCx_GPIOX_PIN_CH4;
141 #endif
142 #if ADCx_CHANNEL5_EN
143 gpioPin |= ADCx_GPIOX_PIN_CH5;
144 #endif
145 #if ADCx_CHANNEL6_EN
146 gpioPin |= ADCx_GPIOX_PIN_CH6;
147 #endif
148 #if ADCx_CHANNEL7_EN
149 gpioPin |= ADCx_GPIOX_PIN_CH7;
150 #endif
151 GPIO_InitStructure.GPIO_Pin = gpioPin;
152 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
153 GPIO_Init(ADCx_GPIOX_1, &GPIO_InitStructure);
154 #endif
155
156
157 #if ADCx_GPIOX_2_EN
158 gpioPin = 0;
159 #if ADCx_CHANNEL8_EN
160 gpioPin |= ADCx_GPIOX_PIN_CH8;
161 #endif
162 #if ADCx_CHANNEL9_EN
163 gpioPin |= ADCx_GPIOX_PIN_CH9;
164 #endif
165 GPIO_InitStructure.GPIO_Pin = gpioPin;
166 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
167 GPIO_Init(ADCx_GPIOX_2, &GPIO_InitStructure);
168 #endif
169
170
171 #if ADCx_GPIOX_3_EN
172 gpioPin = 0;
173 #if ADCx_CHANNEL10_EN
174 gpioPin |= ADCx_GPIOX_PIN_CH10;
175 #endif
176 #if ADCx_CHANNEL11_EN
177 gpioPin |= ADCx_GPIOX_PIN_CH11;
178 #endif
179 #if ADCx_CHANNEL12_EN
180 gpioPin |= ADCx_GPIOX_PIN_CH12;
181 #endif
182 #if ADCx_CHANNEL13_EN
183 gpioPin |= ADCx_GPIOX_PIN_CH13;
184 #endif
185 #if ADCx_CHANNEL14_EN
186 gpioPin |= ADCx_GPIOX_PIN_CH14;
187 #endif
188 #if ADCx_CHANNEL15_EN
189 gpioPin |= ADCx_GPIOX_PIN_CH15;
190 #endif
191 GPIO_InitStructure.GPIO_Pin = gpioPin;
192 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
193 GPIO_Init(ADCx_GPIOX_3, &GPIO_InitStructure);
194 #endif
195
196 /* ADCx configuration ---------------------------------------------------*/
197 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
198 ADC_InitStructure.ADC_ScanConvMode = ENABLE;
199 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
200 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
201 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
202 ADC_InitStructure.ADC_NbrOfChannel = CHANNEL_COUNT;
203 ADC_Init(ADCx, &ADC_InitStructure);
204
205
206 #ifdef ADC_DMA
207 /* ADCx regular channels configuration */
208 #if ADCx_CHANNEL0_EN
209 ADC_RegularChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);
210 #endif
211 #if ADCx_CHANNEL1_EN
212 ADC_RegularChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
213 #endif
214 #if ADCx_CHANNEL2_EN
215 ADC_RegularChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);
216 #endif
217 #if ADCx_CHANNEL3_EN
218 ADC_RegularChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
219 #endif
220 #if ADCx_CHANNEL4_EN
221 ADC_RegularChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);
222 #endif
223 #if ADCx_CHANNEL5_EN
224 ADC_RegularChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
225 #endif
226 #if ADCx_CHANNEL6_EN
227 ADC_RegularChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);
228 #endif
229 #if ADCx_CHANNEL7_EN
230 ADC_RegularChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
231 #endif
232 #if ADCx_CHANNEL8_EN
233 ADC_RegularChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);
234 #endif
235 #if ADCx_CHANNEL9_EN
236 ADC_RegularChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
237 #endif
238 #if ADCx_CHANNEL10_EN
239 ADC_RegularChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);
240 #endif
241 #if ADCx_CHANNEL11_EN
242 ADC_RegularChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
243 #endif
244 #if ADCx_CHANNEL12_EN
245 ADC_RegularChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);
246 #endif
247 #if ADCx_CHANNEL13_EN
248 ADC_RegularChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
249 #endif
250 #if ADCx_CHANNEL14_EN
251 ADC_RegularChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);
252 #endif
253 #if ADCx_CHANNEL15_EN
254 ADC_RegularChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
255 #endif
256
257
258 /* DMA1 channel1 configuration -------------------------------------------*/
259 DMA_DeInit(DMAx_Channelx);
260 DMA_InitStructure.DMA_PeripheralBaseAddr = ADCx_DR_Address;
261 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValueTab;
262 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
263 DMA_InitStructure.DMA_BufferSize = (u32)MAX_AD_SAMPLE_COUNTER; //存储的个数
264 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
265 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
266 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
267 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
268 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
269 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
270 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
271 DMA_Init(DMAx_Channelx, &DMA_InitStructure);
272
273 /* Enable ADCx DMA */
274 ADC_DMACmd(ADCx, ENABLE);
275
276 /* Enable DMA1 channel1 */
277 DMA_Cmd(DMAx_Channelx, ENABLE);
278 #else
279
280 /* Set injected sequencer length */
281 ADC_InjectedSequencerLengthConfig(ADC1, CHANNEL_COUNT);
282
283 #if ADCx_CHANNEL0_EN
284 ADC_InjectedChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);
285 #endif
286 #if ADCx_CHANNEL1_EN
287 ADC_InjectedChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
288 #endif
289 #if ADCx_CHANNEL2_EN
290 ADC_InjectedChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);
291 #endif
292 #if ADCx_CHANNEL3_EN
293 ADC_InjectedChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
294 #endif
295 #if ADCx_CHANNEL4_EN
296 ADC_InjectedChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);
297 #endif
298 #if ADCx_CHANNEL5_EN
299 ADC_InjectedChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
300 #endif
301 #if ADCx_CHANNEL6_EN
302 ADC_InjectedChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);
303 #endif
304 #if ADCx_CHANNEL7_EN
305 ADC_InjectedChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
306 #endif
307 #if ADCx_CHANNEL8_EN
308 ADC_InjectedChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);
309 #endif
310 #if ADCx_CHANNEL9_EN
311 ADC_InjectedChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
312 #endif
313 #if ADCx_CHANNEL10_EN
314 ADC_InjectedChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);
315 #endif
316 #if ADCx_CHANNEL11_EN
317 ADC_InjectedChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
318 #endif
319 #if ADCx_CHANNEL12_EN
320 ADC_InjectedChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);
321 #endif
322 #if ADCx_CHANNEL13_EN
323 ADC_InjectedChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
324 #endif
325 #if ADCx_CHANNEL14_EN
326 ADC_InjectedChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);
327 #endif
328 #if ADCx_CHANNEL15_EN
329 ADC_InjectedChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
330 #endif
331
332 ADC_AutoInjectedConvCmd(ADCx, ENABLE);
333 ADC_ITConfig(ADCx, ADC_IT_JEOC, ENABLE);
334
335 /* Configure and enable ADC interrupt */
336 NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
337 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
338 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
339 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
340 NVIC_Init(&NVIC_InitStructure);
341
342 StartAdc(DISABLE);
343 #endif
344
345 /* Enable ADCx */
346 ADC_Cmd(ADCx, ENABLE);
347
348 /* Enable ADCx reset calibaration register */
349 ADC_ResetCalibration(ADCx);
350 /* Check the end of ADCx reset calibration register */
351 while(ADC_GetResetCalibrationStatus(ADCx));
352
353 /* Start ADCx calibaration */
354 ADC_StartCalibration(ADCx);
355 /* Check the end of ADCx calibration */
356 while(ADC_GetCalibrationStatus(ADCx));
357
358 #ifdef UCOSII
359 adcSem = OSSemCreate(0);
360 #endif
361 return (INT32S)DRV_NO_ERR;
362 }
363
364 /*******************************************************************************
365 * Function Name :static INT32S ADCxClose(void *pd)
366 * Description :
367 * Input :
368 * Output :
369 * Other :
370 * Date :2012.05.24 09:10:25
371 *******************************************************************************/
372 static INT32S ADCxClose(void *pd)
373 {
374 ADC_SoftwareStartConvCmd(ADCx, DISABLE);
375
376 /* Enable DMA1 channel1 */
377 DMA_Cmd(DMAx_Channelx, DISABLE);
378
379 /* Enable ADCx DMA */
380 ADC_DMACmd(ADCx, DISABLE);
381
382 StartAdc(DISABLE);
383
384 return (INT32S)DRV_NO_ERR;
385 }
386
387 /*******************************************************************************
388 * Function Name :static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
389 * Description :无效
390 * Input :
391 * Output :
392 * Other :
393 * Date :2012.05.23 14:19:47
394 *******************************************************************************/
395 static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
396 {
397 return (INT32S)DRV_NO_ERR;
398 }
399
400 /*******************************************************************************
401 * Function Name :static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
402 * Description :读取采样到的数据
403 * Input :*buffer:采样缓冲。lenToRead:采取长度(单位是字节)
404 * Output :
405 * Other :
406 * Date :2012.05.23 14:19:49
407 *******************************************************************************/
408 static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
409 {
410 int i = 0;
411
412 if (lenToRead > sizeof(ADCxBuff))
413 return (INT32S)DRV_READ_FAIL;
414
415 for (i = 0; i < CHANNEL_COUNT; i++)
416 {
417 ADCxBuff[i] = GetSampleValue(i);
418 }
419 memcpy(buffer, ADCxBuff, lenToRead);
420
421 return (INT32S)DRV_NO_ERR;
422 }
423
424 /*******************************************************************************
425 * Function Name :static INT32S ADCxIoCtl(INT32U too, void *pd)
426 * Description :ADCX采样控制
427 * Input :too: 1-停止 AD采样
428 * 2-开始 AD采样 延迟直接退出。
429 * 3-开始 并等待采样缓冲填满后 停止采样。(UCOSII 系统下)
430 * Output :
431 * Other :
432 * Date :2012.05.23 14:19:51
433 *******************************************************************************/
434 static INT32S ADCxIoCtl(INT32U too, void *pd)
435 {
436 switch (too)
437 {
438 case 1 : StartAdc(DISABLE); break;
439 case 2 : StartAdc(ENABLE); break;
440 #ifdef UCOSII
441 case 3 :
442 StartAdc(ENABLE);
443 OSSemPend(adcSem, 0, &err);
444 break;
445 #endif
446 default : return(INT32S)DRV_CTRL_FAIL;
447
448 }
449 return (INT32S)DRV_NO_ERR;
450 }
451 /*******************************************************************************
452 * Function Name :INT32S ADCxInstall(UDFOperationsType *op)
453 * Description :安装ADCx驱动
454 * Input :
455 * Output :
456 * Other :
457 * Date :2012.05.13
458 *******************************************************************************/
459 INT32S ADCxInstall(UDFOperationsType *op)
460 {
461 op->devOpen = ADCxOpen;
462 op->devClose = ADCxClose;
463 op->devWrite = ADCxWrite;
464 op->devRead = ADCxRead;
465 op->devIoctl = ADCxIoCtl;
466
467 return (INT32S)DRV_NO_ERR;
468 }
469
470 /*******************************************************************************
471 * Function Name :INT32S ADCxNuinstall(UDFOperationsType *op)
472 * Description :卸载ADCx驱动
473 * Input :
474 * Output :
475 * Other :
476 * Date :2012.05.13
477 *******************************************************************************/
478 INT32S ADCxNuinstall(UDFOperationsType *op)
479 {
480 INT32S res = (INT32S)DRV_NO_ERR;
481 void *pd = NULL;
482
483 if (op->devClose != NULL)
484 res = op->devClose(pd);
485 op->devOpen = NULL;
486 op->devClose = NULL;
487 op->devWrite = NULL;
488 op->devRead = NULL;
489 op->devIoctl = NULL;
490
491 return res;
492 }
493
494 /*******************************************************************************
495 * Function Name :void ADC_IRQHandler(void)
496 * Description :ADC中断函数
497 * Input :
498 * Output :
499 * Other :
500 * Date :2012.05.24 14:49:49
501 *******************************************************************************/
502 void ADC_IRQHandler(void)
503 {
504 #ifdef UCOSII
505 OSIntEnter();
506 #endif
507 /* Clear ADC1 EOC pending interrupt bit */
508 ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC); //清除规则采样中断
509
510 if (index >= MAX_AD_SAMPLE_COUNTER)
511 {
512 StartAdc(DISABLE);
513 #ifdef UCOSII
514 OSSemPost(adcSem);
515 #endif
516 }
517 else
518 {
519 #if CHANNEL_COUNT > 0
520 ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_1);
521 #endif
522 #if CHANNEL_COUNT > 1
523 ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_2);
524 #endif
525 #if CHANNEL_COUNT > 2
526 ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_3);
527 #endif
528 #if CHANNEL_COUNT > 3
529 ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_4);
530 #endif
531 }
532 #ifdef UCOSII
533 OSIntExit();
534 #endif
535 }
头文件:
1 #ifndef _ADCxDrv_h_
2 #define _ADCxDrv_h_
3 #include "stm32f10x_adc.h"
4 #include "stm32f10x_dma.h"
5 #include "stm32f10x_gpio.h"
6 #include "stm32f10x_rcc.h"
7 #include "stm32f10x_nvic.h"
8 #include "driver.h"
9 #include
10
11
12 //#define ADC_DMA //DMA模式, 不定义为注入模式(最多为四路)
13
14 #define ADCx_SAMPLE_COUNT 10u //单通道采的点数
15
16
17 #define ADCx ADC1 //使用的ADC控制器
18 #define ADCx_DR_Address ((u32)0x4001244C)
19 #define RCC_APBXPeriph_ADCx RCC_APB2Periph_ADC1 //ADC1时钟
20
21
22 #define RCC_AHBPeriph_DMAx RCC_AHBPeriph_DMA1 //DMA1时钟
23 #define DMAx_Channelx DMA1_Channel1
24
25 #define RCC_APBXPeriph_GPIOX_1 RCC_APB2Periph_GPIOA //
26 #define RCC_APBXPeriph_GPIOX_2 RCC_APB2Periph_GPIOB //
27 #define RCC_APBXPeriph_GPIOX_3 RCC_APB2Periph_GPIOC //
28
29 #define ADCx_GPIOX_1 GPIOA
30 #define ADCx_GPIOX_2 GPIOB
31 #define ADCx_GPIOX_3 GPIOC
32
33 #define ADCx_GPIOX_PIN_CH0 GPIO_Pin_0 //通道端口GPIOX_1
34 #define ADCx_GPIOX_PIN_CH1 GPIO_Pin_1 //通道端口GPIOX_1
35 #define ADCx_GPIOX_PIN_CH2 GPIO_Pin_2 //通道端口GPIOX_1
36 #define ADCx_GPIOX_PIN_CH3 GPIO_Pin_3 //通道端口GPIOX_2
37 #define ADCx_GPIOX_PIN_CH4 GPIO_Pin_4 //通道端口GPIOX_2
38 #define ADCx_GPIOX_PIN_CH5 GPIO_Pin_5 //通道端口GPIOX_1
39 #define ADCx_GPIOX_PIN_CH6 GPIO_Pin_6 //通道端口GPIOX_1
40 #define ADCx_GPIOX_PIN_CH7 GPIO_Pin_7 //通道端口GPIOX_2
41 #define ADCx_GPIOX_PIN_CH8 GPIO_Pin_8 //通道端口GPIOX_2
42 #define ADCx_GPIOX_PIN_CH9 GPIO_Pin_9 //通道端口GPIOX_1
43 #define ADCx_GPIOX_PIN_CH10 GPIO_Pin_10 //通道端口GPIOX_1
44 #define ADCx_GPIOX_PIN_CH11 GPIO_Pin_11 //通道端口GPIOX_2
45 #define ADCx_GPIOX_PIN_CH12 GPIO_Pin_12 //通道端口GPIOX_2
46 #define ADCx_GPIOX_PIN_CH13 GPIO_Pin_13 //通道端口GPIOX_1
47 #define ADCx_GPIOX_PIN_CH14 GPIO_Pin_14 //通道端口GPIOX_1
48 #define ADCx_GPIOX_PIN_CH15 GPIO_Pin_15 //通道端口GPIOX_1
49
50 //注意 注入模式 最多先4路通道
51 #define ADCx_CHANNEL0_EN 0 //ADCx通道1 1:便能,0:失能
52 #define ADCx_CHANNEL1_EN 1 //ADCx通道2 1:便能,0:失能
53 #define ADCx_CHANNEL2_EN 0 //ADCx通道3 1:便能,0:失能
54 #define ADCx_CHANNEL3_EN 1 //ADCx通道4 1:便能,0:失能
55 #define ADCx_CHANNEL4_EN 0 //ADCx通道5 1:便能,0:失能
56 #define ADCx_CHANNEL5_EN 0 //ADCx通道6 1:便能,0:失能
57 #define ADCx_CHANNEL6_EN 0 //ADCx通道7 1:便能,0:失能
58 #define ADCx_CHANNEL7_EN 0 //ADCx通道8 1:便能,0:失能
59 #define ADCx_CHANNEL8_EN 0 //ADCx通道9 1:便能,0:失能
60 #define ADCx_CHANNEL9_EN 0 //ADCx通道10 1:便能,0:失能
61 #define ADCx_CHANNEL10_EN 0 //ADCx通道11 1:便能,0:失能
62 #define ADCx_CHANNEL11_EN 0 //ADCx通道12 1:便能,0:失能
63 #define ADCx_CHANNEL12_EN 0 //ADCx通道13 1:便能,0:失能
64 #define ADCx_CHANNEL13_EN 0 //ADCx通道14 1:便能,0:失能
65 #define ADCx_CHANNEL14_EN 0 //ADCx通道15 1:便能,0:失能
66 #define ADCx_CHANNEL15_EN 0 //ADCx通道16 1:便能,0:失能
67
68 //总端口数
69 #define CHANNEL_COUNT (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
70 ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
71 ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
72 ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN + \
73 ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN + \
74 ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
75 ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
76 ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )
77 //
78 #define ADCx_GPIOX_1_EN (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
79 ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
80 ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
81 ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN)
82
83 #define ADCx_GPIOX_2_EN (ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN)
84
85 #define ADCx_GPIOX_3_EN (ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
86 ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
87 ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )
88
89
90 #define ORDER_CH0 ADCx_CHANNEL0_EN
91 #define ORDER_CH1 (ADCx_CHANNEL1_EN + ORDER_CH0)
92 #define ORDER_CH2 (ADCx_CHANNEL2_EN + ORDER_CH1)
93 #define ORDER_CH3 (ADCx_CHANNEL3_EN + ORDER_CH2)
94 #define ORDER_CH4 (ADCx_CHANNEL4_EN + ORDER_CH3)
95 #define ORDER_CH5 (ADCx_CHANNEL5_EN + ORDER_CH4)
96 #define ORDER_CH6 (ADCx_CHANNEL6_EN + ORDER_CH5)
97 #define ORDER_CH7 (ADCx_CHANNEL7_EN + ORDER_CH6)
98 #define ORDER_CH8 (ADCx_CHANNEL8_EN + ORDER_CH7)
99 #define ORDER_CH9 (ADCx_CHANNEL9_EN + ORDER_CH8)
100 #define ORDER_CH10 (ADCx_CHANNEL10_EN + ORDER_CH9)
101 #define ORDER_CH11 (ADCx_CHANNEL11_EN + ORDER_CH10)
102 #define ORDER_CH12 (ADCx_CHANNEL12_EN + ORDER_CH11)
103 #define ORDER_CH13 (ADCx_CHANNEL13_EN + ORDER_CH12)
104 #define ORDER_CH14 (ADCx_CHANNEL14_EN + ORDER_CH13)
105 #define ORDER_CH15 (ADCx_CHANNEL15_EN + ORDER_CH14)
106
107 #define MAX_AD_SAMPLE_COUNTER (ADCx_SAMPLE_COUNT * CHANNEL_COUNT)
108
109
110
111 INT32S ADCxInstall(UDFOperationsType *op);
112 INT32S ADCxNuinstall(UDFOperationsType *op);
113
114
115
116
117
118 #endif
上一篇:Stm32f10x 新建工程详解
下一篇:Stm32f103 DAC 最低电流输出问题
推荐阅读最新更新时间:2024-03-16 15:24