打印
[应用相关]

ADC问题

[复制链接]
8867|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
171795276|  楼主 | 2009-7-1 11:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,关于ADC问题请教大家:
1)我要用到20通道AD,选的芯片是STM32F103ZCT6,用到ADC3、ADC1,设置如下:

void ADC3_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC1和ADC3工作在独立模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //模数转换工作在扫描模式(多通道)
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //模数转换工作在连续模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //转换由软件而不是外部触发启动
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    //ADC数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 9;                //顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC3, &ADC_InitStructure);    //根据ADC_InitStructure中指定的参数初始化外设ADC3的寄存器
//    ADC_Init(ADC1, &ADC_InitStructure);    //根据ADC_InitStructure中指定的参数初始化外设ADC1的寄存器
    
    //设置指定ADC的规则组通道,设置它们的转化顺序(与原理图上的AI序号一致)和采样时间(取最大值)
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_4,  1, ADC_SampleTime_239Cycles5);//AI1,PF6,Pin18
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_5,  2, ADC_SampleTime_239Cycles5);//AI2,PF7,Pin19
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_6,  3, ADC_SampleTime_239Cycles5);//AI3,PF8,Pin20
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_7,  4, ADC_SampleTime_239Cycles5);//AI4,PF9,Pin21
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_10, 5, ADC_SampleTime_239Cycles5);//AI5,PC0,Pin26
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_11, 6, ADC_SampleTime_239Cycles5);//AI6,PC1,Pin27
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_12, 7, ADC_SampleTime_239Cycles5);//AI7,PC2,Pin28
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_13, 8, ADC_SampleTime_239Cycles5);//AI8,PC3,Pin29
    ADC_RegularChannelConfig(ADC3, ADC_Channe3_0,  9, ADC_SampleTime_239Cycles5);//AI9,PA0,Pin34
    ADC_DMACmd(ADC3, ENABLE);                //使能ADC3的DMA请求
//    ADC_DMACmd(ADC1, ENABLE);                //使能ADC1的DMA请求
    ADC_Cmd(ADC3, ENABLE);                    //使能ADC3
//    ADC_Cmd(ADC1, ENABLE);                    //使能ADC1
//    ADC_TempSensorVrefintCmd(ENABLE);        //使能温度传感器和内部参考电压通道

    ADC_ResetCalibration(ADC3);                    //重置ADC3的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC3));    //获取ADC重置校准寄存器的状态并等待其值变为0(校准寄存器已初始化)
//    ADC_ResetCalibration(ADC1);                    //重置ADC1的校准寄存器
//    while(ADC_GetResetCalibrationStatus(ADC1));    //获取ADC重置校准寄存器的状态并等待其值变为0(校准寄存器已初始化)

    ADC_StartCalibration(ADC3);                    //开始ADC3的校准状态
    while(ADC_GetCalibrationStatus(ADC3));        //获取ADC校准寄存器的状态并等待其值变为0(已完成校准)
//    ADC_StartCalibration(ADC1);                    //开始ADC1的校准状态
//    while(ADC_GetCalibrationStatus(ADC1));        //获取ADC校准寄存器的状态并等待其值变为0(已完成校准)

    ADC_SoftwareStartConvCmd(ADC3, ENABLE);        //使能ADC3的软件转换启动功能
//    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能ADC1的软件转换启动功能
}

void ADC1_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC1和ADC3工作在独立模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //模数转换工作在扫描模式(多通道)
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //模数转换工作在连续模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //转换由软件而不是外部触发启动
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    //ADC数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 11;                //顺序进行规则转换的ADC通道的数目
//    ADC_Init(ADC3, &ADC_InitStructure);    //根据ADC_InitStructure中指定的参数初始化外设ADC3的寄存器
    ADC_Init(ADC1, &ADC_InitStructure);    //根据ADC_InitStructure中指定的参数初始化外设ADC1的寄存器
    
    //设置指定ADC的规则组通道,设置它们的转化顺序(与原理图上的AI序号一致)和采样时间(取最大值)
    ADC_RegularChannelConfig(ADC1, ADC_Channe1_1, 1, ADC_SampleTime_239Cycles5);//AI10,PA1,Pin35    
    ADC_RegularChannelConfig(ADC1, ADC_Channe1_2, 2, ADC_SampleTime_239Cycles5);//AI11,PA2,Pin36
    ADC_RegularChannelConfig(ADC1, ADC_Channe1_3, 3, ADC_SampleTime_239Cycles5);//AI12,PA3,Pin37
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_239Cycles5);//AI13,PA4,Pin40
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_239Cycles5);//AI14,PA5,Pin41
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_239Cycles5);//AI15,PA6,Pin42
    ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 7, ADC_SampleTime_239Cycles5);//AI16,PA7,Pin43
    ADC_RegularChannelConfig(ADC1, ADC_Channel_14,8, ADC_SampleTime_239Cycles5);//AI17,PC4,Pin44
    ADC_RegularChannelConfig(ADC1, ADC_Channel_15,9, ADC_SampleTime_239Cycles5);//AI18,PC5,Pin45
    ADC_RegularChannelConfig(ADC1, ADC_Channel_8,10, ADC_SampleTime_239Cycles5);//AI19,PB0,Pin46
    ADC_RegularChannelConfig(ADC1, ADC_Channel_9,11, ADC_SampleTime_239Cycles5);//AI20,PB1,Pin47
    
//    ADC_DMACmd(ADC3, ENABLE);                //使能ADC3的DMA请求
    ADC_DMACmd(ADC1, ENABLE);                //使能ADC1的DMA请求
//    ADC_Cmd(ADC3, ENABLE);                    //使能ADC3
    ADC_Cmd(ADC1, ENABLE);                    //使能ADC1
//    ADC_TempSensorVrefintCmd(ENABLE);        //使能温度传感器和内部参考电压通道

//    ADC_ResetCalibration(ADC3);                    //重置ADC3的校准寄存器
//    while(ADC_GetResetCalibrationStatus(ADC3));    //获取ADC重置校准寄存器的状态并等待其值变为0(校准寄存器已初始化)
    ADC_ResetCalibration(ADC1);                    //重置ADC1的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));    //获取ADC重置校准寄存器的状态并等待其值变为0(校准寄存器已初始化)

//    ADC_StartCalibration(ADC3);                    //开始ADC3的校准状态
//    while(ADC_GetCalibrationStatus(ADC3));        //获取ADC校准寄存器的状态并等待其值变为0(已完成校准)
    ADC_StartCalibration(ADC1);                    //开始ADC1的校准状态
    while(ADC_GetCalibrationStatus(ADC1));        //获取ADC校准寄存器的状态并等待其值变为0(已完成校准)

//    ADC_SoftwareStartConvCmd(ADC3, ENABLE);        //使能ADC3的软件转换启动功能
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能ADC1的软件转换启动功能
}

出现错误说这些量没定义:
compiling YFSIGNAL_MAIN_V1.c...
..SourceYFSIGNAL_MAIN_V1.c(305): error:  #20: identifier "ADC3ConvertedValue" is undefined
..SourceYFSIGNAL_MAIN_V1.c(340): error:  #20: identifier "ADC_Channe3_4" is undefined
..SourceYFSIGNAL_MAIN_V1.c(341): error:  #20: identifier "ADC_Channe3_5" is undefined
..SourceYFSIGNAL_MAIN_V1.c(342): error:  #20: identifier "ADC_Channe3_6" is undefined
..SourceYFSIGNAL_MAIN_V1.c(343): error:  #20: identifier "ADC_Channe3_7" is undefined
..SourceYFSIGNAL_MAIN_V1.c(344): error:  #20: identifier "ADC_Channe3_10" is undefined
..SourceYFSIGNAL_MAIN_V1.c(345): error:  #20: identifier "ADC_Channe3_11" is undefined
..SourceYFSIGNAL_MAIN_V1.c(346): error:  #20: identifier "ADC_Channe3_12" is undefined
..SourceYFSIGNAL_MAIN_V1.c(347): error:  #20: identifier "ADC_Channe3_13" is undefined
..SourceYFSIGNAL_MAIN_V1.c(348): error:  #20: identifier "ADC_Channe3_0" is undefined
..SourceYFSIGNAL_MAIN_V1.c(409): error:  #20: identifier "ADC_Channe1_1" is undefined
..SourceYFSIGNAL_MAIN_V1.c(410): error:  #20: identifier "ADC_Channe1_2" is undefined
..SourceYFSIGNAL_MAIN_V1.c(411): error:  #20: identifier "ADC_Channe1_3" is undefined

2)ADC的连续模式适合用在采什么样的信号:它的单次模式指的是把所有通道(如20通道)都转换一次然后停止,还是只在一个通道上转换一次就停了?
沙发
grant_jx| | 2009-7-1 12:18 | 只看该作者

stm32f10x_conf.h文件的ADC3是否允许?


#define _ADC
#define _ADC1
//#define _ADC2
//#define _ADC3    ???

使用特权

评论回复
板凳
171795276|  楼主 | 2009-7-1 13:08 | 只看该作者

是允许的

#define _ADC
#define _ADC1
#define _ADC2
#define _ADC3

使用特权

评论回复
地板
香水城| | 2009-7-1 13:47 | 只看该作者

你使用了没有定义的标示符

在stm32f10x_adc.h中只有下述定义,没有ADC_Channe3_4、ADC_Channe3_5等这样的定义。

#define ADC_Channel_0                               ((uint8_t)0x00)
#define ADC_Channel_1                               ((uint8_t)0x01)
#define ADC_Channel_2                               ((uint8_t)0x02)
#define ADC_Channel_3                               ((uint8_t)0x03)
#define ADC_Channel_4                               ((uint8_t)0x04)
#define ADC_Channel_5                               ((uint8_t)0x05)
#define ADC_Channel_6                               ((uint8_t)0x06)
#define ADC_Channel_7                               ((uint8_t)0x07)
#define ADC_Channel_8                               ((uint8_t)0x08)
#define ADC_Channel_9                               ((uint8_t)0x09)
#define ADC_Channel_10                              ((uint8_t)0x0A)
#define ADC_Channel_11                              ((uint8_t)0x0B)
#define ADC_Channel_12                              ((uint8_t)0x0C)
#define ADC_Channel_13                              ((uint8_t)0x0D)
#define ADC_Channel_14                              ((uint8_t)0x0E)
#define ADC_Channel_15                              ((uint8_t)0x0F)
#define ADC_Channel_16                              ((uint8_t)0x10)
#define ADC_Channel_17                              ((uint8_t)0x11)


函数ADC_RegularChannelConfig的第一个参数已经指定了使用ADC1还是ADC3,第2个参数只需指定通道即可。

使用特权

评论回复
5
171795276|  楼主 | 2009-7-1 14:20 | 只看该作者

ADC有那么多通道么?

谢谢,
这里定义的只有ADC1的18个
但是我得用到20个,ADC3、ADC1如果有的话,我自己定义应该如何定义呢。

使用特权

评论回复
6
香水城| | 2009-7-1 15:29 | 只看该作者

根本不需要自己定义

这样写配置ADC1的通道1:ADC_RegularChannelConfig(ADC1, ADC_Channe1_1, ......

这样写配置ADC3的通道1:ADC_RegularChannelConfig(ADC3, ADC_Channe1_1, ......


请看清楚ADC_Channe1_1,Channel的最后一个字母是L的小写,不是数字1

使用特权

评论回复
7
171795276|  楼主 | 2009-7-1 15:53 | 只看该作者

哦 ,知道了,知道了

多谢,多谢!!

使用特权

评论回复
8
171795276|  楼主 | 2009-7-1 16:18 | 只看该作者

还有点不明

这里只定义了18通道,STM32最多只有18通道么?
我看介绍最多有21通道。

使用特权

评论回复
9
香水城| | 2009-7-1 16:55 | 只看该作者

STM32中最多有3个ADC模块,每个模块对应的通道不完全重叠

下图是STM32F103CDE数据手册中的总框图的左下角,图中可以看出有8个外部ADC管脚分别接到了3个ADC模块,有8个外部ADC管脚只分别接到了2个ADC模块,还有5个外部ADC管脚只接到了ADC3模块,这样总共是21个通道。



下表是这些ADC管脚与每个ADC模块的对应关系,表中可以看出ADC1还有2个内部通道,分别接到内部的温度传感器和内部的参照电压:

使用特权

评论回复
10
171795276|  楼主 | 2009-7-2 09:10 | 只看该作者

后来搞明白了

这一点后来搞明白了,多谢!

另外开始提了两个问题,第二个是:

2)ADC的连续模式适合用在采什么样的信号:它的单次模式指的是把所有通道(如20通道)都转换一次然后停止,还是只在一个通道上转换一次就停了?

注:我要采的是交流信号

使用特权

评论回复
11
lut1lut| | 2009-7-2 11:07 | 只看该作者

single mode + scan mode enable

把这组内所有通道都转换完了,才停止。

使用特权

评论回复
12
香水城| | 2009-7-2 12:10 | 只看该作者

STM32的ADC转换模式:连续(或单次)与扫描的配置,共有4种组合

单次(Single)模式 = 非连续模式

单次模式 + 非扫描:转换一个通道即停止
连续模式 + 非扫描:连续不断地转换一个通道
单次模式 + 扫描:转换所有选定的通道,每个通道转换一次然后停止
连续模式 + 扫描:连续不断地按指定的顺序转换所有选定的通道

使用特权

评论回复
13
171795276|  楼主 | 2009-7-2 14:53 | 只看该作者

OK

反应速度很快,而且讲解得十分详细

使用特权

评论回复
14
171795276|  楼主 | 2009-7-8 17:55 | 只看该作者

ADC转换启动

如果设置成连续采样模式则不用设置这个控制寄存器来启动,只要初使化好它就在不停采?
#define CR2_ADON_Set                ((u32)0x00000001)
#define CR2_ADON_Reset              ((u32)0xFFFFFFFE)
如果是单次模式则只要设置上面控制寄存器的位来起停么?

使用特权

评论回复
15
171795276|  楼主 | 2009-7-8 21:46 | 只看该作者

软件触发或者两次使能么?

1、是这句么:
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
这个函数的说明是:

使能或者失能指定的ADC的软件转换启动功能
输入参数1 ADCx:x可以是1或者2来选择ADC外设ADC1或ADC2 
输入参数2 NewState:指定ADC的软件转换启动新状态这个参数可以取:ENABLE或者DISABLE        

使能ADC的软件转换启动 
我理解的意思是,仅使能,并未启动。

2、另外看手册,觉得矛盾,到底哪个控制启动AD的:
1)、
通过设置ADC_CR1寄存器的ADON位可给ADC上电。当第一次设置ADON位时,它将ADC从断电状态下唤醒。 
ADC上电延迟一段时间后(tSTAB),再次设置ADON位时开始进行转换。 
2)、
单次转换模式下,ADC只执行一次转换。该模式既可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0。

使用特权

评论回复
16
香水城| | 2009-7-8 21:57 | 只看该作者

2种说法并不矛盾呀

你列出的第2种说法中不是讲的挺清楚的,“既可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道)”。

这里用了 “既可以......也可以”  的句式,中文语法上没有矛盾呀。

使用特权

评论回复
17
171795276|  楼主 | 2009-7-8 22:11 | 只看该作者

谢谢,指第2大点的两小点之间

如题

第一小点说:连续两次设置 CR1的ADON位启动
第二小点讲:设置CR2 的ADON位或者外部触发

或者应该理解成:两次设置CR1的ADON位仅用于两种模式时的软件启动不可外部触发;
                而两次设置CR2的ADON位也可用外部触发ADC??

使用特权

评论回复
18
香水城| | 2009-7-8 22:18 | 只看该作者

第2点中的条件不是很清楚吗?“单次转换模式下”

第1点是没有条件的,与第2点的“既可以......”相吻合呀

郁闷,语法上、语义上都没有问题呀,你为什么会不理解?

使用特权

评论回复
19
171795276|  楼主 | 2009-7-8 22:27 | 只看该作者

修改了上一次的贴子

嗯,我钻到牛角尖里去了。
谢谢
嘿嘿

使用特权

评论回复
20
171795276|  楼主 | 2009-7-9 08:51 | 只看该作者

知道了

后来又看了参考手册,关于AD的控制寄存器的描述。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

79

帖子

0

粉丝