OpenEdv-开源电子网

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

DMA的中断

[复制链接]

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
发表于 2017-10-10 11:05:01 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 Bunny17 于 2017-10-10 11:21 编辑

每次进入中断函数,关闭中断使能,判断是否为我们需要的中断标志,做相应的操作,然后清除标志,重新使能中断,然后不做任何操作,退出中断函数后,DMA是否继续在传输呢,还是需要在中断里面又重新配置一次,开始DMA.

最佳答案

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

不好意思 ,前面问题解决了,那个是自己粗心,都没有设置DMAx是DMA1还是DMA2
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:05:02 | 显示全部楼层
不好意思 ,前面问题解决了,那个是自己粗心,都没有设置DMAx是DMA1还是DMA2
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:06:55 | 显示全部楼层
请赐教。。。。。。。。。。。。。。。。
回复

使用道具 举报

19

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2017-9-21
在线时间
171 小时
发表于 2017-10-10 11:07:11 | 显示全部楼层
你设置的是连续传输还是单次?
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-10-10 11:11:15 | 显示全部楼层
写0还是写1?
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:22:22 | 显示全部楼层
现在新的问题哈
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:22:52 | 显示全部楼层
哆啦A萌 发表于 2017-10-10 11:07
你设置的是连续传输还是单次?

连续传输。。。。
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:23:08 | 显示全部楼层

写1是对的。
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 11:38:47 | 显示全部楼层
我试了一下,是需要重新开启DMA的,但是如果我只是重新开始DMA,通过串口显示,一直都是一样的数据,难道我的ADC没有重新采样吗,我的ADC也是设置的连续转换模式啊。
while(DMAx->LISR&0X20)
                                {
                                        LED0=!LED0;
                                        DMAx->LIFCR |= 1<<5;                //清除传输完成中断标志
                                       
                                }       
                                Adc_Init();  
                                MYDMA_Enable(DMA2_Stream0,512);
我的程序必须这样才可以连续采集,连续传输,通过串口显示就是正确的不重复的数据。
如果我将Adc_Init(); 改成仅仅
ADC1->CR2|=1<<0;                   //开启AD转换器 使能ADC       
        ADC1->CR2|=1<<30;       //启动规则转换通道
这两行就不可以。
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-10-10 11:58:55 | 显示全部楼层
本帖最后由 wxjhby 于 2017-10-10 12:01 编辑

DMA是循环模式,AD是连续采样的还不行就只能跟着寄存器慢慢调了 看是不是哪里漏了
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 13:55:33 | 显示全部楼层
wxjhby 发表于 2017-10-10 11:58
DMA是循环模式,AD是连续采样的还不行就只能跟着寄存器慢慢调了 看是不是哪里漏了

嗯嗯,再找找
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 14:57:59 | 显示全部楼层
本帖最后由 Bunny17 于 2017-10-12 11:56 编辑

void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u8 chx,u32 par,u32 mar,u16 ndtr)
{
        DMA_TypeDef *DMAx;
        u8 streamx;
        if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
                DMAx=DMA2;
                RCC->AHB1ENR|=1<<22;//DMA2时钟使能
        }else
        {
                DMAx=DMA1;
                 RCC->AHB1ENR|=1<<21;//DMA1时钟使能
        }
        while(DMA_Streamx->CR&0X01);//等待DMA可配置   开发指南寄存器版本P226
        streamx=(((u32)DMA_Streamx-(u32)DMAx)-0X10)/0X18;                //得到stream通道号
         if(streamx>=6)DMAx->HIFCR|=0X3D<<(6*(streamx-6)+16);        //清空之前该stream上的所有中断标志
        else if(streamx>=4)DMAx->HIFCR|=0X3D<<6*(streamx-4);    //清空之前该stream上的所有中断标志
        else if(streamx>=2)DMAx->LIFCR|=0X3D<<(6*(streamx-2)+16);//清空之前该stream上的所有中断标志
        else DMAx->LIFCR|=0X3D<<6*streamx;                                                //清空之前该stream上的所有中断标志
        
        DMA_Streamx->PAR=par;                //DMA外设地址
        DMA_Streamx->M0AR=mar;                //DMA 存储器0地址
        DMA_Streamx->NDTR=ndtr;                //数据传输量
        DMA_Streamx->CR=0;                        //先全部复位CR寄存器值
        
        DMA_Streamx->CR|=0<<6;                //存储器到外设模式 改为外设到存储器
        DMA_Streamx->CR|=1<<8;                //非循环模式(即使用普通模式) 改为使能循环模式
        DMA_Streamx->CR|=0<<9;                //外设非增量模式
        DMA_Streamx->CR|=1<<10;                //存储器增量模式
        DMA_Streamx->CR|=1<<11;                //外设数据长度:8位 改为16位,因为ADC为12位
        DMA_Streamx->CR|=0<<13;                //存储器数据长度:8位 改为16位2017.08.03 又改回去改为8位2017.09.06
        DMA_Streamx->CR|=1<<16;                //中等优先级
        DMA_Streamx->CR|=0<<21;                //外设突发单次传输  ???
        DMA_Streamx->CR|=0<<23;                //存储器突发单次传输
        DMA_Streamx->CR|=(u32)chx<<25;//通道选择
        //DMA_Streamx->FCR=0X21;        //FIFO控制寄存器
        DMA_Streamx->CR&=~(1<<0);         //关闭DMA传输
        while(DMA_Streamx->CR&0X1);        //确保DMA可以被设置
        DMA_Streamx->CR|=1<<0;                //开启DMA传输
}

//初始化ADC                                                                                                                                          
void  Adc_Init(void)
{   
        //先初始化IO口
         RCC->APB2ENR|=1<<8;            //使能ADC1时钟  中文参考手册P144
        RCC->AHB1ENR|=1<<1;            //使能PORTB时钟        
        RCC->AHB1ENR|=1<<2;            //使能PORTC时钟
        
        GPIO_Set(GPIOB,PIN0|PIN1,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);        //PB0 PB1,模拟输入,下拉
        GPIO_Set(GPIOC,PIN0|PIN1|PIN2|PIN3|PIN4|PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);        //PC0-PC5,模拟输入,下拉        
         

        RCC->APB2RSTR|=1<<8;           //ADCs复位
        RCC->APB2RSTR&=~(1<<8);        //复位结束         
        ADC->CCR=3<<16;                        //ADCCLK=PCLK2/8=96/8=12Mhz,ADC时钟最好不要超过36Mhz
         
        ADC1->CR1=0;                           //CR1设置清零
        ADC1->CR2=0;                           //CR2设置清零
        ADC1->CR1|=0<<24;              //12位模式
        ADC1->CR1|=1<<8;            //使能扫描模式        
        
        ADC1->CR2|=1<<1;            //连续转换模式
         ADC1->CR2&=~(1<<11);           //右对齐        
        ADC1->CR2|=0<<28;            //软件触发
        ADC1->CR2|=1<<8;            //使能DMA
        
        ADC1->SQR1&=~(0XF<<20);  //位 23:20  L[3:0]:规则通道序列长度  
        ADC1->SQR1|=7<<20;                                 
        //设置通道8的采样时间
        ADC1->SMPR2&=~(7<<(3*8));//通道8采样时间清空          PB0 ADC12_IN8
         ADC1->SMPR2|=7<<(3*8);               ..............................
        
         ADC1->SQR3&=0XC0000000;//规则序列1 通道
        ADC1->SQR2&=0XFFFFFC00;//规则序列1 通道
        ADC1->SQR3|=10<<0;
        ..................
        
        //ADC->CCR=2<<14;        //使能DMA模式2  ???
        
        ADC1->CR2|=1<<0;                   //开启AD转换器 使能ADC        
        ADC1->CR2|=1<<30;       //启动规则转换通道         

回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-10 14:58:15 | 显示全部楼层
没找到问题出在哪里     
回复

使用道具 举报

19

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
257
金钱
257
注册时间
2017-8-2
在线时间
46 小时
 楼主| 发表于 2017-10-12 11:59:35 | 显示全部楼层
ADC直接关闭连续转换模式,没采集完一系列数据后,再重新开始规则转换。  
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 16:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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