STM32 DMA 多通道

发布者:风暴使者最新更新时间:2016-10-05 来源: eefocus关键字:STM32  DMA  多通道 手机看文章 扫描二维码
随时随地手机看文章
ADC_init.C
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
extern vu16 After_filter[ADC_CH]; //用来存放求平均值之后的结果
extern vu16 ADCConvertedValue[ADC_num][ADC_CH];
DMA_InitTypeDef   DMA_InitStructure;  //DMA总线枚举类型
ADC_InitTypeDef   ADC_InitStructure;  //ADC 枚举类型
/*******************************************************************************
* 函数名称: GPIO_Configuration 
* 函数功能: 设置各GPIO端口功能 
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者: 张奇 
* 编写时间: 2012-8-23
* 修改时间: 
* 版    本: V1.0 
* 状    态:调试完成
*******************************************************************************/
void GPIO_Configuration(void) 
{     

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
                             RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|
                             RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE); //开所有IO时钟 
    
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_All; //选择IO口     
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO 输出速度
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //
        GPIO_Init(GPIOB, &GPIO_InitStructure);  //
        GPIO_Init(GPIOC, &GPIO_InitStructure);  //
        GPIO_Init(GPIOD, &GPIO_InitStructure);  //
        GPIO_Init(GPIOE, &GPIO_InitStructure);  //
        GPIO_Init(GPIOF, &GPIO_InitStructure);  //
        GPIO_Write(GPIOA, 0); 
        GPIO_Write(GPIOB, 0); 
        GPIO_Write(GPIOC, 0); 
        GPIO_Write(GPIOD, 0); 
        GPIO_Write(GPIOE, 0);
        GPIO_Write(GPIOF, 0); 
 /*****************AD 口***************/
      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //选择IO口
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN ;//模拟输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO 输出速度
      GPIO_Init(GPIOC, &GPIO_InitStructure);  //相关的GPIO口初始化
      
      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; //选择IO口
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN ;//模拟输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO 输出速度
      GPIO_Init(GPIOA, &GPIO_InitStructure);  //相关的GPIO口初始化   
}
/*******************************************************************************
* 函数名称: DMA_Configuration(void) 
* 函数功能: DMA控制器 设置
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者: 张奇 
* 编写时间: 2012-8-23
* 修改时间: 
* 版    本: V1.0 
* 状    态: ADC1 使用DMA1通道 CH1
*******************************************************************************/
void DMA_Configuration(void)
{
  
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //使能DMA时钟
  //DMA1 channel1 configuration ----------------------------------------------
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;//存放ADC数值
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据目的地址 RAM
  DMA_InitStructure.DMA_BufferSize =ADC_CH*ADC_num;//分配内部RAM
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不改变
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址递增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据宽度为16bit
  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);//
  DMA_Cmd(DMA1_Channel1, ENABLE);
}
/*******************************************************************************
* 函数名称: ADC_Configuration 
* 函数功能: ADC功能设置 使用DMA总线 通道1
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者: 张奇 
* 编写时间: 2012-8-23
* 修改时间: 
* 版    本: V1.0 
* 状    态:调试完成
*******************************************************************************/
void ADC_Configuration(void)
{
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);    //使能ADC1 时钟
  // ADC1 configuration ------------------------------------------------------
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//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_InitStructure.ADC_NbrOfChannel = ADC_CH;//N个通道
  ADC_Init(ADC1, &ADC_InitStructure);// ADC1 初始化

  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5);//GPIOC.0 环境温度
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5);//GPIOC.1  震动
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_239Cycles5);//GPIOC.2  流量
  ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_239Cycles5);//GPIOC.3  速度1
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 5, ADC_SampleTime_239Cycles5);//GPIOA.0 速度2
  
  ADC_DMACmd(ADC1, ENABLE); //使能DMA ADC1 
  ADC_Cmd(ADC1, ENABLE);//使能 ADC1 
  ADC_ResetCalibration(ADC1);// 重置指定的ADC的校准寄存器
  while(ADC_GetResetCalibrationStatus(ADC1)); // 等待重置指定的ADC的校准寄存器
  ADC_StartCalibration(ADC1);//开始指定ADC的校准程序 
  while(ADC_GetCalibrationStatus(ADC1)); // Check the end of ADC1 calibration  
  ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 使能或者失能指定的ADC的软件转换启动功能
}

ADC.c
vu16 ADC_value[ADC_num];//采样值处理中间寄存器
vu16 After_filter[ADC_CH]; //用来存放求平均值之后的结果
vu16 ADCConvertedValue[ADC_num][ADC_CH];//AD数据缓存
/******************************************************************************
* 函数名称: void get_filter(vu16 count) 
* 函数功能: 求平均值
*           采样数组排序  顺序:从小到大  去除最大值,最小值,再求平均值 
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 修改时间: 
* 修改内容: 
* 版    本:V1.0 
******************************************************************************/ 
void get_filter(vu16 count) 
{  
    u8 i,j; 
    int sum1 = 0;
    vu16 temp_ad=0;

    for(i=0;i     { 
        ADC_value[i]=ADCConvertedValue[i][count];
                 
    }     
    
    for(i=0;i     { 
        for(j=0;j         { 
            if(ADC_value[j]>ADC_value[j+1])    
            {
                temp_ad=ADC_value[j];
                ADC_value[j]=ADC_value[j+1];
                ADC_value[j+1]=temp_ad;
            }
                 
    }
        
    for(j=4;j     { 
        sum1 += ADC_value[j];        
    }     
    After_filter[count]=sum1/(ADC_num-8); 
    sum1=0; 
    
    }  



/******************************************************************************
* 函数名称:  GetVolt(u16 advalue)
* 函数功能: 获取ADC的值,将二进制换算为十进制
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者:张奇 
* 编写时间:2014-5-29
* 修改时间: 
* 修改内容: 
* 版    本:V1.0 
* 状    态:
******************************************************************************/
u16 GetVolt(u16 advalue) 

return (float)(advalue * 3300 / 4096); //求的结果扩大了100倍,方便下面求出小数
}  
/******************************************************************************
* 函数名称:  void filter(void)
* 函数功能: 求平均值函数
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者:张奇 
* 编写时间:2014-5-29
* 修改时间: 
* 修改内容: 
* 版    本:V1.0 
* 状    态:
******************************************************************************/ 
void filter(void) 
{  
int sum = 0; 
u8 count,temp_i; 
    for(temp_i=0;temp_i         { 
            for ( count=0;count                   { 
                  sum += ADCConvertedValue[count][temp_i]&0xFFFe; 
                  }  
              After_filter[temp_i]=sum/ADC_num; 
              sum=0;  
        } 

/******************************************************************************
* 函数名称:  WD__funtion1(vu8 channel)
* 函数功能: 数据转换
* 参数变量: NONE
* 全局变量: NONE
* 调用函数:
* 作    者:张奇 
* 编写时间:2014-5-29
* 修改时间: 
* 修改内容: 
* 版    本:V1.0 
* 状    态:
******************************************************************************/ 
int WD__funtion1(vu8 channel)
{
   float datax = 0,temp;
   
    s32 Current_Temp;
    get_filter(channel);
    switch(channel)
    {    
        case 0:
            //datax = GetVolt(After_filter[channel])*0.0778-0.3982;  //电阻    
            datax = GetVolt(After_filter[channel])*0.2037-258.19;   //温度            
            datax = datax *1.0012-0.3190;//温度的二次标定
            datax *= 10;//显示一位小数   
            
            break;
        case 1://震动
                temp= GetVolt(After_filter[channel]);//
                temp=temp/14.554;//电流
                temp=temp*10.0;
                datax=temp;
         
            break;
        case 2://流量
            temp= GetVolt(After_filter[channel]);//
            temp=temp/14.554;//电流
            temp=temp*100.0;
            datax=temp;
         
        break;
        case 3://速度1
            temp= GetVolt(After_filter[channel]);//
            temp=temp/14.554;//电流
            temp=temp*100.0;
            datax=temp;
            break;
        case 4://速度2
        temp= GetVolt(After_filter[3]);//
        temp=temp/14.554;//电流
        temp=temp*100.0;
        datax=temp;
        break;
        default:;break;
    }
    return (int)(datax);
}
关键字:STM32  DMA  多通道 引用地址:STM32 DMA 多通道

上一篇:STM32 Time3 内部触发AD采样配置
下一篇:STM32 RCC配置

推荐阅读最新更新时间:2024-03-16 15:13

STM32_内存管理
1:内存管理简介 内存管理,是指软件运行时动态的对MCU内存资源的分配和使用的技术。最主要的目的是:如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存管理的实现方法有很多种。 2:分块式内存管理 分块式内存管理由内存池和内存管理表两部分组成 ,内存池被等分为n块,对应的内存管理表,大小也为n,内存管理表的每一个项对应内存池的一块内存。 当该项值为0的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为10,那么说明包括本项对应的内存块在内,总共分配了10个内存块给外部的某个指针。 内存分配方向:是从顶-》底的分配方向。即首先从最末
[单片机]
STM32_内存管理
STM32速成笔记(3)—中断
一、什么是中断 首先介绍一下什么是中断。在实际开发过程中,中断是很有必要的。比如需要针对某种特殊情况进行快速响应,单纯的使用一个while轮询似乎并不能满足。中断的概念非常好理解,举个经典例子。比如你在家里看电视,忽然有人敲门,你临时把电视暂停了,转去开门。开完门之后再次回来继续看电视。 中断也就是这种流程。看电视的行为就类似于程序中main函数的while,轮询执行业务。忽然有人敲门,对应程序运行过程中忽然产生了一个中断请求。此时暂停电视,对应于此时程序中断当前的业务,转而去处理中断业务(开门)。最后,中断业务处理完成后,再继续执行main函数while轮询中的业务。简单用一个图来表示一下 中断概念示意图 根据中文参
[单片机]
<font color='red'>STM32</font>速成笔记(3)—中断
STM32(一)STM32简介
一、什么是STM32? 意法半导体(ST)集团于1988年6月成立,是由意大利的SGS微电子公司和法国Thomson半导体公司合并而成。1998年5月,SGS-THOMSON Microelectronics将公司名称改为意法半导体有限公司,是世界最大的半导体公司之一。 STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex®-M0,M0+,M3, M4和M7内核(ST's product portfolio contains a comprehensive range of microcontrollers, from robust, low-cost 8-bit MCUs up
[单片机]
<font color='red'>STM32</font>(一)<font color='red'>STM32</font>简介
STM32 基础系列教程 8 - 互补PWM
前言 PWM及互补PWM是电机控制的基础,前面我们已经学习了PWM的产生,今天来学习一下互补PWM的产生,互补PWM就是两个互补的PWM的组合,用stm32 的高级定时器可以直接产生两路互补的PWM(即互补PWM)。 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。 本示例所用的最小系统板原理图: 从本节开始,关于CUBEMX工具及KEIL工具的操作将不再细讲,如果还有不熟悉的可以查看之前的教程文档。下面直接介绍工程配置: 系统时钟树 高级定时器TIM1配置
[单片机]
<font color='red'>STM32</font> 基础系列教程 8 - 互补PWM
Stm32_调试出现 Error:Flash Download Failed-"Cortex-M3"
rror:Flash Download Failed- Cortex-M3 出现一般有两种情况: 1.SWD模式下,Debug菜单中,Reset菜单选项(Autodetect/HWreset/sysresetReq/Vectreset)默认是AutoDetect,改成SysResetReq即可。 2.Jtag模式下,主要是芯片大小选错。Flash- Configure Falsh Tools配置窗口,切换到“Utilities 页,按“Setting 按钮进入“Flash download setup 配置窗口,在“Flash download setup 配置窗口点击“Add”按钮,在“Add Flash Program
[单片机]
Stm32_调试出现 Error:Flash Download Failed-
STM32正交编码器编程
如图,STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。 如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。 代码如下: void Decoder_Configuration(void) { GPIO_InitTypeDef GPIO_InitSt
[单片机]
<font color='red'>STM32</font>正交编码器编程
关于STM32单片机GPIO口上拉与下拉输入
以前GPIO上接的电路都是低电平触发的那种,新画了个板子有一个按键设计的是高电平触发,结果IO口设置成上拉输入后,怎么读都不正确,按键电路如图1。无奈只能去调试一下,发现当设置为上拉输入后,其ODR(GPIO输出数据寄存器)相应的也置为1,百思不得其解。 图1 按键电路 于是去看一下GPIO的结构图: I/O引脚结构图 由图可以发现其实输出寄存器与输入寄存器之间在I/O引脚处是线与状态,在GPIO设置成上位输入时,其上拉电阻闭合,这时如果输出寄存器设置为0那么在IO口内部就会自己损耗电流,而这些电流的损耗是会增加功耗的。因此当GPIO设置成上拉输入时,相应的输出寄存器也设置为1. 将按键电路与I/O
[单片机]
关于<font color='red'>STM32</font>单片机GPIO口上拉与下拉输入
新款STM32U5:让便携产品拥有惊艳图效
凝聚ST超低功耗微控制器技术精华的STM32U5于2021年问世,是一款堪称可改变游戏规则的低功耗MCU。 作为STM32高性能低功耗系列旗舰产品, STM32U5延续STM32F2/F4/F7的应用范围,同时又有更低的能耗,具有更高的性价比。 在工业控制系统中,U5可以承担主控器、系统监控以及图形显示等核心职能。 高性能,低功耗,丰富的数字外设和更高性能的模拟接口,强大的安全特性,以及支持图形加速,让STM32U5在工业控制、工业表计和医疗健康,个人穿戴设备等应用领域取得良好的表现,为泛工业系统创新赋能。在这个视觉统治一切的时代,人们对图形效果的追求永远没有止境,同时也希望实现起来更简单快速,性价比更高。“如果只
[单片机]
新款STM32U5:让便携产品拥有惊艳图效
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved