IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 多路ADC的采集——stm32 -> 正文阅读

[嵌入式]多路ADC的采集——stm32

?????????在对实际应用过程中,ADC的采集大多是多个通道同时采集的,比如同时采集多个传感器的数据,就可能需要我们配置多个通道的ADC采集了,而多通道的ADC采集大多用到了DMA,笼统的讲通过DMA来传输数据不经过CPU,可以有效的为CPU减负,我们在使用时只需要通过CPU完成相应的初始化,而传输本身呢,是由DMA来进行的,而对于采集到的不同通道的数据我们只需要将其放入指定的数组便可以获得到不同通道具体的数据了。

DMA通道配置过程:
1、在DMA_CPARx寄存器中设置外设寄存起的地址,发生外设数据请求时,这个地址将是数据传输的源或目标。
2、在DMA_CMARx寄存器中设置数据存储寄存器的地址,发生外设数据请求时,传输的数据将从这个地址读出或写入这个地址。
3、在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
4、在DMA_CCRx寄存器的PL[1:0]位中设置优先级。
5、在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断,或
? ? ?传输完成产生中断。
6、设置DMA_CCRx寄存器的ENABLE位,启动该通道。

具体的配置过程我们通过代码来 展示

首先定义一个数组以便我们存放数据,数组大小按照实际需求即可。

u16 ADC_convered[2]={0,0};

然后是io口的初始化(我这儿把ADC的时钟也直接使能了)?

static void ADC_GPIO_CONFIG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	//使能 
    ADC1通道时钟
	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//初始化两个GPIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
}

再接下来便是重头戏了——DMA和ADC的初始化(有些部分是需要配置多个通道的)

static void ADC_MODE_CONFIG_(void)
{ 	
	
	DMA_InitTypeDef DMA_InitInstructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	DMA_DeInit(DMA1_Channel1);//复位
	DMA_InitInstructure.DMA_PeripheralBaseAddr =(u32)(&(ADC1->DR));//配置外设的基址,取adc 
    数据寄存器的地址
	DMA_InitInstructure.DMA_MemoryBaseAddr = (u32)ADC_convered;//把DMA的数据存入数组
	DMA_InitInstructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到DMA
	DMA_InitInstructure.DMA_BufferSize = 2;//2个通道
	DMA_InitInstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
	DMA_InitInstructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitInstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitInstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitInstructure.DMA_Mode = DMA_Mode_Circular;//不断地传输,有数据就传输
	DMA_InitInstructure.DMA_Priority = DMA_Priority_High;//DMA优先级
	DMA_InitInstructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel1,&DMA_InitInstructure);
	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA请求
	
	
	
	
	
	ADC_InitTypeDef ADC_InitStructure; 
	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立 
    模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;	//模数转换工作在多通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	//模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是 
    外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 2;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄 
    存器   




	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
		//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1,1, ADC_SampleTime_239Cycles5 );	 
      //ADC1,ADC1通道1,采样时间为239.5周期
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2,2, ADC_SampleTime_239Cycles5 );	 
     //ADC1,ADC1通道2,采样时间为239.5周期

    ADC_DMACmd(ADC1,ENABLE);	
    ADC_Cmd(ADC1,ENABLE);

	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束


}				  

然后把初始化的程序整到一块,方便调用

void Adc_Init()
{
   ADC_GPIO_CONFIG();
   ADC_MODE_CONFIG_();
}

接下来便是主函数部分了,主函数主要看要实现什么样的功能,初始化之后其实也就是把采集到的数据展示或设置阈值再进行相应的操作。

extern u16 ADC_convered[2];

int main(void)
{ 
   delay_init();
	//uart_init(9600);//串口初始化为9600,串口打印需要对其进行初始化
   float temp[2];
   delay_init();
   Oled_Init();
   Adc_Init();

	float value;
	float value1;
	char buf[5];
	char buf1[5];

	while(1)
	{
	    temp[0]=(float)ADC_convered[0]/4096*3.3;
		temp[1]=(float)ADC_convered[1]/4096*3.3;//结果-电压转换
		
		//printf("\r\n THE AD1 is = %f V \r\n",temp[0]);
		//printf("\r\n THE AD2 is = %f V \r\n",temp[1]);
	
        value = temp[0];
		sprintf(buf,"%f",value);
		Oled_Display_String(0,0,buf);//显示电压值
		
		value1 = temp[1];  
	    sprintf(buf1,"%f",value1);	
		Oled_Display_String(2,0,buf1);//显示电压值
		
		//Oled_Display_String(4,0,buf1);//	
		
		delay_ms(500);//延时了一小会儿,要不数据变化太快,看的心烦
        //我这儿是把电压值显示在了oled上
	}	  
}	

如有错误还请指出,谢谢

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:59:50  更:2021-08-06 10:00:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 9:55:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计