#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转换结果?求助
仿真的时候看一下寄存器
这个ADC采用的是外部触发吗?
两个通道ADC转换,是不是需要打开ADC扫描模式
扫描模式
此模式用于扫描一组模拟通道。
通过将 ADC_CR1 寄存器中的 SCAN 位置 1 来选择扫描模式。将此位置 1 后, ADC 会扫描
在 ADC_SQRx 寄存器(对于规则通道)或 ADC_JSQR 寄存器(对于注入通道)中选择的
所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一
个通道。如果将 CONT 位置 1,规则通道转换不会在组中最后一个所选通道处停止,而是再
次从第一个所选通道继续转换。
一周热门 更多>