历史上的今天
返回首页

历史上的今天

今天是:2025年07月10日(星期四)

正在发生

2018年07月10日 | 关于STM32F0系列多路ADC单独采样数据相同问题的处理

2018-07-10 来源: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);

}


推荐阅读

史海拾趣

Chipcera Technology Co Ltd公司的发展小趣事

随着技术实力的不断增强,Chipcera开始将目光投向更广阔的市场。公司通过参加国际电子展会、与知名厂商合作等方式,积极推广自家产品。同时,公司还加大了对品牌建设的投入,通过提升产品质量、优化售后服务等措施,树立了良好的品牌形象。这些努力使得Chipcera的产品逐渐打入国际市场,成为行业内的佼佼者。

Dover Corporation公司的发展小趣事

为了进一步扩大市场份额,Dover Corporation积极推进国际化布局。公司通过与国际、国内投行及私募基金的合作,成功收购了多家海外公司,实现了业务的全球化。这些收购不仅为Dover带来了更多的市场机会,也增强了其在全球市场中的竞争力。

Deltron公司的发展小趣事

Deltron公司成立于XXXX年,初期以生产基础电子元器件为主。创始人XXX凭借其对电子技术的深刻理解和对市场趋势的敏锐洞察,带领团队进行了一系列技术创新。通过引进先进的生产设备和研发技术,Deltron成功开发出了一系列具有竞争力的产品,逐渐在电子行业中崭露头角。

Ambersil公司的发展小趣事

在电子行业的初期,Ambersil公司以其创新的技术和产品迅速崭露头角。公司研发团队成功开发出一种高效的电子清洁剂,能够去除电路板上的顽固污垢,提高电子设备的性能和稳定性。这一创新产品迅速获得了市场的认可,Ambersil公司因此获得了大量的订单,销售额逐年攀升。

General Magnetics Inc公司的发展小趣事
选择性能稳定、质量可靠的电子元件,如低损耗的电感、高耐压的电容等。
Advanced Analog公司的发展小趣事

随着公司的不断发展和壮大,Advanced Analog开始积极拓展国际市场。公司在全球范围内设立了多个分支机构和销售网络,与众多国际知名企业和品牌建立了长期稳定的合作关系。通过参与国际电子展会和交流活动,Advanced Analog的产品和技术得到了更广泛的认可和赞誉,进一步提升了公司在国际市场的知名度和影响力。

问答坊 | AI 解惑

oscillaor phase noise求助

我搭建了一个最简单的正交LC oscillator. (quadrature). 要求phase noise -120dbc/hz.我的只能调到-111dbc/hz。求助大家如何设计才能达到要求?一般什么东西导致phase noise?如何才能减小phase noise? 谢谢。…

查看全部问答>

来几个RF问题,看看大家的RF基础功底

1. What is the impedance of free space? 2. What happens to the noise figure of a receiver when a 10 dB attenuator is added at the input? a) Noise figure increases by 10 dB b) Noise figure decreases by 10 dB c) Noise figure do ...…

查看全部问答>

模拟线路设计经验(放大回路设计)

模拟线路设计经验(放大回路设计)…

查看全部问答>

串行外设接口应用举例

串行外设接口应用举例…

查看全部问答>

【FPGA问题讨论】用XILINX自带的XST做综合遇到问题

之前是用synplify的,现在改用XST,但是发现UCF文件中的一些语句不知道怎么写,比如用synplify是可以这样写,用XST呢,该怎么改? INST genblk0.FC_GTX_[0].FC2_DUAL LOC = GTX_DUAL_X1Y11;其中FC_GTX是用generate和for产生的blocks。有没有大虾知 ...…

查看全部问答>

evc 下用一个sdk编写了 建立了一个 对话框工程,卸载这个sdk,安装另外一个sdk后,此程序 能直接编译通过吗

evc 下用一个sdk编写了 建立了一个 对话框工程,卸载这个sdk,安装另外一个sdk后,此程序 能直接编译通过吗? 应该如何处理理? 不会是 在后一个sdk下 重新建立一个工程,用原来那个sdk建立的工程下的 对话框等资源,还要重新添加一遍?…

查看全部问答>

[求助] 如何用VHDL设计一个延时器

输入是一些随机产生的信号,要求所有的这些输入信号在延时100个时钟周期(外部时钟)后依次输出。请问这个该如何设计?谢谢!…

查看全部问答>

STM32+RA8875 7寸触屏开发板

新年优惠 299一套,需要的联系我Q404658589 例程及原理图: 第一版的操作演示…

查看全部问答>

stm32和LPC的CAN,哪个功能更强?

咨询下,目前stm32和LPC的CAN,哪个功能更强?…

查看全部问答>

你们都做过哪些模电实验?还记得么?

呵呵,好多实验做过就忘记了。。。…

查看全部问答>