OpenEdv-开源电子网

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

求助各位大神:dma传输完成中断一直生不成

[复制链接]

1

主题

4

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-7
在线时间
3 小时
发表于 2017-10-9 21:42:06 | 显示全部楼层 |阅读模式
5金钱
这个dma是用在adc连续扫描中的,想在中断中处理一些数据,结果中断一直生不成。经测试,dma循环传输和adc连续扫描没有问题,问题就是产生不了中断,望各位大神帮忙解决以下,多谢了!!
       下面是程序
                 dma配置:
             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_Disable;//存储器FEI增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;//存储器数据长度:16位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
  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_FlowControllerConfig(DMA_Streamx,DMA_FlowCtrl_Memory);
               
    NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn; //定时器3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);       
       
        DMA_ITConfig(DMA2_Stream0,DMA_IT_TCIF0,ENABLE);//使能中断
       
}
//开启一次DMA传输
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量  
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr)
{

        DMA_Cmd(DMA_Streamx, DISABLE);                      //关闭DMA传输
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}        //确保DMA可以被设置  
               
        DMA_SetCurrDataCounter(DMA_Streamx,ndtr);          //数据传输量  

        DMA_Cmd(DMA_Streamx, ENABLE);                      //开启DMA传输
}          


void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream0,DMA_FLAG_TCIF0))
{       
        LED1=0;
}
   DMA_ClearITPendingBit(DMA2_Stream0,DMA_FLAG_TCIF0);
}


      adc配置:

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


//初始化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时钟

  //先初始化ADC1通道5 IO口
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//|GPIO_Pin_1;//PA5 通道5
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//|GPIO_Pin_1;//PA5 通道5
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//模拟输入
  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);        //复位结束         

       
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;//预分频8分频。ADCCLK=PCLK2/4=84/8=10.5Mhz,ADC时钟最好不要超过36Mhz
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化
       
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//FEI扫描模式       
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//上升沿触发检测

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐       
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
  ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
        //设置指定ADC的规则组通道,一个序列,采样时间
        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles );        //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度       

        ADC_DMACmd(ADC1,ENABLE);
    ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
        ADC_Cmd(ADC1, ENABLE);//开启AD转换器       

}       


            main.c:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
#include "dma.h"
#include "dacdma.h"
#include "time1.h"
//#include "time2.h"
#include "dac.h"

//ALIENTEK 探索者STM32F407开发板 实验18
//ADC模数转换实验-库函数版本  
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com  
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK
const uint16_t Buffer1[256]={0,50,100,151,201,251,301,351,401,451,501,551,601,651,700,750,
799,848,897,946,995,1044,1092,1141,1189,1237,1285,1332,1380,1427,1474,
1521,1567,1613,1660,1705,1751,1796,1841,1886,1930,1975,2019,2062,2105,
2148,2191,2233,2275,2317,2358,2399,2439,2480,2519,2559,2598,2637,2675,
2713,2750,2787,2824,2860,2896,2931,2966,3000,3034,3068,3101,3133,3166,
3197,3228,3259,3289,3319,3348,3377,3405,3433,3460,3486,3512,3538,3563,
3588,3612,3635,3658,3680,3702,3723,3744,3764,3783,3802,3821,3838,3856,
3872,3888,3904,3919,3933,3947,3960,3972,3984,3996,4006,4016,4026,4035,
4043,4051,4058,4064,4070,4075,4080,4084,4087,4090,4092,4094,4095,4095,
4095,4094,4092,4090,4087,4084,4080,4075,4070,4064,4058,4051,4043,4035,
4026,4016,4006,3996,3984,3972,3960,3947,3933,3919,3904,3888,3872,3856,
3838,3821,3802,3783,3764,3744,3723,3702,3680,3658,3635,3612,3588,3563,
3538,3512,3486,3460,3433,3405,3377,3348,3319,3289,3259,3228,3197,3166,
3133,3101,3068,3034,3000,2966,2931,2896,2860,2824,2787,2750,2713,2675,
2637,2598,2559,2519,2480,2439,2399,2358,2317,2275,2233,2191,2148,2105,
2062,2019,1975,1930,1886,1841,1796,1751,1705,1660,1613,1567,1521,1474,
1427,1380,1332,1285,1237,1189,1141,1092,1044,995,946,897,848,799,750,
700,651,601,551,501,451,401,351,301,251,201,151,100,50};




uint16_t Buffer2[1];


int main(void)
{
        u16 dacval=0;
        u16 adcx1;
        float temp1;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);    //初始化延时函数
        uart_init(115200);        //初始化串口波特率为115200
        LED_Init();                                        //初始化LED
        LCD_Init();         //初始化LCD接口
       
        DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0
        MYDACDMA_Config(DMA1_Stream5,DMA_Channel_7,(u32)&DAC->DHR12R1,(u32)Buffer1,256);
        MYDACDMA_Enable(DMA1_Stream5,256);
        Dac1_Init();                                 //DAC通道1初始化       
    TIM6_Int_Init(200-1,80-1);

        MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)Buffer2,1);
        Adc_Init();         //初始化ADC
        MYDMA_Enable(DMA2_Stream0,1);
       
        ADC_SoftwareStartConv(ADC1);
       
    while(1)
                {
                if(Buffer2[0]>3061) PAout(6)=1;
         if(Buffer2[0]<1861) PAout(6)=0;
        }
}                       


adc采的是dac输出的正弦半波。A4输出,A0采入,主函数循环里面本来想在中断中完成,后来测试对主函数循环和中断服务函数内容做了修改。
望各位大神多多指教!!



最佳答案

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

问题解决了,主要还是中断使能的错误,多谢各位了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-7
在线时间
3 小时
 楼主| 发表于 2017-10-9 21:42:07 来自手机 | 显示全部楼层
1375185311 发表于 2017-10-10 08:35
把这个改一下:
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能

问题解决了,主要还是中断使能的错误,多谢各位了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2017-10-10 00:19:05 | 显示全部楼层
帮顶,论坛参考下别人的代码吧
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-7
在线时间
3 小时
 楼主| 发表于 2017-10-10 07:51:24 来自手机 | 显示全部楼层
正点原子 发表于 2017-10-10 00:19
帮顶,论坛参考下别人的代码吧

原子哥,看出什么端倪没有啊
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-10-9
在线时间
0 小时
发表于 2017-10-10 08:35:08 | 显示全部楼层
把这个改一下:
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-7
在线时间
3 小时
 楼主| 发表于 2017-10-10 11:28:47 来自手机 | 显示全部楼层
1375185311 发表于 2017-10-10 08:35
把这个改一下:
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能

我用的是独立模式,那个dma使能是多重模式。adc采样和dma传输都没问。刚发现了一个问题DMA_ITConfig(DMA2_Stream0,DMA_IT_TCIF0,ENABLE);//使能中断
里面应该是DMA_IT_TC,但是改过来还是不行,我按照你说的也改了一下,还是不行。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-18 18:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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