[应用相关] stm32f103 adc 学习笔记

[复制链接]
 楼主| comparison 发表于 2019-7-16 16:11 | 显示全部楼层 |阅读模式
在做有ad模块项目的时候遇到几个问题: 1, adc配合dma采样规则是怎样的。
2, adc在dma采可否不连续采样,以提高有效采样使用率和降低功耗。
3, 如何提高有效利用率和降低功耗,并减少cpu的占用时间。
4, adc的如何多通道采样。

 楼主| comparison 发表于 2019-7-16 16:12 | 显示全部楼层
针对以上几个问题做解答。

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工作在强电磁的环境中可能会输出丢失部分数据的可能。

         这里就想到了用中断的方式,进行采样。无法用规则模式,因为只能用单次采样触发中断。由于无法确定第一个通道,这样同样会遇到数据错位的现象。所以这里使用注入模式进行中断出发。
 楼主| comparison 发表于 2019-7-16 16:12 | 显示全部楼层
有以下几个优点:

1,  可以最多4路为一组采样,每组采样结束后才产生一次中断,减少了进中断的次数。

2,  在读取数据时几路通道都是预先配置好的。某个变量存放指定某个指定通道。这样永远不可能出现错位现象。

由以总结 在4路及以下通道进行采样时,首选注入模式进行中断采样。超过4路及不是长时间工作的产品(几天以上不断电)可以考虑。

单路采样时,这两种方法都很可靠。

         最近刚好在学习uCosII系统,并参考了下通用驱动程序开发。附上ADC驱动代码,希望有所帮助。





  提示,在使用某路通道 只要 该通道宏定义置1就可以了。

#define ADCx_CHANNEL0_EN  1 //ADCx通道1  1:便能,0:失能

注意: 在使用注入模式时 最多使能4个通道。
 楼主| comparison 发表于 2019-7-16 16:12 | 显示全部楼层
  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. #include "ADCxDrv.h"

  32. //DMA采样缓冲区
  33. static volatile INT16U ADC_ConvertedValueTab[MAX_AD_SAMPLE_COUNTER] = {0};
  34. static INT16U ADCxBuff[CHANNEL_COUNT] = {0};        //缓冲区数据平均值
  35. static INT16U index = 0;

  36. #ifdef UCOSII
  37. static OS_EVENT *adcSem;
  38. static INT8U err;
  39. #endif

  40. //总采样时间(单位ms) = 读样个数 * 采样1个值所用时间 / 72mHz * 1000
  41. //static INT16U sampingTime = (INT16U)(CHANNEL_COUNT * ADCx_SAMPLE_COUNT *
  42. //                                                            239 * 5 / 9e3 + 1);                    

  43. /* Private macro -------------------------------------------------------------*/
  44. /* Private variables ---------------------------------------------------------*/
  45. ADC_InitTypeDef ADC_InitStructure;
  46. DMA_InitTypeDef DMA_InitStructure;
  47. NVIC_InitTypeDef NVIC_InitStructure;



  48. /*******************************************************************************
  49. * Function Name :INT16U GetSampleTemp(INT16U order)
  50. * Description   :获取采样到的数据,并进行平均
  51. * Input         :order:通道序列号
  52. * Output        :返回本通道 采样平均值
  53. * Other         :
  54. * Date          :2012.05.23  14:48:23
  55. *******************************************************************************/
  56. static INT16U GetSampleValue(INT16U order)
  57. {
  58.     u32 sum = 0;
  59.     u16 i = order;
  60.    
  61.     if (order >= CHANNEL_COUNT) return 0;    //序列号超出范围
  62.    
  63.     for (i = order; i < MAX_AD_SAMPLE_COUNTER; i+=CHANNEL_COUNT)
  64.     {
  65.         sum += ADC_ConvertedValueTab[i];
  66.     }
  67.     sum /= ADCx_SAMPLE_COUNT;
  68.    
  69.     return (u16)sum;
  70. }

  71. void StartAdc(FunctionalState stat)
  72. {
  73.     if (stat == ENABLE) index = 0;
  74.    
  75.     ADC_ITConfig(ADCx, ADC_IT_JEOC, stat);
  76.     ADC_Cmd(ADCx, stat);
  77. }


  78. /*******************************************************************************
  79. * Function Name :static INT32S ADCxOpen(void *pd)
  80. * Description   :
  81. * Input         :
  82. * Output        :
  83. * Other         :
  84. * Date          :2012.05.23  10:25:06
  85. *******************************************************************************/
  86. static INT32S ADCxOpen(void *pd)
  87. {
  88.     GPIO_InitTypeDef GPIO_InitStructure;
  89.     INT32U rccApb = 0;
  90.     INT16U gpioPin = 0;

  91.     /* Enable peripheral clocks ----------------------------------------------*/
  92.     /* Enable DMA1 and DMA2 clocks */
  93.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx, ENABLE);


  94. #if ADCx_GPIOX_1_EN
  95.     rccApb |= RCC_APBXPeriph_GPIOX_1;
  96. #endif

  97. #if ADCx_GPIOX_2_EN
  98.     rccApb |= RCC_APBXPeriph_GPIOX_2;
  99. #endif

  100. #if ADCx_GPIOX_3_EN
  101.     rccApb |= RCC_APBXPeriph_GPIOX_3;
  102. #endif

  103.     rccApb |= RCC_APBXPeriph_ADCx;
  104.     RCC_APB2PeriphClockCmd(rccApb, ENABLE);
  105.     RCC_ADCCLKConfig(RCC_PCLK2_Div8);

  106.    
  107. #if ADCx_GPIOX_1_EN
  108.     gpioPin = 0;
  109. #if ADCx_CHANNEL0_EN
  110.     gpioPin |= ADCx_GPIOX_PIN_CH0;
  111. #endif
  112. #if ADCx_CHANNEL1_EN
  113.     gpioPin |= ADCx_GPIOX_PIN_CH1;
  114. #endif
  115. #if ADCx_CHANNEL2_EN
  116.     gpioPin |= ADCx_GPIOX_PIN_CH2;
  117. #endif
  118. #if ADCx_CHANNEL3_EN
  119.     gpioPin |= ADCx_GPIOX_PIN_CH3;
  120. #endif
  121. #if ADCx_CHANNEL4_EN
  122.     gpioPin |= ADCx_GPIOX_PIN_CH4;
  123. #endif
  124. #if ADCx_CHANNEL5_EN
  125.     gpioPin |= ADCx_GPIOX_PIN_CH5;
  126. #endif
  127. #if ADCx_CHANNEL6_EN
  128.     gpioPin |= ADCx_GPIOX_PIN_CH6;
  129. #endif
  130. #if ADCx_CHANNEL7_EN
  131.     gpioPin |= ADCx_GPIOX_PIN_CH7;
  132. #endif
  133.     GPIO_InitStructure.GPIO_Pin = gpioPin;
  134.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  135.     GPIO_Init(ADCx_GPIOX_1, &GPIO_InitStructure);
  136. #endif

  137.          
  138. #if ADCx_GPIOX_2_EN
  139.     gpioPin = 0;
  140. #if ADCx_CHANNEL8_EN
  141.     gpioPin |= ADCx_GPIOX_PIN_CH8;
  142. #endif
  143. #if ADCx_CHANNEL9_EN
  144.     gpioPin |= ADCx_GPIOX_PIN_CH9;
  145. #endif
  146.       GPIO_InitStructure.GPIO_Pin = gpioPin;
  147.       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  148.       GPIO_Init(ADCx_GPIOX_2, &GPIO_InitStructure);
  149. #endif


  150. #if ADCx_GPIOX_3_EN
  151.     gpioPin = 0;
  152. #if ADCx_CHANNEL10_EN
  153.       gpioPin |= ADCx_GPIOX_PIN_CH10;
  154. #endif
  155. #if ADCx_CHANNEL11_EN
  156.       gpioPin |= ADCx_GPIOX_PIN_CH11;
  157. #endif
  158. #if ADCx_CHANNEL12_EN
  159.       gpioPin |= ADCx_GPIOX_PIN_CH12;
  160. #endif
  161. #if ADCx_CHANNEL13_EN
  162.       gpioPin |= ADCx_GPIOX_PIN_CH13;
  163. #endif
  164. #if ADCx_CHANNEL14_EN
  165.       gpioPin |= ADCx_GPIOX_PIN_CH14;
  166. #endif
  167. #if ADCx_CHANNEL15_EN
  168.       gpioPin |= ADCx_GPIOX_PIN_CH15;
  169. #endif
  170.     GPIO_InitStructure.GPIO_Pin = gpioPin;
  171.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  172.     GPIO_Init(ADCx_GPIOX_3, &GPIO_InitStructure);
  173. #endif

  174. /* ADCx configuration ---------------------------------------------------*/
  175. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  176. ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  177. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  178. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  179. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  180. ADC_InitStructure.ADC_NbrOfChannel = CHANNEL_COUNT;
  181. ADC_Init(ADCx, &ADC_InitStructure);


  182. #ifdef ADC_DMA
  183.     /* ADCx regular channels configuration */
  184. #if ADCx_CHANNEL0_EN
  185.     ADC_RegularChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);  
  186. #endif
  187. #if ADCx_CHANNEL1_EN
  188.     ADC_RegularChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
  189. #endif
  190. #if ADCx_CHANNEL2_EN
  191.     ADC_RegularChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);  
  192. #endif
  193. #if ADCx_CHANNEL3_EN
  194.     ADC_RegularChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
  195. #endif
  196. #if ADCx_CHANNEL4_EN
  197.     ADC_RegularChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);  
  198. #endif
  199. #if ADCx_CHANNEL5_EN
  200.     ADC_RegularChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
  201. #endif
  202. #if ADCx_CHANNEL6_EN
  203.     ADC_RegularChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);  
  204. #endif
  205. #if ADCx_CHANNEL7_EN
  206.     ADC_RegularChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
  207. #endif
  208. #if ADCx_CHANNEL8_EN
  209.     ADC_RegularChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);  
  210. #endif
  211. #if ADCx_CHANNEL9_EN
  212.     ADC_RegularChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
  213. #endif
  214. #if ADCx_CHANNEL10_EN
  215.     ADC_RegularChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);  
  216. #endif
  217. #if ADCx_CHANNEL11_EN
  218.     ADC_RegularChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
  219. #endif
  220. #if ADCx_CHANNEL12_EN
  221.     ADC_RegularChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);  
  222. #endif
  223. #if ADCx_CHANNEL13_EN
  224.     ADC_RegularChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
  225. #endif
  226. #if ADCx_CHANNEL14_EN
  227.     ADC_RegularChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);  
  228. #endif
  229. #if ADCx_CHANNEL15_EN
  230.     ADC_RegularChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
  231. #endif


  232.     /* DMA1 channel1 configuration -------------------------------------------*/
  233.     DMA_DeInit(DMAx_Channelx);
  234.     DMA_InitStructure.DMA_PeripheralBaseAddr = ADCx_DR_Address;
  235.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValueTab;
  236.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  237.     DMA_InitStructure.DMA_BufferSize = (u32)MAX_AD_SAMPLE_COUNTER;        //存储的个数
  238.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  239.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  240.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  241.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  242.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  243.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  244.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  245.     DMA_Init(DMAx_Channelx, &DMA_InitStructure);

  246.     /* Enable ADCx DMA */
  247.     ADC_DMACmd(ADCx, ENABLE);

  248.     /* Enable DMA1 channel1 */
  249.     DMA_Cmd(DMAx_Channelx, ENABLE);
  250. #else

  251.     /* Set injected sequencer length */
  252.     ADC_InjectedSequencerLengthConfig(ADC1, CHANNEL_COUNT);

  253. #if ADCx_CHANNEL0_EN
  254.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_0, ORDER_CH0, ADC_SampleTime_239Cycles5);  
  255. #endif
  256. #if ADCx_CHANNEL1_EN
  257.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_1, ORDER_CH1, ADC_SampleTime_239Cycles5);
  258. #endif
  259. #if ADCx_CHANNEL2_EN
  260.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_2, ORDER_CH2, ADC_SampleTime_239Cycles5);  
  261. #endif
  262. #if ADCx_CHANNEL3_EN
  263.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_3, ORDER_CH3, ADC_SampleTime_239Cycles5);
  264. #endif
  265. #if ADCx_CHANNEL4_EN
  266.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_4, ORDER_CH4, ADC_SampleTime_239Cycles5);  
  267. #endif
  268. #if ADCx_CHANNEL5_EN
  269.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_5, ORDER_CH5, ADC_SampleTime_239Cycles5);
  270. #endif
  271. #if ADCx_CHANNEL6_EN
  272.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_6, ORDER_CH6, ADC_SampleTime_239Cycles5);  
  273. #endif
  274. #if ADCx_CHANNEL7_EN
  275.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_7, ORDER_CH7, ADC_SampleTime_239Cycles5);
  276. #endif
  277. #if ADCx_CHANNEL8_EN
  278.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_8, ORDER_CH8, ADC_SampleTime_239Cycles5);  
  279. #endif
  280. #if ADCx_CHANNEL9_EN
  281.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_9, ORDER_CH9, ADC_SampleTime_239Cycles5);
  282. #endif
  283. #if ADCx_CHANNEL10_EN
  284.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_10, ORDER_CH10, ADC_SampleTime_239Cycles5);   
  285. #endif
  286. #if ADCx_CHANNEL11_EN
  287.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_11, ORDER_CH11, ADC_SampleTime_239Cycles5);
  288. #endif
  289. #if ADCx_CHANNEL12_EN
  290.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_12, ORDER_CH12, ADC_SampleTime_239Cycles5);   
  291. #endif
  292. #if ADCx_CHANNEL13_EN
  293.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_13, ORDER_CH13, ADC_SampleTime_239Cycles5);
  294. #endif
  295. #if ADCx_CHANNEL14_EN
  296.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_14, ORDER_CH14, ADC_SampleTime_239Cycles5);   
  297. #endif
  298. #if ADCx_CHANNEL15_EN
  299.     ADC_InjectedChannelConfig(ADCx, ADC_Channel_15, ORDER_CH15, ADC_SampleTime_239Cycles5);
  300. #endif

  301.     ADC_AutoInjectedConvCmd(ADCx, ENABLE);
  302.     ADC_ITConfig(ADCx, ADC_IT_JEOC, ENABLE);

  303.     /* Configure and enable ADC interrupt */
  304.     NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
  305.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  306.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  307.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  308.     NVIC_Init(&NVIC_InitStructure);

  309.     StartAdc(DISABLE);
  310. #endif

  311.     /* Enable ADCx */
  312.     ADC_Cmd(ADCx, ENABLE);

  313.     /* Enable ADCx reset calibaration register */   
  314.     ADC_ResetCalibration(ADCx);
  315.     /* Check the end of ADCx reset calibration register */
  316.     while(ADC_GetResetCalibrationStatus(ADCx));

  317.     /* Start ADCx calibaration */
  318.     ADC_StartCalibration(ADCx);
  319.     /* Check the end of ADCx calibration */
  320.     while(ADC_GetCalibrationStatus(ADCx));
  321.    
  322. #ifdef UCOSII
  323.     adcSem = OSSemCreate(0);
  324. #endif
  325.     return (INT32S)DRV_NO_ERR;
  326. }

  327. /*******************************************************************************
  328. * Function Name :static INT32S ADCxClose(void *pd)
  329. * Description   :
  330. * Input         :
  331. * Output        :
  332. * Other         :
  333. * Date          :2012.05.24  09:10:25
  334. *******************************************************************************/
  335. static INT32S ADCxClose(void *pd)
  336. {   
  337.     ADC_SoftwareStartConvCmd(ADCx, DISABLE);
  338.    
  339.     /* Enable DMA1 channel1 */
  340.     DMA_Cmd(DMAx_Channelx, DISABLE);

  341.     /* Enable ADCx DMA */
  342.     ADC_DMACmd(ADCx, DISABLE);

  343.     StartAdc(DISABLE);

  344.     return (INT32S)DRV_NO_ERR;
  345. }

  346. /*******************************************************************************
  347. * Function Name :static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
  348. * Description   :无效
  349. * Input         :
  350. * Output        :
  351. * Other         :
  352. * Date          :2012.05.23  14:19:47
  353. *******************************************************************************/
  354. static INT32S ADCxWrite(INT8S *buffer, INT32U lenToWrite, INT8U waitType)
  355. {
  356.     return (INT32S)DRV_NO_ERR;
  357. }

  358. /*******************************************************************************
  359. * Function Name :static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
  360. * Description   :读取采样到的数据
  361. * Input         :*buffer:采样缓冲。lenToRead:采取长度(单位是字节)
  362. * Output        :
  363. * Other         :
  364. * Date          :2012.05.23  14:19:49
  365. *******************************************************************************/
  366. static INT32S ADCxRead(INT8S *buffer, INT32U blen, INT32U lenToRead, INT8U waitType)
  367. {   
  368.     int i = 0;

  369.     if (lenToRead > sizeof(ADCxBuff))
  370.         return (INT32S)DRV_READ_FAIL;
  371.    
  372.     for (i = 0; i < CHANNEL_COUNT; i++)
  373.     {
  374.         ADCxBuff[i] = GetSampleValue(i);
  375.     }
  376.     memcpy(buffer, ADCxBuff, lenToRead);
  377.    
  378.     return (INT32S)DRV_NO_ERR;
  379. }

  380. /*******************************************************************************
  381. * Function Name :static INT32S ADCxIoCtl(INT32U too, void *pd)
  382. * Description   :ADCX采样控制
  383. * Input         :too:     1-停止 AD采样
  384. *                        2-开始    AD采样 延迟直接退出。
  385. *                        3-开始 并等待采样缓冲填满后 停止采样。(UCOSII 系统下)
  386. * Output        :
  387. * Other         :
  388. * Date          :2012.05.23  14:19:51
  389. *******************************************************************************/
  390. static INT32S ADCxIoCtl(INT32U too, void *pd)
  391. {
  392.     switch (too)
  393.     {
  394.         case 1 : StartAdc(DISABLE);    break;
  395.         case 2 : StartAdc(ENABLE);    break;
  396. #ifdef UCOSII   
  397.         case 3 :
  398.             StartAdc(ENABLE);
  399.             OSSemPend(adcSem, 0, &err);
  400.             break;
  401. #endif
  402.         default : return(INT32S)DRV_CTRL_FAIL;

  403.     }
  404.     return (INT32S)DRV_NO_ERR;
  405. }
  406. /*******************************************************************************
  407. * Function Name :INT32S ADCxInstall(UDFOperationsType *op)
  408. * Description   :安装ADCx驱动
  409. * Input         :
  410. * Output        :
  411. * Other         :
  412. * Date          :2012.05.13
  413. *******************************************************************************/
  414. INT32S ADCxInstall(UDFOperationsType *op)
  415. {
  416.     op->devOpen = ADCxOpen;
  417.     op->devClose = ADCxClose;
  418.     op->devWrite = ADCxWrite;
  419.     op->devRead = ADCxRead;
  420.     op->devIoctl = ADCxIoCtl;
  421.    
  422.     return (INT32S)DRV_NO_ERR;
  423. }

  424. /*******************************************************************************
  425. * Function Name :INT32S ADCxNuinstall(UDFOperationsType *op)
  426. * Description   :卸载ADCx驱动
  427. * Input         :
  428. * Output        :
  429. * Other         :
  430. * Date          :2012.05.13
  431. *******************************************************************************/
  432. INT32S ADCxNuinstall(UDFOperationsType *op)
  433. {
  434.     INT32S res = (INT32S)DRV_NO_ERR;
  435.     void *pd = NULL;
  436.    
  437.     if (op->devClose != NULL)
  438.         res = op->devClose(pd);
  439.     op->devOpen = NULL;
  440.     op->devClose = NULL;
  441.     op->devWrite = NULL;
  442.     op->devRead = NULL;
  443.     op->devIoctl = NULL;

  444.     return res;
  445. }

  446. /*******************************************************************************
  447. * Function Name :void ADC_IRQHandler(void)
  448. * Description   :ADC中断函数
  449. * Input         :
  450. * Output        :
  451. * Other         :
  452. * Date          :2012.05.24  14:49:49
  453. *******************************************************************************/
  454. void ADC_IRQHandler(void)
  455. {
  456. #ifdef UCOSII
  457.     OSIntEnter();
  458. #endif
  459.     /* Clear ADC1 EOC pending interrupt bit */
  460.     ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);    //清除规则采样中断

  461.     if (index >= MAX_AD_SAMPLE_COUNTER)
  462.     {
  463.         StartAdc(DISABLE);
  464. #ifdef UCOSII        
  465.         OSSemPost(adcSem);
  466. #endif        
  467.     }
  468.     else
  469.     {
  470. #if CHANNEL_COUNT > 0
  471.         ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_1);
  472. #endif
  473. #if  CHANNEL_COUNT > 1
  474.         ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_2);
  475. #endif
  476. #if  CHANNEL_COUNT > 2
  477.         ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_3);
  478. #endif
  479. #if  CHANNEL_COUNT > 3
  480.         ADC_ConvertedValueTab[index++] = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_4);
  481. #endif
  482.     }
  483. #ifdef UCOSII
  484.     OSIntExit();
  485. #endif
  486. }
 楼主| comparison 发表于 2019-7-16 16:13 | 显示全部楼层
头文件:
  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. //#define ADC_DMA                //DMA模式, 不定义为注入模式(最多为四路)

  11. #define ADCx_SAMPLE_COUNT        10u                        //单通道采的点数


  12. #define ADCx                     ADC1                    //使用的ADC控制器
  13. #define ADCx_DR_Address            ((u32)0x4001244C)
  14. #define RCC_APBXPeriph_ADCx    RCC_APB2Periph_ADC1        //ADC1时钟


  15. #define RCC_AHBPeriph_DMAx        RCC_AHBPeriph_DMA1        //DMA1时钟
  16. #define DMAx_Channelx            DMA1_Channel1

  17. #define RCC_APBXPeriph_GPIOX_1    RCC_APB2Periph_GPIOA    //
  18. #define RCC_APBXPeriph_GPIOX_2    RCC_APB2Periph_GPIOB    //
  19. #define RCC_APBXPeriph_GPIOX_3    RCC_APB2Periph_GPIOC    //

  20. #define ADCx_GPIOX_1             GPIOA
  21. #define ADCx_GPIOX_2            GPIOB
  22. #define ADCx_GPIOX_3            GPIOC

  23. #define ADCx_GPIOX_PIN_CH0        GPIO_Pin_0                //通道端口GPIOX_1
  24. #define ADCx_GPIOX_PIN_CH1        GPIO_Pin_1                //通道端口GPIOX_1
  25. #define ADCx_GPIOX_PIN_CH2        GPIO_Pin_2                //通道端口GPIOX_1
  26. #define ADCx_GPIOX_PIN_CH3        GPIO_Pin_3                //通道端口GPIOX_2
  27. #define ADCx_GPIOX_PIN_CH4        GPIO_Pin_4                //通道端口GPIOX_2
  28. #define ADCx_GPIOX_PIN_CH5        GPIO_Pin_5                //通道端口GPIOX_1
  29. #define ADCx_GPIOX_PIN_CH6        GPIO_Pin_6                //通道端口GPIOX_1
  30. #define ADCx_GPIOX_PIN_CH7        GPIO_Pin_7                //通道端口GPIOX_2
  31. #define ADCx_GPIOX_PIN_CH8        GPIO_Pin_8                //通道端口GPIOX_2
  32. #define ADCx_GPIOX_PIN_CH9        GPIO_Pin_9                //通道端口GPIOX_1
  33. #define ADCx_GPIOX_PIN_CH10    GPIO_Pin_10                //通道端口GPIOX_1
  34. #define ADCx_GPIOX_PIN_CH11    GPIO_Pin_11                //通道端口GPIOX_2
  35. #define ADCx_GPIOX_PIN_CH12    GPIO_Pin_12                //通道端口GPIOX_2
  36. #define ADCx_GPIOX_PIN_CH13    GPIO_Pin_13                //通道端口GPIOX_1
  37. #define ADCx_GPIOX_PIN_CH14    GPIO_Pin_14                //通道端口GPIOX_1
  38. #define ADCx_GPIOX_PIN_CH15    GPIO_Pin_15                //通道端口GPIOX_1

  39. //注意 注入模式 最多先4路通道
  40. #define ADCx_CHANNEL0_EN        0    //ADCx通道1  1:便能,0:失能
  41. #define ADCx_CHANNEL1_EN        1    //ADCx通道2  1:便能,0:失能
  42. #define ADCx_CHANNEL2_EN        0    //ADCx通道3  1:便能,0:失能
  43. #define ADCx_CHANNEL3_EN        1    //ADCx通道4  1:便能,0:失能
  44. #define ADCx_CHANNEL4_EN        0    //ADCx通道5  1:便能,0:失能
  45. #define ADCx_CHANNEL5_EN        0    //ADCx通道6  1:便能,0:失能
  46. #define ADCx_CHANNEL6_EN        0    //ADCx通道7  1:便能,0:失能
  47. #define ADCx_CHANNEL7_EN        0    //ADCx通道8  1:便能,0:失能
  48. #define ADCx_CHANNEL8_EN        0    //ADCx通道9  1:便能,0:失能
  49. #define ADCx_CHANNEL9_EN        0    //ADCx通道10  1:便能,0:失能
  50. #define ADCx_CHANNEL10_EN        0    //ADCx通道11  1:便能,0:失能
  51. #define ADCx_CHANNEL11_EN        0    //ADCx通道12  1:便能,0:失能
  52. #define ADCx_CHANNEL12_EN        0    //ADCx通道13  1:便能,0:失能
  53. #define ADCx_CHANNEL13_EN        0    //ADCx通道14  1:便能,0:失能
  54. #define ADCx_CHANNEL14_EN        0    //ADCx通道15  1:便能,0:失能
  55. #define ADCx_CHANNEL15_EN        0    //ADCx通道16  1:便能,0:失能

  56. //总端口数
  57. #define CHANNEL_COUNT        (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
  58.                             ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
  59.                             ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
  60.                             ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN + \
  61.                             ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN + \
  62.                             ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
  63.                             ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
  64.                             ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )
  65. //                        
  66. #define ADCx_GPIOX_1_EN    (ADCx_CHANNEL0_EN + ADCx_CHANNEL1_EN + \
  67.                             ADCx_CHANNEL2_EN + ADCx_CHANNEL3_EN + \
  68.                             ADCx_CHANNEL4_EN + ADCx_CHANNEL5_EN + \
  69.                             ADCx_CHANNEL6_EN + ADCx_CHANNEL7_EN)

  70. #define ADCx_GPIOX_2_EN    (ADCx_CHANNEL8_EN + ADCx_CHANNEL9_EN)

  71. #define ADCx_GPIOX_3_EN    (ADCx_CHANNEL10_EN + ADCx_CHANNEL11_EN + \
  72.                             ADCx_CHANNEL12_EN + ADCx_CHANNEL13_EN + \
  73.                             ADCx_CHANNEL14_EN + ADCx_CHANNEL15_EN )


  74. #define ORDER_CH0            ADCx_CHANNEL0_EN
  75. #define ORDER_CH1            (ADCx_CHANNEL1_EN + ORDER_CH0)
  76. #define ORDER_CH2            (ADCx_CHANNEL2_EN + ORDER_CH1)
  77. #define ORDER_CH3            (ADCx_CHANNEL3_EN + ORDER_CH2)
  78. #define ORDER_CH4            (ADCx_CHANNEL4_EN + ORDER_CH3)
  79. #define ORDER_CH5            (ADCx_CHANNEL5_EN + ORDER_CH4)
  80. #define ORDER_CH6            (ADCx_CHANNEL6_EN + ORDER_CH5)
  81. #define ORDER_CH7            (ADCx_CHANNEL7_EN + ORDER_CH6)
  82. #define ORDER_CH8            (ADCx_CHANNEL8_EN + ORDER_CH7)
  83. #define ORDER_CH9            (ADCx_CHANNEL9_EN + ORDER_CH8)
  84. #define ORDER_CH10            (ADCx_CHANNEL10_EN + ORDER_CH9)
  85. #define ORDER_CH11            (ADCx_CHANNEL11_EN + ORDER_CH10)
  86. #define ORDER_CH12            (ADCx_CHANNEL12_EN + ORDER_CH11)
  87. #define ORDER_CH13            (ADCx_CHANNEL13_EN + ORDER_CH12)
  88. #define ORDER_CH14            (ADCx_CHANNEL14_EN + ORDER_CH13)
  89. #define ORDER_CH15            (ADCx_CHANNEL15_EN + ORDER_CH14)

  90. #define MAX_AD_SAMPLE_COUNTER (ADCx_SAMPLE_COUNT * CHANNEL_COUNT)



  91. INT32S ADCxInstall(UDFOperationsType *op);
  92. INT32S ADCxNuinstall(UDFOperationsType *op);





  93. #endif

八层楼 发表于 2019-8-9 11:28 | 显示全部楼层
非常感谢楼主分享
观海 发表于 2019-8-9 11:33 | 显示全部楼层
非常感谢楼主分享
guanjiaer 发表于 2019-8-9 11:37 | 显示全部楼层
非常感谢楼主分享
heimaojingzhang 发表于 2019-8-9 11:47 | 显示全部楼层
感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

417

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部