Stm32f103 ADC 学习笔记

news/2024/12/29 20:34:26/
原文地址为: Stm32f103 ADC 学习笔记

在做有AD模块项目的时候遇到几个问题:

1,  ADC配合DMA采样规则是怎样的。

2,  ADC在DMA采可否不连续采样,以提高有效采样使用率和降低功耗。

3,  如何提高有效利用率和降低功耗,并减少CPU的占用时间。

4,  ADC的如何多通道采样。

针对以上几个问题做解答。

ADC的采样模式主要分两个:规则采样和注入采样。规则模式可采样16个通道,注入模式最多只能4个通道。

配合DMA使用时主要是用规则采样模式。在初始化时配置采样端口为规则采样通道即可如下:

列:         ADC_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 <string.h>
 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

 

 


转载请注明本文地址: Stm32f103 ADC 学习笔记

http://www.ppmy.cn/news/481906.html

相关文章

Zynq Ultrascale+ RF Data Coverter IP配置 - ADC

Zynq Ultrascale RF Data Coverter IP配置中的有关概念-ADC ADC xczu28dr-ffvg1517-2共有8个ADC,分布在4个Tile上&#xff0c;图为tile225&#xff0c;另外三个tile为226、227、228 4个tile各自拥有一个独立的PLL。2个12bit/DAC,2个mixer&#xff0c;Tile中的mixer是用于I/Q混…

单片机ADC0808,DAC0832信号发生器

1. 设计内容和设计要求 1.1 设计内容 利用AT89C52单片机、DAC0832、ADC0808设计信号发生器&#xff0c;能够产生固定幅值的方波、锯齿波、三角波及正弦波。要求能够调节信号的幅度及频率&#xff0c;并在波形切换过程中&#xff0c;能够给予相应的指示。其中幅值采用DAC0832进行…

linux adc时钟设置,linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟

linux设备驱动归纳总结(十三)&#xff1a;1.触摸屏与ADC时钟 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 这节的内容说不上是驱动&#xff0c;只是写个代码让触摸屏能够工作&#xff0c;随便介绍一下时钟子系统(我不知道这样叫合…

10个ADC滤波算法

1、限幅滤波法&#xff08;又称程序判断滤波法&#xff09; A、方法&#xff1a; 根据经验判断,确定两次采样允许的最大偏差值&#xff08;设为A&#xff09;每次检测到新值时判断&#xff1a; 如果本次值与上次值之差<A,则本次值有效 如果本次值与上次值之差>A,则…

9、ADC

1、12位ADC是一种逐次逼近型模拟数字转换器。 它有多达18个通道&#xff0c;可测量16个外部和2个内部信号源。 各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入…

震旦adc225扫描到u盘_复印机扫描安装设置

网络扫描设置与使用简易操作手册 复印机扫描到电脑安装视频 网络扫描设置与使用 一.复印机端设置IP地址、子网掩码、网关: 1. 先按操作面板上的“效用/计数器”键 2.按“管理员管理”键 3.输入管理员密码,默认为“00000000”然后按“输入” 4.选择“管理员2” 5.选择“网…

【Vue3 页面美化】常用组件库推荐

Vue 作为一款深受广大群众喜欢的前端框架&#xff0c;拥有众多优秀的开源 UI 组件库&#xff0c;这里整理了一下供大家参考。 这几套框架主要用于后台管理系统和移动端的制作&#xff0c;方便开发者快速开发。 一、PC 端 UI 库 1.1 Element Plus 官网地址&#xff1a;https…

MT4开户平台交易注意事项有哪些?

很多投资者都会选择MT4平台进行开户交易&#xff0c;毕竟MT4平台的起步时间比较早&#xff0c;对一些关注资金安全的投资者来说&#xff0c;MT4平台无疑是他们最佳的选择&#xff0c;那么&#xff0c;在MT4开户平台交易就一定不会发生失误吗&#xff1f;答案就是&#xff1a;不…