Stm32标准库函数2——多通道ADC DMA

news/2024/11/24 9:44:52/

 

#include "stm32f10x.h"    //在该头文件中默认定义系统时钟为72M
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "adc.h"
#include "DMA.h"

//串口:A9 A10,波特率115200;AD为A0-A4

//u16 AdcBuff[SIZE];
extern u8 uartFlag;
int main(void)
{        
       u32 i;
//    float temp;
    delay_init();             //延时函数初始化      
    NVIC_Configuration();      //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    DMA_NVIC_Configuration();
    uart_init(115200);         //串口初始化为9600
    Adc_Init();                  //ADC初始化
    DMA_Configuration();//必须重新配置
     while(1)
    {
      if(uartFlag!=0){
        ADC_Cmd(ADC1, ENABLE);    
        delay_ms(1000);    
        for(i=0;i<SIZE;i++)
            Show_u16(AD_Value[i]);
//        USART1_SendData(0X0D);     //换行
//        USART1_SendData(0X0A);     //回车    
        uartFlag=0;    
      }
      //delay_ms(1);
    }    
}

#include "stm32f10x.h"
#include "DMA.h"
#include "usart.h"
#include "delay.h"

u16 AD_Value[SIZE]={0};

/*************
    配置DMA
*************/
void DMA_Configuration(void)
{

    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
                                                  
    DMA_DeInit(DMA1_Channel1);   //将DMA//的通道1//寄存器重设为缺省//值
    DMA_InitStructure.DMA_PeripheralBaseAddr =  (u32)&ADC1->DR ;  //DMA外设ADC基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;  //DMA内存基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //内存作为数据传输的目的地
    DMA_InitStructure.DMA_BufferSize = SIZE;  //DMA通道的DMA缓存的大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环缓存模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级  
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道
    DMA_Cmd(DMA1_Channel1, ENABLE);
    DMA_ClearITPendingBit(DMA1_IT_GL1);                   //清除DMA1全局中断标志位
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);    
    //使能DMA1的存储完成中断    


}
/*******************************
功能:配置嵌套中断向量控制器NVIC
*******************************/
void DMA_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    
    /* DMA中断优先级配置 */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn ;   //选择DMA1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;   //
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
    NVIC_Init(&NVIC_InitStructure);


}
/******************************
    DAM1中断服务函数
*******************************/
void DMA1_Channel1_IRQHandler(void)
{
     if(DMA_GetITStatus(DMA1_IT_TC1) != RESET )              //DMA是否中断
    {
        ADC_Cmd(ADC1, DISABLE);    //暂停ADC    
        DMA_ClearITPendingBit(DMA1_IT_TC1);                   //清除DMA完成中断标志位
    }
    DMA_ClearITPendingBit(DMA1_IT_GL1);                       //清除DMA中断全局标志位
}

#include "adc.h"
 #include "delay.h"

                                                                    
void  Adc_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_Pin_1|GPIO_Pin_2| GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);    

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

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                 //ADC1和ADC2独立工作模式
//    ADC_InitStructure.ADC_ScanConvMode = DISABLE;                         //ADC设置为单通道模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                        
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                  //设置为连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制开始转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                //AD输出数值为右端对齐方式
    ADC_InitStructure.ADC_NbrOfChannel = 4;                             //指定要进行AD转换的信道数量
    ADC_Init(ADC1, &ADC_InitStructure);                                 //用上面的参数初始化ADC1

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0,  1, ADC_SampleTime_239Cycles5); //ADC_SampleTime_239Cycles5=239.5个AD时钟周期。
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1,  2, ADC_SampleTime_239Cycles5);  //AD最小转换时间不能小于1.17us(STM32F103),12M Hz是最小为ADC_SampleTime_13Cycles5
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2,  3, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3,  4, ADC_SampleTime_239Cycles5);
 
    ADC_DMACmd(ADC1, ENABLE);//使能ADC1的DMA                                                                  //采样时间为55.5个周期
    ADC_Cmd(ADC1, ENABLE);                                              //使能ADC1
    ADC_ResetCalibration(ADC1);                                          //重置ADC1校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));                          //得到重置校准寄存器状态
    ADC_StartCalibration(ADC1);                                          //开始校准ADC1
    while(ADC_GetCalibrationStatus(ADC1));                              //得到校准寄存器状态
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);                              //使能ADC1由软件控制开始转换

}                  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
      //设置指定ADC的规则组通道,一个序列,采样时间
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_1Cycles5 );    //ADC1,ADC通道,采样时间为28.5周期                      
 
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能    
    
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

    return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
    u32 temp_val=0;
    u8 t;
    for(t=0;t<times;t++)
    {
        temp_val+=Get_Adc(ch);
//        delay_ms(5);
    }
    return temp_val/times;
}     


http://www.ppmy.cn/news/5043.html

相关文章

HTML5网页设计制作基础大二dreamweaver作业、使用HTML+CSS技术制作博客网站(5个页面)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

数据中心网络学习资料

目录 该文章持续更新&#xff0c;收集了一些比较好的与数据中心相关的文章和课程。 文章&#xff1a; 老网工&#xff1a;浅谈数据中心云网技术的历经风雨和演进&#xff1a;https://www.sdnlab.com/22920.html 数据中心网络架构浅谈&#xff08;一&#xff09;&#xff1a;…

【GRU回归预测】基于灰狼算法优化门控循环单元GWO-GRU神经网络实现多输入单输出回归预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;​​Matlab科研工作室​​ &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; ​​智…

大数据必学Java基础(一百一十五):Session域监听器

文章目录 Session域监听器 一、Session域共有四个监听器接口 二、监听器代码 Session域监听器

【GO】 K8s 管理系统项目[API部分--Daemonset]

K8s 管理系统项目[API部分–Daemonset] 1. 接口实现 service/dataselector.go // daemonCell type daemonSetCell appsv1.DaemonSetfunc(d daemonSetCell) GetCreation() time.Time {return d.CreationTimestamp.Time }func(d daemonSetCell) GetName() string {return d.Na…

kettle - get请求

文章目录前言kettle - get请求前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#xff0c;那欢迎常来啊!!! kettle - get请…

[附源码]计算机毕业设计Python高校商铺管理系统论文(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

毕业设计 单片机GPS定位位置记录系统 - 物联网 嵌入式 stm32

文章目录0 前言1 简介2 主要器件3 实现效果4 硬件设计概述硬件模块的连接**AB32VG1主控MCU**5 软件说明6 部分核心代码7 最后0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩…