OpenEdv-开源电子网

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

关于103DMA和ADC和程序问题

[复制链接]

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
发表于 2017-5-16 20:49:37 | 显示全部楼层 |阅读模式
1金钱
这几天学了ADC和DMA,想结合使用一下。但是今天写代码出现了问题。ADC没法把值通过DMA给一个数组。但是可以直接读取ADC的值,说明ADC程序是可以的。贴出代码吧。

#include "DMA.h"
#include "stm32f10x.h"

u16 size;
void MYDMA_Init1(uint32_t MADDR,uint32_t ADC_ADDR,u16 BSIZE)
{
        DMA_InitTypeDef DMA_InitStruct;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
       
        size=BSIZE;
        DMA_InitStruct.DMA_BufferSize=BSIZE;
        DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;                //íaéèμ½Äú′æ
        DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryBaseAddr=MADDR;
        DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;
        DMA_InitStruct.DMA_PeripheralBaseAddr=ADC_ADDR;
        DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStruct.DMA_Priority=DMA_Priority_High;
        DMA_Init(DMA1_Channel1,&DMA_InitStruct);       
}

void MYDMA_Init2(uint32_t MADDR,uint32_t USART_ADDR,u16 BSIZE)
{
        DMA_InitTypeDef DMA_InitStruct;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
       
        size=BSIZE;
       
        DMA_InitStruct.DMA_BufferSize=BSIZE;
        DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;                //Äú′æμ½íaéè
        DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryBaseAddr=MADDR;
        DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Disable;
        DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;
        DMA_InitStruct.DMA_PeripheralBaseAddr=USART_ADDR;
        DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;
        DMA_Init(DMA1_Channel4,&DMA_InitStruct);
               
}

void A2M_DMA_Enable()
{
        DMA_Cmd(DMA1_Channel1,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel1,size);
        DMA_Cmd(DMA1_Channel1,ENABLE);
        ADC_DMACmd(ADC1,ENABLE);
        /*while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
        DMA_ClearFlag(DMA1_FLAG_TC1);*/
}

void M2U_DMA_Enable()
{
        DMA_Cmd(DMA1_Channel4,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel4,size);
        DMA_Cmd(DMA1_Channel4,ENABLE);
        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
        while(DMA_GetFlagStatus(DMA1_FLAG_TC4)==RESET);
        DMA_ClearFlag(DMA1_FLAG_TC1);
}

最佳答案

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

找出BUG了,ADC_DMACmd(ADC1,ENABLE);这个指令要先于DMA。但是 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 这个指令倒是不用。有大神来解释一下为什么么。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-16 20:49:38 | 显示全部楼层
找出BUG了,ADC_DMACmd(ADC1,ENABLE);这个指令要先于DMA。但是        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
这个指令倒是不用。有大神来解释一下为什么么。
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-16 20:50:55 | 显示全部楼层
MYDMA_Init2是可以的,可以把数组的值发给串口
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-5-16 21:20:48 | 显示全部楼层
帮顶
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 08:21:53 | 显示全部楼层

谢谢原子哥帮顶,有人来帮帮忙么。。。
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 08:58:41 | 显示全部楼层
传输错误和传输完成标志位都没有致1.。可能压根就没有传输,不知道配置哪里出问题或者少配置了什么。
回复

使用道具 举报

10

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2017-4-20
在线时间
102 小时
发表于 2017-5-17 14:02:15 | 显示全部楼层
   我最近也卡在ADC+DMA +串口了  
回复

使用道具 举报

10

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2017-4-20
在线时间
102 小时
发表于 2017-5-17 14:03:50 | 显示全部楼层
能打包程序给我参考下么        貌似串口打印  不需要开DMA4通道        
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 14:21:28 | 显示全部楼层
564646396 发表于 2017-5-17 14:03
能打包程序给我参考下么        貌似串口打印  不需要开DMA4通道

怎么发文件?
回复

使用道具 举报

10

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2017-4-20
在线时间
102 小时
发表于 2017-5-17 14:37:47 | 显示全部楼层
回帖栏这一行有个表情         这一行的最右端就是上传文件夹   然后你在发表回复   也可以  加我QQ  564646396   一起讨论交流   
回复

使用道具 举报

9

主题

101

帖子

0

精华

高级会员

Rank: 4

积分
532
金钱
532
注册时间
2017-3-5
在线时间
74 小时
发表于 2017-5-17 15:09:28 | 显示全部楼层
hyh80227 发表于 2017-5-17 09:44
找出BUG了,ADC_DMACmd(ADC1,ENABLE);这个指令要先于DMA。但是        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABL ...

你用的是ADC和DMA,不关串口的事,为啥使能串口DMA呢
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 15:33:37 | 显示全部楼层
openedvxiaowang 发表于 2017-5-17 15:09
你用的是ADC和DMA,不关串口的事,为啥使能串口DMA呢

是这样的,ADC的值通过DMA发送到RAM,然后吧RAM的值通过DMA发送到串口
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 15:35:11 | 显示全部楼层
564646396 发表于 2017-5-17 14:37
回帖栏这一行有个表情         这一行的最右端就是上传文件夹   然后你在发表回复   也可以  加我QQ  564 ...

[mw_shl_code=c,true]#include "DMA.h"
#include "stm32f10x.h"

u16 size;
void MYDMA_Init1(uint32_t MADDR,uint32_t ADC_ADDR,u16 BSIZE)
{
        DMA_InitTypeDef DMA_InitStruct;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
       
        size=BSIZE;
        DMA_InitStruct.DMA_BufferSize=BSIZE;
        DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;                //íaéèμ½Äú′æ
        DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryBaseAddr=MADDR;
        DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;
        DMA_InitStruct.DMA_PeripheralBaseAddr=ADC_ADDR;
        DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStruct.DMA_Priority=DMA_Priority_High;
        DMA_Init(DMA1_Channel1,&DMA_InitStruct);       
}

void MYDMA_Init2(uint32_t MADDR,uint32_t USART_ADDR,u16 BSIZE)
{
        DMA_InitTypeDef DMA_InitStruct;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
       
        size=BSIZE;
       
        DMA_InitStruct.DMA_BufferSize=BSIZE;
        DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;                //Äú′æμ½íaéè
        DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryBaseAddr=MADDR;
        DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;
        DMA_InitStruct.DMA_PeripheralBaseAddr=USART_ADDR;
        DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;
        DMA_Init(DMA1_Channel4,&DMA_InitStruct);
               
}

void A2M_DMA_Enable()
{
        DMA_Cmd(DMA1_Channel1,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel1,size);
        DMA_Cmd(DMA1_Channel1,ENABLE);
        while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
        DMA_ClearFlag(DMA1_FLAG_TC1);
}

void M2U_DMA_Enable()
{
        DMA_Cmd(DMA1_Channel4,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel4,size);
        DMA_Cmd(DMA1_Channel4,ENABLE);
        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
        while(DMA_GetFlagStatus(DMA1_FLAG_TC4)==RESET);
        DMA_ClearFlag(DMA1_FLAG_TC4);
}





#include "ADC.h"
#include "stm32f10x.h"

void MYADC_Init()
{
        GPIO_InitTypeDef GPIO_InitStruct;
        ADC_InitTypeDef ADC_InitStruct;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
        //GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
       
        ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;
        ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
        ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
        ADC_InitStruct.ADC_NbrOfChannel=1;
        ADC_InitStruct.ADC_ScanConvMode=DISABLE;
        ADC_Init(ADC1,&ADC_InitStruct);
       
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_71Cycles5);
       
        ADC_DMACmd(ADC1,ENABLE);
        ADC_Cmd(ADC1,ENABLE);
       
        ADC_ResetCalibration(ADC1);
        while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);
        while(ADC_GetCalibrationStatus(ADC1));
}

u16 MYADC_ENABLE()
{
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_71Cycles5);
        ADC_SoftwareStartConvCmd(ADC1,ENABLE);
        while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
        return ADC_GetConversionValue(ADC1);
}

[/mw_shl_code]
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 15:37:03 | 显示全部楼层
564646396 发表于 2017-5-17 14:37
回帖栏这一行有个表情         这一行的最右端就是上传文件夹   然后你在发表回复   也可以  加我QQ  564 ...

主函数你应该会的。
回复

使用道具 举报

10

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2017-4-20
在线时间
102 小时
发表于 2017-5-17 16:05:44 | 显示全部楼层
谢谢哈   已经搞出来了     如果你需要交流 可以加我
QQ图片20170517160530.png
回复

使用道具 举报

9

主题

101

帖子

0

精华

高级会员

Rank: 4

积分
532
金钱
532
注册时间
2017-3-5
在线时间
74 小时
发表于 2017-5-17 16:10:24 | 显示全部楼层
hyh80227 发表于 2017-5-17 15:33
是这样的,ADC的值通过DMA发送到RAM,然后吧RAM的值通过DMA发送到串口

嗯嗯,你是要用这个发送到电脑串口助手看数据对吧。这就需要了。我是外接一个LCD屏,在那里看的
回复

使用道具 举报

10

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2017-4-20
在线时间
102 小时
发表于 2017-5-17 16:24:23 | 显示全部楼层
openedvxiaowang 发表于 2017-5-17 16:10
嗯嗯,你是要用这个发送到电脑串口助手看数据对吧。这就需要了。我是外接一个LCD屏,在那里看的

我不是楼主   楼主和我应该是陷入了一个思想误区   以为ADC 通道的值  都存储在DMA通道1   只要通过DMA通道4才能发送出去    然后我想清楚了  跟DMA通道4 串口1发送的没有关系  
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 20:28:35 | 显示全部楼层
564646396 发表于 2017-5-17 16:24
我不是楼主   楼主和我应该是陷入了一个思想误区   以为ADC 通道的值  都存储在DMA通道1   只要通过DMA通 ...

不是,程序的错误是ADC开启DMA要在初始化之前。之后就不行了。我也不知道为什么。
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-5-16
在线时间
29 小时
 楼主| 发表于 2017-5-17 21:01:19 | 显示全部楼层
好吧,问题又来了。。我把ADC的值存到数组里,居然只是存上了一个,我设置了RAM地址递增,也设置了个数。。。
回复

使用道具 举报

9

主题

101

帖子

0

精华

高级会员

Rank: 4

积分
532
金钱
532
注册时间
2017-3-5
在线时间
74 小时
发表于 2017-5-18 09:12:58 | 显示全部楼层
564646396 发表于 2017-5-17 16:24
我不是楼主   楼主和我应该是陷入了一个思想误区   以为ADC 通道的值  都存储在DMA通道1   只要通过DMA通 ...

回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-21 02:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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