博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32实现双通道ADC采集电压电流值
阅读量:5020 次
发布时间:2019-06-12

本文共 4334 字,大约阅读时间需要 14 分钟。

本次的实验是通过配置DMA来获取ADC采集到的数据的。

软件实现如下:

  adc.c文件

#include "adc.h"#define ADC1_DR_Address    ((u32)0x40012400+0x4c)                      //定义ADC1地址volatile uint16_t ADCConvertedValue[2];                                //定义内存地址数组float AD_Value[2];static void ADC1_GPIO_Config(void){    GPIO_InitTypeDef GPIO_InitStructure;        /* Enable ADC1 and GPIOC clock */    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);        /* Configure PC.01  as analog input */    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    GPIO_Init(GPIOB, &GPIO_InitStructure);                               // PB0,PB1 ,输入时不用设置速率}static void ADC1_DMA_Config(void){    DMA_InitTypeDef DMA_InitStructure;        /* DMA channel1 configuration */    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);                    //使能DMA传输    DMA_DeInit(DMA1_Channel1);    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);        //ADC地址    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;     //内存地址    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;    DMA_InitStructure.DMA_BufferSize = 2;     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //外设地址固定    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;              //内存地址不固定    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //半字    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                       //循环传输    DMA_InitStructure.DMA_Priority = DMA_Priority_High;    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    DMA_Init(DMA1_Channel1, &DMA_InitStructure);}static void ADC1_Config(void){    /* ADC1 configuration */    ADC_InitTypeDef ADC_InitStructure;    ADC_DeInit(ADC1);        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);                  //使能ADC1时钟    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                   //独立ADC模式    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                         //启动扫描模式,扫描模式用于多通道采集    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                   //开启连续转换模式,即不停地进行ADC转换    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //不使用外部触发转换    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;               //采集数据右对齐    ADC_InitStructure.ADC_NbrOfChannel = 2;                               //要转换的通道数目2    ADC_Init(ADC1, &ADC_InitStructure);        /*配置ADC时钟,为PCLK2的6分频,即12Hz*/    RCC_ADCCLKConfig(RCC_PCLK2_Div6);     /*配置ADC1的通道8,9为239.5个采样周期,序列为1,2*/     ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1 , ADC_SampleTime_239Cycles5);    ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2 , ADC_SampleTime_239Cycles5);        /* Enable ADC1 DMA */    ADC_DMACmd(ADC1, ENABLE);        /* Enable ADC1 */    ADC_Cmd(ADC1, ENABLE);        /*复位校准寄存器 */       ADC_ResetCalibration(ADC1);    /*等待校准寄存器复位完成 */    while(ADC_GetResetCalibrationStatus(ADC1));        /* ADC校准 */    ADC_StartCalibration(ADC1);    /* 等待校准完成*/    while(ADC_GetCalibrationStatus(ADC1)); }void adc1_start(void){    ADC_SoftwareStartConvCmd(ADC1, ENABLE);                         //ADC1软计启动    DMA_Cmd(DMA1_Channel1, ENABLE);                                 //使能DMA通道1}void ADC1_Init(void){    ADC1_GPIO_Config();    ADC1_DMA_Config();    ADC1_Config();}

adc.h文件

#ifndef __ADC_H#define __ADC_H#include 
void ADC1_Init(void);void adc1_start(void);#endif /*ADC_H*/

main.c文件

#include "adc.h"extern volatile uint16_t ADCConvertedValue[2];                  //定义内存地址数组extern float AD_Value[2];int main(void){        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);             //设置中断优先级组为组2,2位抢占优先级,2位响应优先级    USART1_Int();                                               //串口初始化        ADC1_Init();                                                //ADC1初始化    adc1_start();    SysTick_Init();                                             //系统时钟初始化        while(1)    {               AD_Value[0]=(float)ADCConvertedValue[0]/4096*3.3;      //获取电压值       AD_Value[1]=(float)ADCConvertedValue[1]/4096*3.3;      //获取电流值               printf("\r\n电压值为:%f V\r\n",AD_Value[0]);       printf("\r\n电流值为:%f A\r\n",(AD_Value[1]-2.5)/0.185);    }}

本次实验的电流采集模块用的是ACS712模块,所以在打印输出时需要转换一下。

转载于:https://www.cnblogs.com/lucky-3/p/11269835.html

你可能感兴趣的文章
php面向对象编程(oop)基础知识示例解释
查看>>
1.在数组中找到与给定总和的配对
查看>>
树的子结构
查看>>
关于根据Build Platform或者OS 加载x86或者x64 dll的问题
查看>>
程序员高效开发的几个技巧
查看>>
js-权威指南学习笔记19.2
查看>>
hexo 搭建博客
查看>>
关于 UIWebView 几个高级用法
查看>>
maven创建的项目中无法创建src/main/java 解决方案
查看>>
华为软件开发云测评报告二:代码检查
查看>>
集合1
查看>>
js 原生 ajax
查看>>
关键词 virtual
查看>>
建造者模式(屌丝专用)
查看>>
UVALive 4730 Kingdom +段树和支票托收
查看>>
[APIO2010]特别行动队
查看>>
[SCOI2016]幸运数字
查看>>
SpringBoot 集成ehcache
查看>>
初步swift语言学习笔记2(可选类型?和隐式可选类型!)
查看>>
Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
查看>>