完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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] = (ADC_ConvertedValue&0xffff); //获取ADC的值 value[1] = ((ADC_ConvertedValue>> 16)&0xffff); //获取ADC的值 printf("rn 编号%d t 编号%d t AD值: %drn", 0,i, value[0]); printf("rn 编号%d t 编号%d t AD值: %drn", 1,i, value[1]); } 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); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1632 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1559 浏览 1 评论
985 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1605 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
655浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
525浏览 3评论
540浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
512浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 23:00 , Processed in 2.517200 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号