历史上的今天
返回首页

历史上的今天

今天是:2024年10月30日(星期三)

正在发生

2019年10月30日 | STM32F103实现双ADC同步采集电压信号

2019-10-30 来源:eefocus

STM32一般都拥有1~3个ADC,这些ADC可以独立使用,也可以使用双重/三重ADC采样模式,本文使用STM32F103ZET6的双重ADC模式,同步采集两个通道的电压信号。

一、注意事项

1、配置ADC的采样模式为同步规则采样

ADC1和ADC2采样模式相同,但其中ADC1为主ADC,ADC2为从ADC。

该模式在ADC_CR1寄存器中配置:(具体资料请参详STM32参考手册)

在这里插入图片描述

2、使能DMA位

在双ADC模式中,ADC1和ADC2的规则通道转换数据均会保存到主数据寄存器,也就是ADC1数据寄存器(ADC1_DR)中。为了能在主寄存器中读取从ADC的转换数据,必须使能DMA位。** 无论是否使用DMA传输规则通道数据 **

在ADC_CR2寄存器中配置:

在这里插入图片描述

3、触发方式配置

如果ADC1使用软件触发,ADC2则使用外部通道触发;ADC1使用外部事件触发时,ADC2设置成软件触发,这样可以防止意外触发从转换。


二、代码配置

1、adc.c

 /****

 *   程序功能:实现双ADC同步采集,每路ADC各有1个通道(单通道)

 *

 ******/

 #include "adc.h"

 #include "delay.h"

 #include "usart.h"


#define M 128

#define N 8

uint16_t   value[N][M];

u32 ADC_ConvertedValue;  



//初始化ADC1

void Adc1_Multi_Init(void)

{

ADC_InitTypeDef ADC_InitStructure; 

GPIO_InitTypeDef GPIO_InitStructure;

 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );   //使能ADC1通道时钟

 

 

RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

 

//PA1 作为模拟通道输入引脚

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚

GPIO_Init(GPIOA, &GPIO_InitStructure);

 

ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

 

ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //ADC工作模式:ADC1同步规则组模式

ADC_InitStructure.ADC_ScanConvMode =DISABLE;     //模数转换工作在非扫描模式

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //模数转换工作在单次转换模式

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   //ADC数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = 1;    //顺序进行规则转换的ADC通道的数目

ADC_Init(ADC1, &ADC_InitStructure);   //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

 

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 );

 

// 开启ADC的DMA支持

ADC_DMACmd(ADC1, ENABLE);  //使能ADC的DMA位

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE); //使能ADC1


/* Enable ADC1 reset calibaration register  使能ADC1复位校准寄存器 */   

ADC_ResetCalibration(ADC1);

/* Check the end of ADC1 reset calibration register   ADC1复位校准寄存器检查结束*/

while(ADC_GetResetCalibrationStatus(ADC1));


/* Start ADC1 calibaration    启动ADC1校准 */

ADC_StartCalibration(ADC1);

/* Check the end of ADC1 calibration  ADC1校准检查结束 */

while(ADC_GetCalibrationStatus(ADC1));

}



//初始化ADC2

void Adc2_Multi_Init(void)

{

ADC_InitTypeDef ADC_InitStructure; 

GPIO_InitTypeDef GPIO_InitStructure;

 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC2 , ENABLE );   //使能ADC2通道时钟

 

RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

 

//PB0,1 作为模拟通道输入引脚

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;   

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚

GPIO_Init(GPIOC, &GPIO_InitStructure);

 

ADC_DeInit(ADC2);  //复位ADC2,将外设 ADC2 的全部寄存器重设为缺省值

 

ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //ADC工作模式:ADC1同步规则组模式

ADC_InitStructure.ADC_ScanConvMode =DISABLE; //模数转换工作在非扫描模式

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   //转换由软件而不是外部触发启动

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目

ADC_Init(ADC2, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

 

ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5 );


ADC_ExternalTrigConvCmd(ADC2, ENABLE);   //使能ADC2的外部触发模式 

 

    /* Enable ADC2 */

ADC_Cmd(ADC2, ENABLE); //使能ADC2


/* Enable ADC1 reset calibaration register  使能ADC2复位校准寄存器 */   

ADC_ResetCalibration(ADC2);

/* Check the end of ADC1 reset calibration register   ADC2复位校准寄存器检查结束*/

while(ADC_GetResetCalibrationStatus(ADC2));


/* Start ADC1 calibaration    启动ADC2校准 */

ADC_StartCalibration(ADC2);

/* Check the end of ADC1 calibration  ADC2校准检查结束 */

while(ADC_GetCalibrationStatus(ADC2));

 

}



/*初始化ADC */

void MY_ADC_Init(void)

{

Adc1_Multi_Init();

Adc2_Multi_Init();

}



void task_adc(void)

{    

int i;

     printf("rn 采样开始rn");

for(i=0;i {

/* Start ADC1 Software Conversion  启动ADC1软件转换 */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);  //开始转换

ADC_ConvertedValue=ADC1->DR;

value[0][i] = (ADC_ConvertedValue&0xffff); //获取ADC的值

        value[1][i] = ((ADC_ConvertedValue>> 16)&0xffff);  //获取ADC的值

printf("rn 编号%d  t 编号%d  t AD值: %drn", 0,i,  value[0][i]);

printf("rn 编号%d  t 编号%d  t AD值: %drn", 1,i,  value[1][i]); 

}

printf("rn 采样结束rn");

}


2、adc.h

#ifndef __ADC_H

#define __ADC_H

#include "sys.h"



void Adc1_Multi_Init(void);

void Adc2_Multi_Init(void);

void MY_ADC_Init(void);

void task_adc(void);


#endif 


3、main.c

#include "led.h"

#include "delay.h"

#include "key.h"

#include "sys.h"

#include "usart.h"  

#include "adc.h"

 


 int main(void)

 {  

    

delay_init();     //延时函数初始化   

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

  LED_Init();      //LED端口初始化

  MY_ADC_Init();   //ADC初始化

       

while(1)

{

task_adc();

LED0=!LED0;

delay_ms(250);

}

}


推荐阅读

史海拾趣

Globaltech Semiconductor Co Ltd公司的发展小趣事

近年来,全球半导体行业面临了诸多挑战,包括供应链紧张、技术迭代加速等。面对这些挑战,Globaltech积极调整战略,加强与上游供应商和下游客户的沟通与合作,确保供应链的稳定。同时,公司还加大了对新技术和新产品的研发投入,以应对行业变化带来的挑战。通过这些努力,Globaltech不仅成功应对了行业挑战,还实现了业务的持续增长。

Aeroflex公司的发展小趣事

近年来,全球半导体行业面临了诸多挑战,包括供应链紧张、技术迭代加速等。面对这些挑战,Globaltech积极调整战略,加强与上游供应商和下游客户的沟通与合作,确保供应链的稳定。同时,公司还加大了对新技术和新产品的研发投入,以应对行业变化带来的挑战。通过这些努力,Globaltech不仅成功应对了行业挑战,还实现了业务的持续增长。

DZUS公司的发展小趣事

在XX世纪XX年代,DZUS公司的创始人John Doe看到了航空工业对高质量紧固件的迫切需求。他凭借自己在机械工程领域的深厚造诣,设计并制造了第一款DZUS快拆紧固件。这款产品在航空工业中迅速获得了认可,为DZUS公司的发展奠定了坚实的基础。John Doe的创业精神和对品质的坚持,成为了DZUS公司的核心价值观。

Eaton公司的发展小趣事

自1993年进入中国市场以来,伊顿公司凭借其先进的技术和丰富的经验,迅速在电网、石油化工、轨道交通、数据中心、商业楼宇等多个行业建立了市场地位。伊顿在中国的发展过程中,不仅带来了全球领先的产品和解决方案,还积极参与了本地市场的建设和创新。通过一系列的战略合作和收购活动,伊顿在中国市场的业务不断扩展,为中国经济和电气工业的发展做出了重要贡献。

Acutechnology公司的发展小趣事

在市场竞争日益激烈的背景下,Acutechnology公司深知品质是企业生存和发展的关键。因此,公司建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。同时,公司还注重品牌建设,通过广告宣传、参加展会等方式提升品牌知名度和美誉度。这些举措有效地提升了公司的市场竞争力,赢得了客户的广泛认可。

ELDECO公司的发展小趣事

在电子记录仪(ELD)市场刚刚兴起时,ELDECO公司凭借其在嵌入式系统领域的深厚积累,迅速推出了首款高性能、易集成的ELD产品。这款产品不仅满足了当时法规对车辆监控的要求,还通过创新的数据分析功能,帮助运输企业提高了运营效率。随着市场需求的不断增长,ELDECO公司继续加大研发投入,不断推出新产品和解决方案,逐渐在ELD市场确立了领先地位。

问答坊 | AI 解惑

求智能循迹小车驱动电路图

本帖最后由 paulhyde 于 2014-9-15 03:17 编辑 有那位高人能提供智能循迹小车驱动电路的pcb呀 核心板芯片是pc9s12xs128的 电机驱动电路的芯片是33886的 或是其他的芯片耶可以 还有能否提供光电探测板的电路图和pcb 在这 ...…

查看全部问答>

Microsoft Communication Controls Version 6.0 不支持此接口

RT. 我用vc6.0新建了个对话框的工程,添加MSComm控件时,出现了上面的提示,无法插入该控件。 这个该如何解决?…

查看全部问答>

sql ce2.0用rda连接sql server,出现问题,在线等

请教一个问题,我用rda连接sql server ,但出现以下错误: 未处理的“System.Data.SqlServerCe.SqlCeException”类型的异常出现在 System.Data.SqlServerCe.dll 中。 我是C# 2003、sql server 2000、Pda是win mobile 5.0 我的代码如下: string ...…

查看全部问答>

lm3s8962 - - CAN

因为平时使用CAN总线很多,所以这次专门找时间,试用了一下lm3s8962的CAN功能,附件就是我简单试用时,使用的程序。(接收指定ID的CAN数据,并通过串口输出)程序中还有不明之处,望指点!! 例程中对CAN报文对象设置时: // CAN接收报文对象设置tC ...…

查看全部问答>

LED照明的过流保护器件应用

LED具有低功耗、寿命长、环保等鲜明的特点,在从小尺寸背光应用领域向大尺寸面板背光进行渗透之后,现在进一步向通用照明应用领域扩张,目前已经在景观、建筑、商业、汽车、移动照明等领域快速发展。   面对LED照明的众多应用领域,由于市场并没 ...…

查看全部问答>

STM32 USART 接收问题 已经解决

实现功能:我用串口接收PC端一串数据   然后在把数组中的数据发送给串口 传到PC   遇到问题:串口接收正常 但是发送每次只能发送一两个数据 环境       :串口5 中断接收 请大家帮忙分析下原因 谢谢! ...…

查看全部问答>

纪念第一次注册博客-2011年3月8日

在IC行业混了10多年,一直想参见某个专业的网上社区组织,2011年3月8日终于实现了。会每天抽出半小时来,写写感想,记记生活中的人和事。…

查看全部问答>

继前帖《安富利的spartan-6LX9使用进行中。。。》

有与之前的帖子很久没更新,不能去更新了。现在只能重新发帖了。。以前的贴地址:https://bbs.eeworld.com.cn/thread-297778-1-1.html 这块板子很适合做嵌入式的。最近在用最快板子搞控制,和通信类的。现在传上简单的LCD12864的实验结果及程序吧 ...…

查看全部问答>

DSP2812无法进入周期中断

一、主程序: #include \"DSP28_Device.h\" float        ADResult; unsigned int k=0; float        adclo; interrupt void ADC_ISR(void); void main(void) {     ...…

查看全部问答>

GPS方面的,ucOS+ucGUI+STM32(转)

主控芯片STM32103RBT6,软件主要是uc/OS+uc/GUI 专营STM8/32 QQ 940436962 http://y-ec.taobao.com/ …

查看全部问答>