#include "sys.h"
#include "adc.h"
#include "delay.h"
#define ADC1_DR_Address ((uint32_t)ADC1_BASE+0x4c)
__IO uint16_t ADC1OscConver[10]={0};
void DMA2_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//打开DMA2的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
//初始化个寄存器的配置
DMA_DeInit(DMA2_Stream0);
DMA_StructInit( &DMA_InitStructure);
//选取DMA通道0,数据流0
DMA_InitStructure.DMA_Channel=DMA_Channel_0;
//设置外设的基地址
DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)ADC1_DR_Address;
//设置内存的地址
DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&ADC1OscConver;
//设置数据从外设传到内存
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;
//设置每次传送的数据量1000
DMA_InitStructure.DMA_BufferSize=10;
//外设地址不变
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
//内存地址每次加1
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
//外设发送数据大小为半字
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
//内存接收数据为半字
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
//不断的循环从外设发送数据到内存
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;
//设置数据流的优先级
DMA_InitStructure.DMA_Priority=DMA_Priority_High;
//这里不用FIFO模式
DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
//将以上应用于数据流0和通道0
DMA_Init(DMA2_Stream0,&DMA_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//选择DMA2数据流0通道0
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn;
//抢占式优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
//响应式优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=4;
//通道使能
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//将以上配置应用于NVIC
NVIC_Init(&NVIC_InitStructure);
//使能DMA传输中断
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);
//使能DMA
DMA_Cmd(DMA2_Stream0, ENABLE);
}
//time2定时器的配置
void Tim2Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
//打开time2的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_Prescaler=42-1;
TIM_TimeBaseInitStruct.TIM_Period=44;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//使用更新事件作为触发
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
TIM_Cmd(TIM2,ENABLE); //使能定时器
}
//初始化ADC
//初始化规则通道
void Adc_Init(void)
{
//先配置IO口 使用ADC1 通道5
GPIO_InitTypeDef GPIO_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //使能ADC1的时钟
//先初始化ADC1通道5的IO
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5; //PA5 ADC1 通道5
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AN; //模拟输入
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL; //不带上下拉
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);//复位结束
//初始化ADC的通用设置
//设置ADC为独立模式
ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;
//两个采样阶段之间延时5个时钟
ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
//DMA失能
ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_1;
//设置ADC预分频为4分频
//这里分频以后要小于36MHZ,而4分频后频率为21MHZ
ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;
ADC_CommonInit(&ADC_CommonInitStruct);//初始化
//初始化ADC1相关参数
ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;//12位模式
//非扫描模式
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
//关闭连续转换
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;
//触发检测
ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_Rising;
//使用外部触发来启动AD转换 这里使用定时器2的TRGO触发
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_TRGO;
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_InitStruct.ADC_NbrOfConversion=1;//一个转换在规则序列中
ADC_Init(ADC1,&ADC_InitStruct);
// //使能ADC在DMA模式下的连续转换
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
//使能ADC的DMA模式
ADC_DMACmd(ADC1,ENABLE);
//开启ADC转换
ADC_Cmd(ADC1,ENABLE);
}
//获得ADC值
//ch:通道值0~15
//返回值:转换结果
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_3Cycles); //第三个参数为规则组采样第一个
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回一次转换结果
}
//获取通道ch的转换值,取times后然后平均
//ch为通道编号 times为获取次数
//返回值 ch的times次转换的平均结果
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
现在不使用DMA的时候可以采集到数据,而且使用DMA可以进到中断服务函数,请大虾帮忙看一下问题!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>