国民技术与stm32 ADC采集

发布时间:2024年01月04日

一、国民技术芯片ADC采集配置

/*
PA1  ADC1_IN2  默认功能
DMA 通道1由ADC1触发
外部晶振16  系统时钟144M  AHB 2分频 HCLK=72M
HCLK  经APB1 4分频 pclk1 = 18M=HCLK/4
HCLK  经APB2 4分频 pclk2 = 18M=HCLK/4

ADCCLK不得超过14M


*/
void DMA_ADC_Config(void)
{
	  ADC_InitType ADC_InitStructure;
      DMA_InitType DMA_InitStructure;
	  GPIO_InitType GPIO_InitStructure;
	  
	  /* Enable peripheral clocks ------------------------------------------------*/	
	  /* Enable DMA1 and DMA2 clocks */	 
	  RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1 , ENABLE);   
	  /* Enable ADC1, ADC2, ADC3 and GPIOC clocks */	
	  // RCC_EnableAPB2PeriphClk(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2_PERIPH_GPIOC, ENABLE);    
	  /* Enable GPIOC clocks */	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);    
	  /* Enable ADC1, ADC2, ADC3 and ADC4 clocks */	
	  RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1,ENABLE);	
	  /* RCC_ADCHCLK_DIV16 144/16  72/8*/	   
	  ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8);


     GPIO_InitStructure.Pin       = GPIO_PIN_1;    
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    
	 GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
	  
  /* DMA1 channel1 configuration ----------------------------------------------*/
    DMA_DeInit(DMA1_CH1);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)&ADCConvertedValue;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 1;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_DISABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(DMA1_CH1, &DMA_InitStructure);
    /* Enable DMA1 channel1 */
    DMA_EnableChannel(DMA1_CH1, ENABLE);

    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_NONE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
   
	 //  配置ADC时钟分频因子  不超过14M    8分频得到
	 //  使用外部高速时钟
	 // RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV2);
	 
    /* ADC1 regular channel14 configuration */
		
    //ADC_ConfigRegularChannel(ADC1, ADC_CH_2, 1, ADC_SAMP_TIME_55CYCLES5);
		ADC_ConfigRegularChannel(ADC1, ADC1_Channel_02_PA1, 1, ADC_SAMP_TIME_55CYCLES5);
	
    /* Enable ADC1 DMA */
    ADC_EnableDMA(ADC1, ENABLE);

    /* Enable ADC1 */
    ADC_Enable(ADC1, ENABLE);
	
    /*Check ADC Ready*/
    while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET);
	
    /* Start ADC1 calibration */
    ADC_StartCalibration(ADC1);
	
    /* Check the end of ADC1 calibration */
    while (ADC_GetCalibrationStatus(ADC1));

    /* Start ADC1 Software Conversion */
    ADC_EnableSoftwareStartConv(ADC1, ENABLE);
}

二、stm32? ADC采集

// ADC多通道采集 
void ADC_IN_x_Config(void)
{
   ADC_InitTypeDef ADC_InitStructure;
	
	  //  使能ADC时钟
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	  
	 //  ADC结构体配置
	 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;   //  独立模式   ADC1/2/3/4只使用了一个
	 ADC_InitStructure.ADC_ScanConvMode = ENABLE;         //  扫描模式 
	 ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;     //  连续转换(多次转换ENABLE)   一次转换(disable) 
	 ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;  //  禁止触发检测、使用软件触发  ADC_ExternalTrigConv_None
	 ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; //   右对齐
	 ADC_InitStructure.ADC_NbrOfChannel=NOFCHANEL;                //  2个转换在规则序列中
	 ADC_Init(ADC1,&ADC_InitStructure);

	 //  配置ADC时钟分频因子  不超过14M     APB2=72M   APB2 8分频得到
	  RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	
	 // 配置ADC通道的转换顺序和采样时间 Tconv = 采样时间 +  12.5 个周期   第三个参数为通道转换序列
   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 55.5 个时钟周期 
  
	 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 2,第二个转换,采样时间为 55.5 个时钟周期 
	
   //ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);              // ADC 转换结束产生中断,在中断服务程序中读取转换值 
	 ADC_DMACmd(ADC1,ENABLE);                               // 使能ADC DMA请求
	 
	 //  使能ADC并开始转换
	 ADC_Cmd(ADC1,ENABLE);
	 
	 //  初始化并校准寄存器
	 ADC_ResetCalibration(ADC1);
	 
	 //  等待校准寄存器初始化完成
	 while(ADC_GetResetCalibrationStatus(ADC1));
	 
	 //  ADC开始校准
	 ADC_StartCalibration(ADC1);
	 
	 //  等待校准完成
	 while(ADC_GetCalibrationStatus(ADC1));
	 
	 //  软件触发ADC转换,没有使用时外部触发
	 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	  
}
/*********************************************DMA配置*********************************************/
// 1、DMA_Chx  DMA通道  2、Dpba  外设地址  3、Dmba  存储器地址  4、Dbse  DMA通道的缓冲区大小
void DMA_Config(DMA_Channel_TypeDef* DMA_Chx,uint32_t Dpba,uint32_t Dmba,uint32_t Dbs)
{
	DMA_InitTypeDef DMA_InitStructure; 
  //  使能时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	//  复位DMA控制器  DMA 通道复位
	DMA_DeInit(DMA_Chx);
	
	//  配置结构体
	DMA_InitStructure.DMA_PeripheralBaseAddr=Dpba;  //  ADC数据寄存器地址
	DMA_InitStructure.DMA_MemoryBaseAddr=Dmba;      //  存储器地址  目标地址
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//  数据传输方向:数据来源于外设
	DMA_InitStructure.DMA_BufferSize=Dbs;           //  DMA缓冲区大小=数据目的地的大小
	
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;             //   指定外设地址寄存器是否递增.只有一个不递增
	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工作模式  循环输出模式    正常工作模式DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority=DMA_Priority_High;                          //   优先级 DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响 
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                               //   禁用内存到内存的传输模式   外设->内存
	
	DMA_Init(DMA_Chx,&DMA_InitStructure);
	DMA_Cmd(DMA_Chx,ENABLE);
}

初始化

#define ADC_X_PIN     GPIO_Pin_0
#define ADC_X_CHANNEL ADC_Channel_8

#define ADC_Y_PIN     GPIO_Pin_1
#define ADC_Y_CHANNEL ADC_Channel_9

// ADC1 对应 DMA1 通道 1,ADC3 对应 DMA2 通道 5,ADC2 没有 DMA 功能 
#define ADC_DMA_CHANNEL DMA1_Channel1 

ext short int ADC_CollectValue[NOFCHANEL];   //  需要ADC转换的电压值
#define NOFCHANEL  2

void ADC_XY_Init(void)
{
	
	//  x(PA0)、y轴 引脚初始化   模拟输入   AD
	// GPIOx_Config(RCC_APB2Periph_GPIOA,GPIOA,GPIO_Pin_0|GPIO_Pin_1,GPIO_Mode_AIN);
	  GPIO_InitTypeDef GPIO_InitStructure;
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; // 模拟输入
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//  ADC配置
	//  Tconv = 采样时间 + 12.5 个周期    55.5+12.5  Tconver=(55.5+12.5)*1/9=7.55us
	 ADC_IN_x_Config();
	//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期
	//  DMA配置    1、DMA通道   2、外设地址  3、存储器地址  4、缓冲区大小,应该等于数据目的地的大小
	DMA_Config(ADC_DMA_CHANNEL,(u32)(&( ADC1->DR )),(u32)ADC_CollectValue,NOFCHANEL);
	
}

文章来源:https://blog.csdn.net/RONG_YAO/article/details/135377664
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。