我用的
单片机是
STM32F103VC,扫描ADC1的8个通道,用DMA1传输转换结果。DMA接收后的数据与实际ADC的结果不一致。
部分代码如下:
void CSL_ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12M,ADC最大时间不能超过14M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOC,&GPIO_InitStructure);
//ADC1初始化
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在扫描模式
ADC_InitStructure.ADC_Con
tinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 8; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1,&ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1,ENABLE); //使能指定的ADC1
//ADC1校准
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
//配置每个通道的转换次序和采样时间
ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 1,ADC_SampleTime_71Cycles5); //TC1
ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 2,ADC_SampleTime_71Cycles5); //TC2
ADC_RegularChannelConfig(ADC1,ADC_Channel_3, 3,ADC_SampleTime_71Cycles5); //TC3
ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 4,ADC_SampleTime_71Cycles5); //TC4
ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 5,ADC_SampleTime_71Cycles5); //TC5
ADC_RegularChannelConfig(ADC1,ADC_Channel_6, 6,ADC_SampleTime_71Cycles5); //TC6
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,7,ADC_SampleTime_71Cycles5); //Current1
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,8,ADC_SampleTime_71Cycles5); //Current2
}
void CSL_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA传输
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&ADC1->DR); //DMA外设ADC1转换结果基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC1Result; //DMA内存基地址 ADC1Result 为数组
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设读取数据到内存
DMA_InitStructure.DMA_BufferSize = 32; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //数据宽度为32位
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; //数据宽度为32位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA1通道1拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
void APP_Measure_Temperature_Current(void) //扫描ADC1 8个通道,用DMA传输数据 100ms周期调用
{
ADC_DMACmd(ADC1,ENABLE); //开启ADC1 DMA传输
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能指定的ADC1的软件转换启动功能
DMA_Cmd(DMA1_Channel1, ENABLE);
DMA_SetCurrDataCounter(DMA1_Channel1,32);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //等待转换结束 大约56us
while(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET)
{
DMA_ClearFlag(DMA1_FLAG_TC1); //清除通道1传输完成标志
break;
}
ADC_DMACmd(ADC1,DISABLE); //关闭ADC1 DMA传输
DMA_Cmd(DMA1_Channel1,DISABLE);
ADC_SoftwareStartConvCmd(ADC1,DISABLE); //关闭指定的ADC1的软件转换启动功能
}
是配置问题,还是其他。请赐教,第一次使用DMA。
函数固件库中样例程序走起,有用DMA来ADC的样例。我第一次用ADC就是DMA的,非常省事。
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
为什么是DMA_PeripheralDataSize_HalfWord,ADC转换结果寄存器是32位的,应该是DMA_PeripheralDataSize_Word的吧,如果只转一路的话,DMA_InitStructure.DMA_BufferSize 为4个字节吗?
一周热门 更多>