Stm32f103 ADC 学习笔记

发布者:灵感之翼最新更新时间:2016-12-08 来源: eefocus关键字:Stm32f103  ADC 手机看文章 扫描二维码
随时随地手机看文章

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



关键字:Stm32f103  ADC 引用地址:Stm32f103 ADC 学习笔记

上一篇:Stm32f10x 新建工程详解
下一篇:Stm32f103 DAC 最低电流输出问题

推荐阅读最新更新时间:2024-03-16 15:24

汽车电源的监视和开关
在如今的汽车中,为了提高舒适度和行车体验而设计了座椅加热、空调、导航、信息娱乐、行车安全等系统,从这些系统很容易理解在车中为各种功能供电的电子系统的好处。现在我们很难想像仅仅 100 多年以前的景象,那时,在汽油动力汽车中,一个电子组件都没有。在世纪交替时期的汽车开始有了手摇曲柄,前灯开始用乙炔气照明,也可以用铃声向行人发出提示信息了。如今的汽车正处于彻底变成电子系统的交界点,最大限度减少了机械系统的采用,正在成为人们生活中最大、最昂贵的“数字化工具”。由于可用性和环保原因,以及提高内燃型、混合动力型和全电动型汽车行车安全的需求,市场逐步减少了对汽油的依赖,这正是“数字化”转变的驱动力。 随着越来越多的机械系统被电子系统取代,
[汽车电子]
STM32F103RCT6第一个程序——跑马灯程序
下面简单介绍下跑马灯程序主要需要配置的方面: 1. 配置GPIO模式 CRL和CRH寄存器用于配置STM32的IO口的模式和速率; GPIO有8种工作模式: 1、输入浮空 2、输入上拉 3、输入下拉 4、模拟输入 5、开漏输出 6、推挽输出 7、推挽式复用功能 8、开漏复用功能 对应代码如下: typedef enum { GPIO_Mode_AIN=0x0, 模拟输入 GPIO_Mode_IN_FLOATING=0x4, 浮空输入 GPIO_Mode_IPD=0x28, 下拉输入 GPIO_Mode_IPU=0x48, 上拉输入 GPIO_Mode_OUT_OD=0x14, 开漏输出
[单片机]
STM32 ADC详解
01、ADC简介 ADC是Analog-to-DigitalConverter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。 从STM32F207的数据手册中下图看到,STM32F207VC有3个精度为12bit的ADC控制器,有16个外部通道,而144脚的STM32F207Zx和176脚的STM32F207Ix因为带PF脚,所以多8个通道,为24个外部通道。各通道的A/D转换可以单次、连续、扫描或间断执行,ADC转换的结果可以左对齐或右对齐储存在16位数据寄存器中。 02、STM32的ADC外设 上面说
[单片机]
STM32 <font color='red'>ADC</font>详解
单片机 ADC采集电压
/********************************************* 函数名:Adc_Configuration 功 能:ADC初始化配置 形 参: 返回值: 备 注: 作 者:薛建强 时 间:2019/06/06 **********************************************/ void Adc_Configuration void #if Config_ADC_Inti #if (Config_ADC_Inti_CH & 0x01) == 1 Enable_ADC_AIN0 // P1.7 #endif #if ((Config_ADC_Inti_CH 1) & 0x01
[单片机]
ADC0809与MCS-51单片机连接电路的设计和实现
ADC0809与MCS-51的连接电路   ADC0809与MCS-51单片机的连接如图9.10所示。电路连接主要涉及两个问题。一是8路模拟信号通道的选择,二是A/D转换完成后转换数据的传送。   MCS51是指由美国INTEL公司(对了,就是大名鼎鼎的INTEL)生产的一系列单片机的总称,这一系列单片机包括了好些品种,如8031,8051,8751,8032,8052,8752等,其中8051是最早最典型的产品,该系列其它单片机都是在8051的基础上进行功能的增、减、改变而来的,所以人们习惯于用8051来称呼MCS51系列单片机,而8031是前些年在我国最流行的单片机,所以很多场合会看到8031的名称。   1. 8路
[单片机]
<font color='red'>ADC</font>0809与MCS-51单片机连接电路的设计和实现
信号处理机的高速ADC模块动态性能在线测试
       摘 要 :在设计信号处理机的工作中,需要分析模数转换电路模块对整个系统的影响。本文介绍了一种基于DSP技术在线测试信号处理机的高速ADC转换电路动态性能参数的方法。该方法利用信号处理机的本身的DSP数据采集系统,实时采集标准测试信号。再利用matlab软件对数据进行频谱分析,计算出高速ADC模块的SENAD,SNR 等几个主要的动态参数。实现了电路板的ADC器件及周边电路的性能进行在线评估,对工程实践有一定的指导作用。    关键字: ADC;动态性能;DSP;matlab;在线测试   高速ADC是信号处理机的不可欠缺的组成部分,其性能的好坏对信号处理系统的整体性能也至关重要。通常ADC的技术参数是由生产厂商
[模拟电子]
信号处理机的高速<font color='red'>ADC</font>模块动态性能在线测试
降低设备功耗的方法 - 精确测量
有人预言,全世界的能量需求很可能超出了所供给的能量。美国能源部估计,预计美国总的能源消耗在2035年将增加30%,达到5万亿千瓦,而在同一时期计划开发的能源,包括可再生能源,增长率仅有22%。 此外,对能源管理的策略则是非常原始和低效的,结果降低了能源分配过程中的可靠性和稳定性。工程师们正努力改善所有电子产品中能量的利用效率,包括商用设备、家用设备、工业电机,以及网络设备。然而,也需要知道在一个闭环系统中能量是怎样被消耗来产生有益作用和减少浪费的。改善效率只是众多因素中的一个。改变消费者对效率的不关心可以通过功耗智能监视来实现,它可以给出节能的选择。 精确的功耗测量和持续监视产生的数据可以提交给本地数据和控制网络。一旦数据到达
[测试测量]
降低设备功耗的方法 - 精确测量
STM32F103_外部RAM用作运存
概述 SRAM的简介 折腾过电脑的朋友都知道,当电脑运行比较卡的时候,我们可以通过给电脑加装内存条来改善电脑的性能。那么号称微型计算机的单片机能不能像电脑一样加装内存条呢?装内存条倒是不行,但是我们可以给单片机外加和内存条效果一样的SRAM来提升单片机的性能。下面以STM32F407ZGT6单片机来讲解一下来扩展外部SRAM。 原理:给STM32芯片扩展内存与给PC扩展内存的原理是一样的,只是PC上一般以内存条的形式扩展,内存条实质是由多个内存颗粒(即SRAM芯片)组成的通用标准模块,而STM32直接与SRAM芯片连接。 SRAM,型号IS62WV51216,管脚图如下: IS62WV51216的管脚总的来说大致分为:
[单片机]
<font color='red'>STM32F103</font>_外部RAM用作运存
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved