2019物联网开发者大会 12.06 北京北辰洲际酒店→ 报名参会 ←
电子产品世界 » 论坛首页 » 企业专区 » GD32 » GD32107C-EVAL--ADC实验(二)

共1条 1/1 1 跳转至

GD32107C-EVAL--ADC实验(二)

高工
2015-03-31 01:51:57    评分

这次的实验和上一个ADC实验不同的是,采用扫描模式采样通道13和通道16。因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据。 只有在规则通道的转换结束时才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户指定的目的地址。因此这样也能体验一下GD32的DMA功能。

void  AdcInit()
{
    GPIO_InitTypeDef    GPIO_InitStruct;
	  ADC_InitTypeDef     ADC_InitStruct;
	  DMA_InitTypeDef     DMA_InitStruct;
	
	  RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1 ,ENABLE );
	  RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1, ENABLE);
	  RCC_ADCCLKConfig (RCC_PCLK2_Div6);
	  RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC,ENABLE);
	
	  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN ;
	  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
	  GPIO_Init (GPIOC,&GPIO_InitStruct);
	
	  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE ;
	  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
	  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	  ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
	  ADC_InitStruct.ADC_NbrOfChannel = 2;
	  ADC_InitStruct.ADC_ScanConvMode = ENABLE ;
	  ADC_Init (ADC1,&ADC_InitStruct);
		
		ADC_RegularChannelConfig(ADC1,ADC_Channel_13,1,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC_Channel_16,2,ADC_SampleTime_239Cycles5);
		
		
		
		ADC_DMACmd (ADC1,ENABLE);
	  ADC_Cmd (ADC1,ENABLE);
		ADC_TempSensorVrefintCmd (ENABLE );
		
		
	  ADC_ResetCalibration(ADC1);
	  while(ADC_GetResetCalibrationStatus(ADC1) == SET)
		{
         ;
    }
    ADC_StartCalibration(ADC1);	
		while(ADC_GetCalibrationStatus(ADC1) == SET)
		{
         ;
    }
	  
	  
		
		DMA_InitStruct.DMA_BufferSize = 2;
		DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC ;
		DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
		DMA_InitStruct.DMA_MemoryBaseAddr = (u32)gAdcVal;
		DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord   ;
		DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
		DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
		DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));
		DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord    ;
		DMA_InitStruct.DMA_Priority = DMA_Priority_High;
		DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
		DMA_Init (DMA1_Channel1 ,&DMA_InitStruct);
		DMA_Cmd (DMA1_Channel1,ENABLE);
		
    ADC_SoftwareStartConvCmd (ADC1,ENABLE);
}

 

这次代码没有在中断服务函数里去获取AD采样的值,在这里是通过建立一个数组,通过DMA来直接将ADC1的数据寄存器的值传到数组中。那么再主函数里就可以直接使用:

float  gVoltage = 0.01;
float  gTemperate = 0.01;

int main()
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LedPinInit();
	SysTickInit();
	TimerInit(99,7199);
	AdcInit();
	GUI_Init();
	GUI_SetBkColor(GUI_RED);
	GUI_SetColor(GUI_WHITE);
	GUI_Clear();
	GUI_DispStringAt("liklon--->GD32107C-EVAL",1,40);
	GUI_DispStringAt("www.eepw.com.cn",40,60);
	GUI_DispStringAt("ADC:",80,80);
	GUI_DispStringAt("VOLTAGE:",48,120);
	GUI_DispStringAt("TEMPERATE:",48,160);
	while(1)
	{
		  if(gLedRunFlag > 10)
			{
        gVoltage = gAdcVal[0] * 3.3 / 4096.0;
 				gTemperate = gAdcVal[1] * 3.3 / 4096.0;
				gTemperate = (1.43 - gTemperate) / 0.0043 + 25;
				GUI_DispDecAt(gAdcVal[0],100,100,4);
 				GUI_GotoXY(100,140);
 				GUI_DispFloat(gVoltage,3);
				GUI_GotoXY(100,180);
 				GUI_DispFloat(gTemperate,5);
				gLedRunFlag = 0;
      }
	}
}

 

计算温度误差比较大,下面是效果图:


这次体验的是DMA功能在ADC中的应用,这样以后如果需要多个通道采集时,便方便许多了。GD32的内部资源丰富而且都非常实用。这个温度误差有点大,不知道是不是自己换算的过程中有问题,一眼看出道道的童鞋希望可以指点指点。




关键词: GD32     ADC     DMA    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]