您的位置:首页 > 其它

STM32 ADC—DMA传输

2016-04-11 16:35 302 查看
因为规则通道转换的值一直存储在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据

例程:

将ADC1的通道4,5,6使用DMA传输

总结

1.DMA外设基地址(DMA_MemoryBaseAddr),当只需要读取一个通道的值时,设置成某一自定义变量的地址;当需要读取多个通道的值时,设成某一自定义数组的地址。地址都是32位——(uint32_t)

例如 u16 RecBuff[3];

DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)RecBuff;

2.DMA传送ADC采样值到定义的数组或者变量,如果需要得到采样值,不需要再使用ADC_GetConversionValue(ADCx);直接用数组或变量转化即可

temp1=(float)RecBuff[0]*(3.3/4096);

3.DMA_DIR_PeripheralDST 外设作为数据传输的目的地;

DMA_DIR_PeripheralSRC 外设作为数据传输的来源

4.ADC 设置成连续转换模式,若是多通道,使能扫描

ADC_InitStructure.ADC_ScanConvMode = ENABLE;

5.ADC为12位,将外设数据宽度和存储器数据宽度设为半字

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

ADC1设置步骤

1)开启端口时钟和ADC1时钟

2)复位ADC1,同时设置ADC分频因子

3)初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息

4)使能ADC并校准

5)配置规则通道参数

6)开启软件转换

//7)使能ADC1的DMA传送

DMA设置步骤

1)使能DMA时钟

2)初始化DMA通道参数

3)使能DMA函数

常用的外设DMA使能函数

USART_DMACmd();

ADC_DMACmd();

DAC_DMACmd();

I2C_DMACmd();

SPIO_DMACmd();

SPI_I2S_DMACmd();

TIM_DMACmd();

4)使能DMA通道,启动传输

5)查询DMA传输状态

代码块(STM32F1)

adc.c
//初始化ADC
//ADC1规则通道4、5、6
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟

RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6,ADC最大时间不能超过14M

//PA4,5,6 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

ADC_DeInit(ADC1);  //复位ADC1

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;    //模数转换工作在扫描模式
ADC_InitStructure.ADC_ContinuousC
4000
onvMode = ENABLE;  //模数转换工作在连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

ADC_Cmd(ADC1, ENABLE);  //使能指定的ADC1

ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1);  //开启AD校准
while(ADC_GetCalibrationStatus(ADC1));   //等待校准结束

ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3,ADC_SampleTime_239Cycles5);

ADC_DMACmd(ADC1,ENABLE); //使能ADC1的DMA发送

ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能
}

dam.c
//配置DMA1
//从存储器->外设模式/16位数据宽度/存储器增量模式
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量
void MYDMA_Config(u32 cpar,u32 cmar,u16 cndtr)
{
DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输时钟

DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值

DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设发送到内存
DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
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_High; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);
}

//得到转换值
if(DMA_GetFlagStatus(DMA1_FLAG_TC1)!=RESET)
{
temp1=(float)RecBuff[0]*(3.3/4096);
temp2=(float)RecBuff[1]*(3.3/4096);
temp3=(float)RecBuff[2]*(3.3/4096);
DMA_ClearFlag(DMA1_FLAG_TC1); //清除通道1传输完成标志
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: