4.N32G452_ADC

简述

N32G452的12位ADC使用的是逐次逼近的高速模数转换器。他有多个通道,每个通道的A/D转换有四种执行模式:

  • 单次
  • 连续
  • 扫描
  • 间断
    ADC转换值储存(左对齐/右对齐)在16位数据寄存器中。可以通过模拟看门狗检测输入电压是否在用户定义的高/低阈值内,并且ADC的输入时钟的最大频率为72MHZ。

在这里插入图片描述
在这里插入图片描述
ADC框图

在这里插入图片描述
ADC引脚

在这里插入图片描述
ADC时钟

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ADC转换的四种模式:

  • 单次转换模式:在该模式下,外部触发或者ADC_CTRL2.ON=1(仅适用于规则通道)启动ADC转化,ADC只进行一次转换,转换完成后ADC停止。
void ADC_Initl()
{
	/*打开ADC1引脚时钟*/
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
	/*打开ADC1总线时钟*/
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1 ,ENABLE);
    /*将ADCHCLK配置为DIV16*/
    ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV16);
    /*设置ADC1M时钟来源为HSE*/
    RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8); 
    /*初始化ADC引脚*/
    GPIO_InitType GPIO_InitStructure;
     /* PC0 PC1  -------------------------*/
    GPIO_InitStructure.Pin       = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitPeripheral(GPIOC, &GPIO_InitStructure);
    /* ADC初始化 -----------------------*/
    ADC_InitType ADC_InitStructure;	
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;//独立输入模式
    ADC_InitStructure.MultiChEn      = DISABLE;//多通道禁用
    ADC_InitStructure.ContinueConvEn = DISABLE;//连续转化禁用
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_NONE;//外部触发选择
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;//数据右对齐
    ADC_InitStructure.ChsNumber      = 1;//通道数
    ADC_Init(ADCx, &ADC_InitStructure);	
    
    /* 使能 ADC */
    ADC_Enable(ADCx, ENABLE);
    while(ADC_GetFlagStatusNew(ADCx,ADC_FLAG_RDY) == RESET);
    /* ADC校准 */
    ADC_StartCalibration(ADCx);
    while (ADC_GetCalibrationStatus(ADCx));
}

uint16_t ADC_GetData(ADC_Module* ADCx, uint8_t ADC_Channel)
{
    uint16_t dat;
    
    ADC_ConfigRegularChannel(ADCx, ADC_Channel, 1,ADC_SAMP_TIME_239CYCLES5);
    /* Start ADC Software Conversion */
    ADC_EnableSoftwareStartConv(ADCx, ENABLE);
    while(ADC_GetFlagStatus(ADCx, ADC_FLAG_ENDC)==0){
    }
    ADC_ClearFlag(ADCx, ADC_FLAG_ENDC);
    ADC_ClearFlag(ADCx, ADC_FLAG_STR);
    dat=ADC_GetDat(ADCx);
    return dat;
}
  • 连续转换模式:ADC 可以通过配置 ADC_CTRL2.CTU 为 1 进入连续转换模式。在该模式下,外部触发或设置ADC_CTRL2.ON 为 1 可以启动 ADC 开始转换,ADC 会持续转换选择的通道。连续模式仅对规则通道有
    效,对注入通道无效。
UINT16 	adc_value;
void ADC_Initl()
{
	 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);//使能DMA时钟
	 /* DMA1 通道配置 ----------------------------------------------*/
	DMA_InitType DMA_InitStructure;
    DMA_DeInit(DMA1_CH1);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;//外设地址
    DMA_InitStructure.MemAddr        = (uint32_t)&adc_value;//内存地址
    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总线时钟*/
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1 ,ENABLE);
    /*将ADCHCLK配置为DIV16*/
    ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV16);
    /*设置ADC1M时钟来源为HSE*/
    RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8); 
		
		
    /* ADC初始化 -----------------------*/
    ADC_InitType ADC_InitStructure;	
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;//独立输入模式
    ADC_InitStructure.MultiChEn      = DISABLE;//多通道禁用
    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);	
    /*配置ADC1通道*/
	ADC_ConfigRegularChannel(ADC1, ADC1_Channel_01_PA0, 1, ADC_SAMP_TIME_55CYCLES5);
	/*使能DMA*/
	ADC_EnableDMA(ADC1, ENABLE);
		
    /* 使能 ADC */
    ADC_Enable(ADC1, ENABLE);
    while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET);
    /* ADC校准 */
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1));
	/*开启连续转化*/	
	ADC_EnableSoftwareStartConv(ADC1, ENABLE);	
}
  • 扫描模式:通过配置 ADC_CTRL1.SCAMD 为 1 可以开启扫描转换模式,通过配置四个寄存器 ADC_RSEQ1、ADC_RSEQ2、ADC_RSEQ3、ADC_JSEQ 可以选择转换通道序列,ADC 会对所有选择的规则或注入通道进行扫描转换。转换开始后,通道将一个一个转换。如果此时 ADC_CTRL2.CTU 为 1,则在所有选中的规则
    通道的转换完成后,将从转换序列的第一个通道重新开始转换。
void ADC_Initl()
{
	RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);
	 /* DMA1 channel1 configuration ----------------------------------------------*/
	DMA_InitType DMA_InitStructure;
    DMA_DeInit(DMA1_CH1);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)&adc_value;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 2;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    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总线时钟*/
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1 ,ENABLE);
    /*将ADCHCLK配置为DIV16*/
    ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV16);
    /*设置ADC1M时钟来源为HSE*/
    RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8); 
		
		
    /* ADC初始化 -----------------------*/
    ADC_InitType ADC_InitStructure;	
    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      = 2;//通道数
    ADC_Init(ADC1, &ADC_InitStructure);	
    
	ADC_ConfigRegularChannel(ADC1, ADC1_Channel_01_PA0, 1, ADC_SAMP_TIME_55CYCLES5);
	ADC_ConfigRegularChannel(ADC1, ADC1_Channel_02_PA1, 2, ADC_SAMP_TIME_55CYCLES5);
	ADC_EnableDMA(ADC1, ENABLE);
		
    /* 使能 ADC */
    ADC_Enable(ADC1, ENABLE);
    while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET);
    /* ADC校准 */
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1));
		
	ADC_EnableSoftwareStartConv(ADC1, ENABLE);
		
}

  • 间断模式:
在这里插入代码片
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是N32G032K8L7ADC连续转换的示例代码: ```c #include "n32g032.h" #define ADC_CHANNEL_NUM 3 uint16_t ADC_ConvertedValue[ADC_CHANNEL_NUM]; void ADC_ContinousConversion(void) { ADC_InitTypeDef ADC_InitStruct = {0}; ADC_ChannelConfTypeDef sConfig = {0}; // 使能ADC时钟 __HAL_RCC_ADC1_CLK_ENABLE(); // 配置ADC参数 ADC_InitStruct.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; ADC_InitStruct.Resolution = ADC_RESOLUTION_12B; ADC_InitStruct.DataAlign = ADC_DATAALIGN_RIGHT; ADC_InitStruct.ContinuousConvMode = ENABLE; ADC_InitStruct.DiscontinuousConvMode = DISABLE; ADC_InitStruct.ExternalTrigConv = ADC_SOFTWARE_START; ADC_InitStruct.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; ADC_InitStruct.DMAContinuousRequests = DISABLE; ADC_InitStruct.EOCSelection = ADC_EOC_SINGLE_CONV; HAL_ADC_Init(&hadc1, &ADC_InitStruct); // 配置ADC通道 sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = ADC_REGULAR_RANK_2; HAL_ADC_ConfigChannel(&hadc1, &sConfig); sConfig.Channel = ADC_CHANNEL_6; sConfig.Rank = ADC_REGULAR_RANK_3; HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 启动ADC连续转换 HAL_ADC_Start(&hadc1); while (1) { // 等待转换完成 if (HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK) { // 获取ADC转换结果 for (int i = 0; i < ADC_CHANNEL_NUM; i++) { ADC_ConvertedValue[i] = HAL_ADC_GetValue(&hadc1); } } } } ``` 在这个示例中,我们使用了3个ADC通道(ADC_CHANNEL_4, ADC_CHANNEL_5和ADC_CHANNEL_6)进行连续转换。在程序的主循环中,我们等待转换完成并获取转换结果,然后将结果存储在ADC_ConvertedValue数组中。可以根据需要修改ADC通道的数量和其他参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值