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

news2024/11/24 7:42:24

 

#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.coloradmin.cn/o/100368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux-12月第四周-磁盘存储和文件系统

文章目录管理存储使用磁盘空间过程为什么要磁盘分区划分分区的方式MBR管理存储 使用磁盘空间过程 买来一块新硬盘后&#xff0c;有以下三个使用步骤 第一步&#xff1a;划分分区&#xff08;将硬盘划分为若干个分区&#xff0c;windows上的C盘&#xff0c;D盘&#xff0c;E盘…

SCUT01在线协作白板技术解决方案

在七牛云校园黑客马拉松中&#xff0c;来自华南理工大学的SCUT01团队&#xff0c;为我们带来了UI精美、体验优秀的白板作品&#xff0c;在大赛中获得二等奖的好成绩。以下是这款在线协作白板的技术解决方案。 背景 疫情背景下&#xff0c;线上课堂、线上会议等业务背景下都有着…

PCL 点云配准衡量指标

0. 简介 PCL作为目前最为强大的点云库&#xff0c;内部存在有大量集成好的算法。而对于数据量大、非同源、含大量噪声且部分重叠的激光点云与影像重建点云&#xff0c;其稀疏程度、噪声程度等不同&#xff0c;非重叠区域的面积很大。真实场景的点云尤其是影像重建点云噪声较多…

用javascript分类刷leetcode23.并查集(图文视频讲解)

并查集&#xff08;union & find&#xff09;&#xff1a;用于处理一些元素的合并和查询问题 Find&#xff1a;确定元素属于哪一个子集&#xff0c;他可以被用来确定两个元素是否属于同一个子集&#xff0c;加入路径压缩&#xff0c;复杂度近乎O(1) Union&#xff1a;将两…

如何在 ESXi 7.x 上安装 Windows Server 2019

安装 Windows Server 2019 连接 ESXi 7.0上传 Windows Server 2019 镜像创建虚拟机安装 Windows Server 2019在本文中,我们将逐步在 ESXi 7.x 上安装 Windows Server 2019。 连接 ESXi 7.0 使用 VMware 主机或 vSphere Web 客户端连接到 VMware vSphere Hypervisor 7.0(ESX…

Unity-ROS与话题与服务(二)

0. 简介 对于ROS而言&#xff0c;其最常用的就是Topic话题以及Service两个了。之前我们在了解Unity Robotics Hub时候就了解到基本的Unity和ROS的通讯&#xff0c;下面我们来详细介绍一下Unity与ROS的话题与服务。 ROS和Unity之间的通信是通过Unity的“ROS-TCP-Connector”软…

Linux学习07-vim程序编辑器

1 vi与vim vi 是老式的文书处理器&#xff0c;不过功能已经很齐全了&#xff0c;但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具&#xff0c;就连 vim 的官方网站 &#xff08;http://www.vim.org&#xff09; 自己也说 vim 是一个“程序开发工具”而…

服务器内存CPU负载监控

1&#xff0c;系统平均负载(Load average)&#xff1a; 系统平均负载被定义为在特定时间间隔内运行队列中的平均进程树&#xff0c;一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的&#xff0c;如果每个CPU的任务数大于5&#xff0c;那么就表示这台机器的…

SpringBoot+MDC实现链路调用日志

1.首先介绍什么是MDC MDC&#xff08;Mapped Diagnostic Context&#xff0c;映射调试上下文&#xff09;是 log4j 、logback及log4j2 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的哈希表&#xff0c;可以往其中添加键值对。MDC 中包含的…

毕业设计 STM32自行车智能无线防盗报警器 -物联网 单片机 嵌入式

0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过…

【C++进阶】C++11新特性下篇(万字详解)

&#x1f387;C学习历程&#xff1a;入门 博客主页&#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 也许你现在做的事情&#xff0c;暂时看不到成果&#xff0c;但不要忘记&…

京东前端高频vue面试题(边面边更)

Redux 和 Vuex 有什么区别&#xff0c;它们的共同思想 &#xff08;1&#xff09;Redux 和 Vuex区别 Vuex改进了Redux中的Action和Reducer函数&#xff0c;以mutations变化函数取代Reducer&#xff0c;无需switch&#xff0c;只需在对应的mutation函数里改变state值即可Vuex由…

【树莓派】擦灰重启行动

高中时候看大佬各种秀项目&#xff0c;于是乎兴致冲冲买了一块树莓派4B&#xff0c;400r&#xff0c;当时没想到光是开机&#xff0c;就折腾了两个星期~后来不出意外它在房间的角落很安逸地吃灰&#xff0c;但是&#xff0c;后来&#xff0c;我误打误撞学了CS&#xff0c;再误打…

Okhttp源码分析实践(五)【实践环节:Okhttp的基本框架搭建请求实现】

http的基础知识、okhttp的框架基本源码,我们通过之前课程都已学习总结过,接下来,就是关键的实践课程。 各位coder,需要紧跟小编脚步,要开始加速飙车了。 1.基本框架的搭建实现 既然不知道如何入手,我们不妨就以okhttp的基本使用代码为例,作为入手点,去开始编程实现。…

机器学习理论介绍

前言 图灵奖获得者、著名数据库专家James Gray 博士观察并总结人类自古以来&#xff0c;在科学研究上&#xff0c;先后历经了实验、理论、计算和数据四种范式。 科学研究第一种范式&#xff1a;实验 在古代&#xff0c;人们的认知水平较低&#xff0c;对事物的认识很大程度上…

React redux使用

1.redux是什么 redux是一个专门用于状态管理的JS库&#xff08;不是react插件库&#xff09; 它可以用在react,angular,vue等项目中&#xff0c;但基本与react配合使用 作用&#xff1a;集中式管理react应用中多个组件共享的状态 2.为什么要使用redux 某个组件的状态&#…

Windows命令行到底有多强大?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store DevWeekly收集整理每周优质开发者内容&#xff0c;包括开源项目、资源工具、技术文章等方面。 每周五定期发布&#xff0c;同步更新到 知乎&#xff1a;Jackpop。 欢迎大家投稿&#xff0c;提交issu…

高可用系列文章之三 - NGINX 高可用实施方案

前文链接 高可用系列文章之一 - 概述 - 东风微鸣技术博客 (ewhisper.cn)高可用系列文章之二 - 传统分层架构技术方案 - 东风微鸣技术博客 (ewhisper.cn) 四 NGINX 高可用实施方案 高可用的实施, 主要步骤概述如下: NGINX 的安装及基础配置负载均衡层高可用: NGINX Keepali…

在BSV上运行深度神经网络

我们已经实现了一个用于手写数字分类的深度神经网络。已经训练好的模型完全在链上运行。它使用手写数字的 MNIST 数据集进行离线训练。该模型采用 28x28 灰度像素的图像并输出 0 到 9 的数字。 深度神经网络简介 人工神经网络是受生物神经网络启发而构建的。网络通过接触大量带…