OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4730|回复: 4

我使用双重adc模式和dma,以及定时器pwm触发adc采集,可是什么都采集不到,请问该怎么配置呢

[复制链接]

12

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-10-1
在线时间
39 小时
发表于 2017-10-4 22:51:03 | 显示全部楼层 |阅读模式
7金钱

TIM触发双重ADC采集DMA存储.rar

8.79 MB, 下载次数: 165

程序如下

最佳答案

查看完整内容[请看2#楼]

论坛搜索参考下别人的代码吧
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-10-4 22:51:04 | 显示全部楼层
论坛搜索参考下别人的代码吧
回复

使用道具 举报

12

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-10-1
在线时间
39 小时
 楼主| 发表于 2017-10-5 13:54:08 | 显示全部楼层
程序如下
DMA部分的初始化

#include "dma.h"                                                                                                                                                     
#include "delay.h"                 
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//DMA 驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////          


//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chxMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//par:外设地址
//mar:存储器地址
//ndtr:数据传输量  
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{

        DMA_InitTypeDef  DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
               
        }else
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
        }
  DMA_DeInit(DMA_Streamx);
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
       
  /* 配置 DMA Stream */
  DMA_InitStructure.DMA_Channel = chx;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//存储器到外设模式
  DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据长度:32位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//存储器数据长度:32位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//最高优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
       
        DMA_ITConfig(DMA2_Stream0, DMA_IT_TC , ENABLE);
       
        NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
       
        NVIC_Init(&NVIC_InitStructure);
}

ADC的初始化

#include "adc.h"
#include "delay.h"                 
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//ADC 驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        


//初始化ADC                                                                                                                          
void  Adc_Init(void)
{   
  GPIO_InitTypeDef  GPIO_InitStructure;
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
        ADC_InitTypeDef       ADC_InitStructure;
       
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟
       
  //先初始化GPIO口
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4;//ADC1的PA0和ADC2的PA4
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);          //ADC1复位
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);        //复位结束
       
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);          //ADC2复位
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);        //复位结束
       
  ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;//双重ADC规则同时模式
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;//两个采样阶段之间的延迟5个时钟
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2; //DMA2模式
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化
       
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式       
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T4_CC4;//触发源TIM4CH4
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//上升沿触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐       
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
  ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//从adc关闭触发
  ADC_Init(ADC2, &ADC_InitStructure);
       
        ADC_Cmd(ADC1, ENABLE);//开启AD转换器       
  ADC_Cmd(ADC2, ENABLE);
       
        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles);
        ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_480Cycles);
       
        ADC_DMACmd(ADC1, ENABLE);

       
}       

PWM初始化

void TIM4_PWM_Init(void)
{                                                          
        //此部分需手动修改IO口设置
       
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);          //TIM4时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);         //使能GPIOB时钟       
       
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_TIM4); //GPIOB9复用为定时器4
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOB9
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
        GPIO_Init(GPIOB,&GPIO_InitStructure);              //初始化PB9
          
        TIM_TimeBaseStructure.TIM_Prescaler=8399;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=499;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化定时器4
       
        //初始化TIM4  PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性低
        TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4

        TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR1上的预装载寄存器
       
        TIM_CtrlPWMOutputs(TIM4, ENABLE);//高级定时器要开启MOE位

        TIM_SetCompare1(TIM4, 100);

        TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE使能
       
        TIM_Cmd(TIM4, ENABLE);  //使能TIM14

                                                                                  
}  


主程序
#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "adc.h"
#include "dma.h"
#include "lcd.h"
#include "led.h"
#include "pwm.h"

//ALIENTEK 探索者STM32F407开发板 实验0
//STM32F4工程模板-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK

/*定义32位数组储存ADC1和ADC2的电压*/
void DMA2_Stream0_IRQHandler()
{
        if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)==1)
        {
                TIM_Cmd(TIM4, DISABLE);
        }
        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC);
}

u32 Voltage[20];
u8 time=0;
u32 voltage1,voltage2;
int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        delay_init(168);
        uart_init(115200);
        Adc_Init();
        LCD_Init();
        TIM4_PWM_Init();
        MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC->CDR,(u32)Voltage,20);
        LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");        //先在固定位置显示小数点  
        DMA_Cmd(DMA2_Stream0, ENABLE);
        TIM_Cmd(TIM4, ENABLE);
        delay_ms(50);
        voltage2=(ADC->CDR)&0xFFFF0000;
        printf("\r\n voltage1 value = %fV\r\n",(float)voltage2);
        LCD_ShowxNum(134,130,voltage2,4,16,0);
        delay_ms(1000);
        for(time=0;time<20;time++)
        {
                voltage1=Voltage[time]&0x0000FFFF;
                voltage1=(float)(voltage1*3.3/4096);
                voltage2=(Voltage[time]&0xFFFF0000)>>16;
                voltage2=(float)(voltage2*3.3/4096);
                printf("\r\n voltage1 value = %fV\r\n",(float)voltage1);
                printf("\r\n voltage2 value = %fV\r\n",(float)voltage2);
        }
       
       
}
回复

使用道具 举报

12

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-10-1
在线时间
39 小时
 楼主| 发表于 2017-10-5 13:54:37 | 显示全部楼层
请问上面的程序哪里出了问题呢
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2019-3-17
在线时间
2 小时
发表于 2019-4-25 17:32:05 | 显示全部楼层
正点原子 发表于 2017-10-4 22:51
论坛搜索参考下别人的代码吧

原子哥,问个小问题。比如用TIM1作为触发源触发adc的时候,寄存器该怎么配置啊?是直接配置TIM1的EGR么?如果是用EGR,怎么判断TIM1的触发事件是event几?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 13:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表