当前位置:首页 > 单片机 > 单片机
[导读]在做有AD模块项目的时候遇到几个问题:1, ADC配合DMA采样规则是怎样的。2, ADC在DMA采可否不连续采样,以提高有效采样使用率和降低功耗。3, 如何提高有效利用率和降低功耗,并减少CPU的占用时间。4, 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就可以了。


#defineADCx_CHANNEL0_EN1//ADCx通道11:便能,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

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭