你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 6633|回复: 19

STM32F103VE AD转换跨界问题

[复制链接]

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2011-12-13 16:47:47 | 显示全部楼层 |阅读模式
 用STM32进行4通道ADC转换,采用DMA方式。基准源为2500mv,12位AD采样, 采样电压使用范围为120-750mv,经测试在三段内出现非常大采样误差,大约分别是154-164mv,308-318mv,620-630mv;其他范围采样非常好,经过分析发现这三个段正好在跨在AD进位点,155mv--255(2^8),312mv--512(2^9),625mv--1024(2^10)这三个点。
155mv附近测试数据如下:
处理器采样结果                万用表测量结果
145.16                                143.75
149.15                             147.76
151.42                                150.21
153.75                                152.52
155.04                                154.9
155.36                                155.73
155.59                                157.75
155.64                                159.23
155.78                                161.14
156.21                                161.68
157.36                                162.7
159.89                                163.86
163.24                                164.73
166.05                                165.57
167.78                                166.42
 
误差就出现在,电压在154-164mv范围内采样出的电平都在停止不前(或者说增加变缓),直到电压达到166时,采样恢复正常。其他2个点都是这种情况。
请问有哪位高手给指导下,问题出现在哪儿?我换过通道口没有改善,电压信号原来是由传感器产生,后面改由电位器调节出电平无改善。采样时间修改无改善,测量通道修改为1无改善。换处理器103VE、103VC、107VC无改善
回复

使用道具 举报

3

主题

185

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2011-12-13 21:40:38 | 显示全部楼层

回复:STM32F103VE AD转换跨界问题

你说的这种情况,还真没有遇到过,你可以看看你的RC电路的参数,是不是这个原因。
1、你用一个通道来测量,不用DMA方式,看看是否出现这种情况。先确定是硬件的问题还是软件的问题。
2、看看输出的AD值是否正常,不要处理AD值,看原始的AD值。
回复 支持 反对

使用道具 举报

134

主题

4489

回帖

239

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2011-12-13 21:43:01 | 显示全部楼层

RE:STM32F103VE AD转换跨界问题

如果你要的精度很高的话,光万用表采集的不准确,还是用精度高的可调电源测试。
回复 支持 反对

使用道具 举报

134

主题

4489

回帖

239

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2011-12-13 21:45:53 | 显示全部楼层

RE:STM32F103VE AD转换跨界问题

如果想要采集的经度高的话,首先要注意几个问题:
1、如果用到分压,最好使用放大器来处理,并且分压电阻的精度要高;
2、万用表的精度也很重要,他不一定比你MCU采集的精度高;
3、测试的时候,电源的使用也很重要,要考虑使用精度高的可调电源。
回复 支持 反对

使用道具 举报

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2011-12-14 12:03:48 | 显示全部楼层

回复:STM32F103VE AD转换跨界问题

回复第 2 楼 于2011-12-13 13:40:38发表:
你说的这种情况,还真没有遇到过,你可以看看你的RC电路的参数,是不是这个原因。
1、你用一个通道来测量,不用DMA方式,看看是否出现这种情况。先确定是硬件的问题还是软件的问题。
2、看看输出的AD值是否正常,不要处理AD值,看原始的AD值。 

单通道测量过,没改善,并且我使用过例程程序单通道,单值一秒读一次数,只看AD值,会出现在255处出现不增长的情况(当然波动是存在的,我说的不增长是指多数概率出现255而不是正确的大于255的AD值),之前只发现155mv和625mv两个点不好,就因为是看AD值才发现测出的点正好跨在AD进位点上,我才推断出512的点(即312mv)也可能有误差,结果验证后真是如此。
软件换过多种办法没什么改善,硬件换过处理器,还换过另外一种板子,没改善。所以到底是软件或硬件问题我也没弄清除。
回复 支持 反对

使用道具 举报

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2011-12-14 12:21:19 | 显示全部楼层

RE:STM32F103VE AD转换跨界问题

现在问题不在于采样精度,而在于采样的一致性,问题是在我使用的120-750mv范围内除提到的三个点附近外,其他范围一致性非常好,电压增加,AD采样值相应增加,万用表测量值相应增加,当然它们之间都是有偏差的,但总体增加的比例是对的。就是在AD值进位点出现了电压增加AD值(多数值)停止不前的情况,直到电压高到一定值,AD值会突变到正确的值上,之后就与电压按比例变化了。并且除误差段外其他范围的线性都很好。
回复 支持 反对

使用道具 举报

134

主题

4489

回帖

239

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2011-12-14 14:55:59 | 显示全部楼层

RE:STM32F103VE AD转换跨界问题

我认为是你程序处理的问题,你可以检查一下。当155mV的时候,AD寄存器的值应该是0x130,你可以把你AD寄存器的实际值输出来,再换算成电压试试。
回复 支持 反对

使用道具 举报

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2011-12-15 12:26:30 | 显示全部楼层

回复:STM32F103VE AD转换跨界问题

回复第 7 楼 于2011-12-14 06:55:59发表:
我认为是你程序处理的问题,你可以检查一下。当155mV的时候,AD寄存器的值应该是0x130,你可以把你AD寄存器的实际值输出来,再换算成电压试试。 

谢谢帮助,但AD满量程2500mv,12位AD,155mv时的AD值应为 155*4096/2500=253.952 (254),也就是0x00FE。我只所以发现是在跨界点就是因为把AD值之间输出来才发现的。
 
回复 支持 反对

使用道具 举报

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2011-12-15 12:54:31 | 显示全部楼层

回复:STM32F103VE AD转换跨界问题

我的程序运行流程为,打开ADC和DMA,定时器3  10ms中断,每次中断把AD缓冲区ADCBUFLEN个数据求均值,之后把均值累加,达到ADCNUMMAX 次后,置位标志ADC_Result_OK,主循环检测标志ADC_Result_OK进入数据处理函数得到电平信号。意味着差不多1s获得一个平均电平值。具体程序如下
 
#define  ADC1_DR_Address    ((uint32)0x4001244C)
#define  ADCBUFLEN   2048    // ADC单通道数据缓冲区数据长度
#define  ADCBUFCHL   4     // ADC通道数
#define  ADCVREF    2500     // 参考电平为mV
#define  ADCNUMMAX    100     // ADC转换ADCBUFLEN次的次数
/*********************************************************************************************************
** 函数名称: DMA_Cfg
** 功能描述: 配置DMA
** 输   入: 无
** 输   出: 无
********************************************************************************************************/
void DMA_Cfg(void)
{
 DMA_InitTypeDef DMA_InitStructure;
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  // 使能DMA时钟
 // DMA配置
 DMA_DeInit(DMA1_Channel1);
 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  // DMA外设基地址
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32)&ADC_Value_Buf; // DMA内存基地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;    // DMA_DIR_PeripheralSRC 外设作为数据传输的来源; DMA_DIR_PeripheralDST 外设作为数据传输的目的地
 DMA_InitStructure.DMA_BufferSize = ADCBUFLEN*ADCBUFCHL;  // DMA缓存的大小,单位为数据单位
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设地址寄存器不递增
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;   // 内存地址寄存器递增
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据宽度为16位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据宽度为16位
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     // DMA_Mode_Circular 工作在循环缓存模式;DMA_Mode_Normal 工作在正常缓存模式
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;    // DMA通道拥有高优先级
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;     // 没有设置为内存到内存传输
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 DMA_Cmd(DMA1_Channel1, ENABLE); // 使能DMA
}
回复 支持 反对

使用道具 举报

1

主题

14

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2011-12-15 12:56:26 | 显示全部楼层

RE:STM32F103VE AD转换跨界问题

/*********************************************************************************************************
** 函数名称: GPIO_ADC_Cfg
** 功能描述: ADC引脚配置
** 输   入: 无
** 输   出: 无
********************************************************************************************************/
void GPIO_ADC_Cfg(void)
{
GPIO_InitTypeDef GPIO_InitStructure;   // 定义1个结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 打开GPIOX时钟

// 配置 PA0 PA1 PA2 PA3(ADC 通道 0 1 2 3)模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************************************************
** 函数名称: ADC_Cfg
** 功能描述: 配置AD转换器
** 输   入: 无
** 输   出: 无
********************************************************************************************************/
void ADC_Cfg(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1时钟
//ADC1配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;     // 独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;      // 扫描模式(多通道)
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;     // 连续模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 转换由软件触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    // ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = ADCBUFCHL;     // 规定了顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure);
// ADC1规则模式通道配置
ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1 , 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2 , 3, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3 , 4, ADC_SampleTime_55Cycles5);
ADC_Cmd(ADC1, ENABLE);  // 使能ADC1
ADC_DMACmd(ADC1, ENABLE); // 使能ADC1 DMA功能
// Enable ADC1 reset calibaration register
ADC_ResetCalibration(ADC1);
// Check the end of ADC1 reset calibration register
while(ADC_GetResetCalibrationStatus(ADC1));
// Start ADC1 calibaration
ADC_StartCalibration(ADC1);
// Check the end of ADC1 calibration
while(ADC_GetCalibrationStatus(ADC1));
// 启动转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
回复 支持 反对

使用道具 举报

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版