历史上的今天
返回首页

历史上的今天

今天是:2025年05月20日(星期二)

正在发生

2018年05月20日 | STM32的ADC多通道采集的实现

2018-05-20 来源:eefocus

在经过半个月的不懈努力下,终于将32的ADC多通道的信号采集完成,在网上能找到一些对于多通道信号采集的范例,要么就是用多个ADC,要么就是指贴出部分关键代码,也不对其中的配置及实现做一些细致的说明,这让人会走很多弯路,但也正是这样才能不断提升,才能认识自己的不足。好了,下面就先对STM的ADC做个简单的介绍;

         ADC又称'模拟/数字转换器',在STM32单片机中模拟/数字转换器(ADC)是一种提供可选择多通道输入,逐次逼近型的模数转换器。分辨率为12位,在一般的信号采集应用中已经算是很高的分辨率了。

        它有18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

        下面就是对ADC多通道采集是如何实现做详细说明:
        第一:先讲讲大家在调试这功能可能遇到的一些困惑,我也是这样过来的,不知道你们是不是这样.
        1、范例是用DMA的方式对所采集到的数据进行的读取,这是我首先困惑的,存储到哪个地方去了,为此我还专门看了DMA(直接记忆存取/直接内存存取)到底是什么东西;
        2、我们就认为采集的数据已经被DMA提取并存储了,怎么把这么多通道的数据分离!!! 真滴是伤神~~~
        把上面这两个主要的大问题解决了,那么就能将这个模块调通,并能在实际中得到应用。16路信号的采集还不是小小的应用哟~~~

        下面上代码
//多通道转换函数
vu32 ADC_MultiChannelConvertedValue;
void ADC1_MultiChannel_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        DMA_InitTypeDef DMA_InitStruct;
        ADC_InitTypeDef ADC_InitStruct;


        //ADC input init PA0-7 AD0-7
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1|GPIO_PinSource2|GPIO_PinSource3|GPIO_PinSource4|GPIO_PinSource5|GPIO_PinSource6|GPIO_PinSource7;
        GPIO_Init(GPIOA,&GPIO_InitStructure);


        //ADC input init PB0-1 AD8-9
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1;
        GPIO_Init(GPIOB,&GPIO_InitStructure);


        //ADC input init Pc0-5 AD10-15
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1|GPIO_PinSource2|GPIO_PinSource3|GPIO_PinSource4|GPIO_PinSource5;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
    
                
        DMA_DeInit(DMA1_Channel1);//开启DMA1的第一通道
        DMA_InitStruct.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA对应的外设基地址
        DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned long)&ADC_MultiChannelConvertedValue;        这就是单片机采集后存储的值的地址
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//DMA_MemoryDataSize_HalfWord  DMA搬运的数据尺寸,注意ADC是12位的,HalfWord就是16位。这个地方只有用word方式才能对位转换搬移,具体原因不详wxm
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; //接收一次数据后,目标内存地址是否后移--重要概念,用来采集多个数据的,多通道的时候需要使能它
        DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//接收一次数据后,设备地址是否后移
        DMA_InitStruct.DMA_Mode  = DMA_Mode_Circular;//转换模式,循环缓存模式,常用
        DMA_InitStruct.DMA_Priority = DMA_Priority_High;//DMA优先级,高
        DMA_InitStruct.DMA_BufferSize = 16;//DMA缓存大小,1*16个
        DMA_Init(DMA1_Channel1,&DMA_InitStruct);


        
        ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; //转换模式,为独立转换
        ADC_InitStruct.ADC_ScanConvMode = ENABLE; 
        ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //连续转换模式开启
        ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC外部触发开关,关闭 
        ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //对齐方式,ADC结果是12位的,显然有个对齐左边还是右边的问题。一般是右对齐
        ADC_InitStruct.ADC_NbrOfChannel = 16; //开启通道数,16个
        ADC_Init(ADC1, &ADC_InitStruct); 

        /* Enable ADC1 */ 
        ADC_Cmd(ADC1, ENABLE); 
        /* 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));  
}
//多通道转换函数
u8 MultiChannel_AsciiBuff[5];
void Read_ADC1_MultiChannel(unsigned char u8_channNo)
{  
          unsigned short  ADC_data = 0;
        unsigned char i,id;
        ADC_SoftwareStartConvCmd(ADC1, DISABLE);
                
        for(i=16;i>0;i--)
        {        
                //ADC1,ADC 通道 x,规则采样顺序值为 1,采样时间为 7.5 周期,大于此周期除了通道 0 能识别外,其他不能识别
                ADC_RegularChannelConfig(ADC1, u8_channNo, 1, ADC_SampleTime_7Cycles5 );
                ADC_SoftwareStartConvCmd(ADC1, ENABLE);                         /* 软件启动 ADC1 */                
                do
                {
                        id = ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC);                         /* 读取转换标志 */
                }        while(!id);                                                                                 /* 等待,直到转换完成 */
                
                ADC_data += ADC_GetConversionValue(ADC1);                                这里将值读出,后面就是解析的过程咯
                ADC_SoftwareStartConvCmd(ADC1, DISABLE);                                 /* 软件停止 ADC1 */                                                                          
        }
                                 
        ADC_data = ADC_data >> 4;                                                                         /* 取 16 次采样平均值 */        
        ADC_data = (unsigned int)(((unsigned int)ADC_data)*3300>>12);/* 把采集到的数值转换成电压数据 */


        MultiChannel_AsciiBuff[0] = ADC_data/1000%10 + 0x30;
        MultiChannel_AsciiBuff[1] = ADC_data/100%10 + 0x30;
        MultiChannel_AsciiBuff[2] = ADC_data/10%10 + 0x30;                                                 /* 数据分离送 USART1 显示 */
        MultiChannel_AsciiBuff[3] = ADC_data%10 + 0x30;
        MultiChannel_AsciiBuff[4] = 0;


        USART1Write((u8*)MultiChannel_AsciiBuff,4);
        USART1Write((u8*)"\r\n",sizeof("\r\n"));


        //return (unsigned int)(((unsigned long)(ADC_data>>4))*3300>>12);
}       
        对于那两个问题的答案也在这里面。首先是DMA的存储地址,用横着的红线做了标记;对于采集数据的分离在最后一个红色竖线部分。呵呵,看着是不是就很简单咯~   

推荐阅读

史海拾趣

Hirose公司的发展小趣事

对于单级PFC电路,网友可能还会有多种问题,以下是一些常见问题及其回答:

一、技术原理与特性

  1. 单级PFC电路的基本工作原理是什么?
    • 回答:单级PFC电路通过共用一个开关管和一套PWM控制电路,同时实现功率因数校正(PFC)和对输出电压的调节。它通常由升压型PFC级和DC-DC变换器组合而成,两部分电路共用一个开关,通过控制开关的通断,电路同时完成对AC输入电流的整形和对输出电压的调节。
  2. 单级PFC电路相比两级PFC电路有哪些优缺点?
    • 回答:优点包括电路结构简单、成本较低、效率较高(在某些设计下)。缺点则在于PFC和对输入电流谐波抑制的效果可能不如两级PFC电路,且在某些应用中可能面临安规问题。

二、设计与应用

  1. 如何设计单级PFC电路以满足特定的功率因数要求?
    • 回答:设计单级PFC电路以满足特定功率因数要求时,需要考虑电感的选择、开关管的选型、控制电路的设计以及反馈机制等因素。通过精确控制开关管的通断时间和占空比,可以实现对输入电流的整形,从而改善功率因数。此外,还可以采用有源钳位和软开关技术来进一步提高效率并降低开关损耗。
  2. 单级PFC电路在哪些应用场景中较为常见?
    • 回答:单级PFC电路因其结构简单、成本较低而广泛应用于各种需要功率因数校正的电子设备中,如LED驱动电源、电源适配器、开关电源等。特别是在对成本有一定要求的场合,单级PFC电路更具竞争力。

三、故障与调试

  1. 单级PFC电路在调试过程中可能会遇到哪些常见问题?
    • 回答:在调试单级PFC电路时,可能会遇到次级去电流检测电阻过大、光耦供电电阻过大、比较器电流反馈电容过大等问题。这些问题可能导致PFC电路无法正常工作或性能下降。解决方法包括调整相关电阻和电容的数值、检查电路连接是否正确、更换损坏的元件等。
  2. 如何诊断和解决单级PFC电路中的故障?
    • 回答:诊断和解决单级PFC电路中的故障时,首先需要检查电路中的保险丝是否熔断、MOS管是否损坏或过热、反馈控制元件是否失效以及负载是否存在故障等。通过逐一排查这些可能的问题点,可以定位故障原因并采取相应的修复措施。在检修过程中,需要注意安全操作规范,避免触碰高压部位并断开电源。

四、性能优化

  1. 如何优化单级PFC电路的性能?
    • 回答:优化单级PFC电路的性能可以从多个方面入手,包括优化电感的设计以减小损耗、选择合适的开关管和二极管以降低导通压降和反向恢复时间、改进控制算法以提高控制精度和响应速度等。此外,还可以采用有源钳位和软开关技术来进一步降低开关损耗并提高整体效率。
  2. 单级PFC电路的效率如何提升?
    • 回答:提升单级PFC电路的效率可以通过多种方法实现,包括优化电路拓扑结构、选用高效率的开关管和二极管、降低电路中的寄生参数和损耗、采用先进的控制算法等。此外,合理设计散热系统以确保开关管和其他关键元件在正常工作温度下运行也是提高效率的重要手段之一。
DURATOOL公司的发展小趣事

人才是企业发展的第一资源。DURATOOL公司一直高度重视人才的培养和引进。公司建立了一套完善的人才选拔和培养机制,通过内部培训、外部招聘等方式不断吸纳优秀人才加入公司。同时,公司还为员工提供了广阔的发展空间和良好的福利待遇,激发了员工的积极性和创造力。这些举措使得DURATOOL公司拥有一支高素质、专业化的员工队伍,为企业的发展提供了有力的人才保障。

Gigarams Semiconductor Device Corp公司的发展小趣事
这可能是由于传感器精度不足、控制器算法不准确或驱动器性能不稳定等原因导致的。解决方案包括提高传感器精度、优化控制器算法和更换性能更稳定的驱动器。
ARBOR公司的发展小趣事

ARBOR公司深知合作的重要性,积极与上下游企业建立紧密的合作关系。公司通过与供应商和客户建立长期稳定的战略合作关系,实现了资源共享和优势互补。这种合作模式不仅降低了公司的运营成本,也提高了产品的竞争力。同时,ARBOR公司还积极参与行业交流活动,推动整个电子产业的健康发展。

Global Communications公司的发展小趣事
根据应用场景中可能遇到的环境温度范围,选择具有相应温度测量范围的温度传感器。
Amphenol RF公司的发展小趣事
温度传感器的输出与温度之间的线性关系可能不理想,导致补偿效果不准确。此时,可以采用非线性补偿技术或选择具有更好线性度的温度传感器来解决问题。

问答坊 | AI 解惑

实验板制作6F3胆牛耳机放大器

关注已久的电子管多用途板终于和大家见面了。本站将推出一系列洞洞板作品,已便大家交流。首先推出的一款作品是6F3胆牛耳放,这款作品大家看了一定很熟悉,他的电路和本站前期的PCL86电路完全相同,只是用管不同,电路元件参数稍有不同。由于在洞 ...…

查看全部问答>

"手榴弹"式灭火器

这种类似于“手榴弹”一样的灭火器不像传统的灭火器那样需要人工喷射,只要扔进火堆里,一见到明火,自身就可以引爆灭火。这样一个4升的灭火器有效范围能达到七、八个平方米左右,相当于5至6个3升钢瓶灭火器的威力,而且即使是没有人在现场,事先设 ...…

查看全部问答>

GPRS数据传输问题!!

最近要做一个设计,心电数据采集后的远程发送部分,要求通过GPRS传输到计算机,老师说用手机或gprs模块都行,但我是一菜鸟,不懂怎麽用手机通过gprs远程传输数据到计算机?网上说的我都不明啊,现老师降低要就,只要我能把数据包通过gprs送到计算机 ...…

查看全部问答>

wince +s3c2440 按键音和屏幕点击音 时有时无

wince +s3c2440 按键音和屏幕点击音 时有时无 有时是第一次有,第二次没有,第三次又有.......…

查看全部问答>

stm32f103开发板

[ 本帖最后由 qingfenglinxia 于 2012-5-27 10:03 编辑 ]…

查看全部问答>

TI铅酸蓄电池均衡管理的芯片么?

德州仪器公司有对铅酸蓄电池进行管理的芯片么?是那种?知道的介绍一下…

查看全部问答>

急求VCA822中文资料

急求VCA822中文资料…

查看全部问答>

关于电子设计的书籍求推荐

    最近要做一个擦地机器人,但我是一个菜鸟,希望 大家能推荐一些关于电子设计的书籍,最好是有传感器模块,电源模块,避障模块,驱动模块和路径规划等相关内容讨论的书籍,唉…感觉这些好高级希望不要鄙视我。急需大家帮助,谢谢…

查看全部问答>

[TI首届低功耗设计大赛] fr5969读取串口MPU6050数据

板子好久之前就收到了,因为期中考试和社团活动把它放了好久,有点对不起eeworld了,根据我的项目内容要用到陀螺仪和加速度传感器,这里我选用通信方式比较简单的串口通信的MPU6050,先来晒下板子和传感模块的图 然后下面晒晒数据,用的是低频3276 ...…

查看全部问答>