#include "dma.h"
#include "delay.h"
//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_Streamx
MA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx
MA通道选择,@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;
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;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_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传输
//DMA_Streamx
MA数据流,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传输
}
#include "adc.h"
void My_adc_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1,ENABLE);
//初始化ADC
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AN;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitStruct);
ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;
ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div2;
ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_10Cycles;
ADC_CommonInit(&ADC_CommonInitStruct);
ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfConversion=ADC_Channel_5;
ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
ADC_Init(ADC1,&ADC_InitStruct);
// ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
}
u16 get_result(void)
{
u16 ADC_result;
ADC_RegularChannelConfig(ADC1,5,1,ADC_SampleTime_480Cycles);//每次转换需要配置规则模式
ADC_SoftwareStartConv(ADC1);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==DISABLE);
ADC_result=ADC_GetConversionValue(ADC1);
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
return ADC_result;
}
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "adc.h"
#include "led.h"
#include "dma.h"
#define USART1_DR_BASE ((u32)0x40011004)
#define ADC1_DR_BASE ((u32)0x4001204c)
#define SENDSIZE 1
__IO u16 result_data;
int main(void)
{
u16 i;
u8 j;
delay_init(168);
uart_init(115200);
LED_Init();
My_adc_init();
MYDMA_Config(DMA2_Stream0,DMA_Channel_0,ADC1_DR_BASE,(u32)&result_data,SENDSIZE);
while(1)
{
ADC_DMACmd(ADC1,ENABLE);
MYDMA_Enable(DMA2_Stream0,SENDSIZE);
ADC_RegularChannelConfig(ADC1,5,1,ADC_SampleTime_480Cycles);//每次转换需要配置规则模式
ADC_SoftwareStartConv(ADC1);
while(1)
{
if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==ENABLE)
{
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
break;
}
LED1=!LED1;
delay_ms(500);
}
while(1)
{
if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==ENABLE)
{
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
break;
}
LED0=!LED0;
delay_ms(500);
}
printf("the result is %d
",result_data);
}
}
请问我设置的是AD连续采样模式,和DMA循环模式。为什么串口显示如下
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
为什么不更新AD转换结果?求助
你好 我最近也在学习这个 我想用读取两个模拟量 需要用到DMA 么
这个好像一般不需要,DMA好像一般用于比较大的数据保存数据,不过也可以通过这个练习一下
遇到问题可以大家讨论一下
一周热门 更多>