在做有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