历史上的今天
今天是: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); } }
史海拾趣
|
本帖最后由 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 ...… 查看全部问答> |
|
因为平时使用CAN总线很多,所以这次专门找时间,试用了一下lm3s8962的CAN功能,附件就是我简单试用时,使用的程序。(接收指定ID的CAN数据,并通过串口输出)程序中还有不明之处,望指点!! 例程中对CAN报文对象设置时: // CAN接收报文对象设置tC ...… 查看全部问答> |
|
LED具有低功耗、寿命长、环保等鲜明的特点,在从小尺寸背光应用领域向大尺寸面板背光进行渗透之后,现在进一步向通用照明应用领域扩张,目前已经在景观、建筑、商业、汽车、移动照明等领域快速发展。 面对LED照明的众多应用领域,由于市场并没 ...… 查看全部问答> |
|
实现功能:我用串口接收PC端一串数据 然后在把数组中的数据发送给串口 传到PC 遇到问题:串口接收正常 但是发送每次只能发送一两个数据 环境 :串口5 中断接收 请大家帮忙分析下原因 谢谢! ...… 查看全部问答> |
|
有与之前的帖子很久没更新,不能去更新了。现在只能重新发帖了。。以前的贴地址:https://bbs.eeworld.com.cn/thread-297778-1-1.html 这块板子很适合做嵌入式的。最近在用最快板子搞控制,和通信类的。现在传上简单的LCD12864的实验结果及程序吧 ...… 查看全部问答> |
|
一、主程序: #include \"DSP28_Device.h\" float ADResult; unsigned int k=0; float adclo; interrupt void ADC_ISR(void); void main(void) {   ...… 查看全部问答> |
|
主控芯片STM32103RBT6,软件主要是uc/OS+uc/GUI 专营STM8/32 QQ 940436962 http://y-ec.taobao.com/ … 查看全部问答> |




