历史上的今天
今天是:2024年09月26日(星期四)
2021年09月26日 | 关于STM32F0系列多路ADC单独采样数据相同问题的处理
2021-09-26 来源:eefocus
先看一下,大家认为“正确”的代码
void MYADC_init(void) {
//时钟使能
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//GPIO配置
GPIO_InitTypeDef PORT_ADC;
PORT_ADC.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
PORT_ADC.GPIO_Mode = GPIO_Mode_AN;
PORT_ADC.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &PORT_ADC);
//ADC配置
ADC_InitTypeDef ADC_InitStuctrue;
ADC_InitStuctrue.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStuctrue.ADC_ContinuousConvMode = DISABLE;
ADC_InitStuctrue.ADC_ExternalTrigConv= ADC_ExternalTrigConvEdge_None;
ADC_InitStuctrue.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStuctrue.ADC_ScanDirection = ADC_ScanDirection_Backward;
ADC_Init(ADC1, &ADC_InitStuctrue);
//ADC使能
ADC_Cmd(ADC1, ENABLE);
}
unsigned short MYADC_getValue(unsigned char arg0) {
if(arg0==1){
ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
}else if(arg0==2){
ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);
}else if(arg0==3){
ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_239_5Cycles);
}
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY) == RESET);
ADC_StartOfConversion(ADC1);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
int main(void){
//此处完成你的各种初始化
MYADC_init();
unsigned short adcValue1;
unsigned short adcValue2;
unsigned short adcValue3;
while(1){
adcValue1=MYADC_getValue(1);
//此处加入程序,如将adcValue打印发送出来
adcValue2=MYADC_getValue(2);
//此处加入程序,如将adcValue打印发送出来
adcValue3=MYADC_getValue(3);
//此处加入程序,如将adcValue打印发送出来
}
}
以上代码,是我之前认为“正确”的代码,但是当执行while时,一开始打印出来的3个值adcValue1,adcValue2和adcValue3都是正确的,但是后面继续打印的数据都是同adcValue3。
那是什么原因造成的吗?
原来,问题出在ADC_ChannelConfig()函数。
大家可以在STM32库源文件中找到如下图所示代码。

问题在于,库函数中对ADC通道选择寄存器的赋值用的是或“|”,当while(1)第一次执行该函数时,ADC_Channel=0x00000001,CHSELR=0x00000001,ADC转换数据对应第一通道,第二次执行该函数的时候,ADC_Channel=0x00000010,CHSELR=0x00000011,因为是独立采样模式,系统对高位有效通道进行采样,对应结果为第2通道的值。第三次执行该函数时,ADC_Channel=0x0000100,CHSELR=0x00000111,同样,因为是独立采样模式,对应结果为第3通道的值。在while再次循环时,我们预期结果希望是第一通道,但是实际上此时的CHSELR值已经是0x00000111了,在和0x00000001相或,值还是0x00000111,所以实际结果是最高位,即第3通道的值。
针对多通道单独采样模式,个人建议直接对CHSELR寄存器进行赋值,使用方法如下:
unsigned short MYADC_getValue(unsigned char arg0) {
if(arg0==1){
ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
ADC1->CHSELR =ADC_Channel_1;
}else if(arg0==2){
ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);
ADC1->CHSELR =ADC_Channel_2;
}else if(arg0==3){
ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_239_5Cycles);
ADC1->CHSELR =ADC_Channel_3;
}
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY) == RESET);
ADC_StartOfConversion(ADC1);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
史海拾趣
|
s3c2410大多移植2.4内核或是uclinux, 2440以后基本都是2.6内核,请问内核版本选择跟芯片有关吗? 网上看到有人在2410板子上移植成功2.6内核, 请问这样的配合合理吗? 会不会有在奔3机子上装winXP这种感觉呢?… 查看全部问答> |
|
四、硅谷模式不适全中国环境 很多从硅谷回国的海归在创业失败后,都会说,在中国运营公司比在硅谷要难。笔者在2005年和2006年认识了很多的回国创业的海归人士,当年都是雄心勃勃,结果,几年下来,现在大都已经宣布公司倒闭,有的回到美国去了,有 ...… 查看全部问答> |
|
ADC10_B只有一个ADC10MEM0,也就是每次只能转化一个通道数据,如果我想同时转化多个通道的数据该怎么办呢? 我原本的想法有两个: 第一,采用Single-channel, single-conversion,每次转换好一个通道后,写指令改通道,再转换, ...… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:12 编辑 TI的收发集成方案请参考下面连接.AFE7225,TRF3720,TRF3711 ti./solution/femto_base_station … 查看全部问答> |
|
想做一个对共阴数码管和独立按键的操控,没想到输出的共阴数码管的信号最后是乱码……也不动,按键按了也不变,这个程序也没做完,我看把基本的加法实现了减法应该也能实现(从0+到99),但是没想到遇到了这样的问题,请大神帮忙看看代码有什么问题 ...… 查看全部问答> |
|
哪个跑过TI DEMO2540 。。就是那个最简单的测试程序 我现在USB DONGLE 端口 写00X0028 和1 或者 2 的时候蜂蜜器叫的方式不一样,,这个 00X0028 和1 或者 2 为什么是这个数字… 查看全部问答> |




