栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

ADC-注入模式

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ADC-注入模式

更多交流欢迎关注作者抖音号:81849645041

目标

        掌握ARM Cortex-M 系列芯片外设ADC注入模式的工作原理,通过配置STM32F407的ADC来分别测出规则通道和注入通道的电压值。

原理

        配置ADC1通道4(PA4)工作在规则通道,配置ADC1通道5(PA5)工作在注入通道,其中通道5的注入模式选择定时器触发,每一秒触发一次,并通过串口打印出测得电压值。通道4选择连续转换并且每500ms打印一次,因此当规则通道打印两次数据的时候,注入通道打印一次数据。

准备

        MDK5 开发环境。

        STM32F4xx HAL库。

        STM32F407 开发板。

        STM32F4xx 参考手册。

        STM32F407 开发板电路原理图。

        串口调试助手软件。

        USB转TTL模块。

步骤

  • 首先创建TIM1_Config()函数,初始化触发定时器和PWM,函数中配置定时器周期为1秒,且PWM的比较值为5000。
    static void TIM1_Config(void)
    {
    	__TIM1_CLK_ENABLE();  // 使能定时器1时钟
    	
    	TIM_HandleTypeDef TIM_Handle; // 定时器初始化结构体变量
    	TIM_OC_InitTypeDef TIM_OC_Handle; // 定时器输出初始化结构体变量	
    	
    	// 定时器初始化
    	TIM_Handle.Channel = HAL_TIM_ACTIVE_CHANNEL_4; // 通道4
    	TIM_Handle.Instance = TIM1; // 选择定时器1
    	TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟1分频
    	TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
    	TIM_Handle.Init.Period = 10000 - 1; // 自动重装载值
    	TIM_Handle.Init.Prescaler = 16800 - 1; // 预分频系数
    	HAL_TIM_PWM_Init(&TIM_Handle); // 初始化定时器
    	
    	// 定时器输出PWM初始化
    	TIM_OC_Handle.OCMode = TIM_OCMODE_PWM1; // 模式选择PWM1
    	TIM_OC_Handle.OCPolarity = TIM_OCPOLARITY_LOW; // 输出比较极性为低
    	TIM_OC_Handle.Pulse = 5000; // 设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
    	HAL_TIM_PWM_ConfigChannel(&TIM_Handle, &TIM_OC_Handle, TIM_CHANNEL_4); // 配置PWM输出
    	
    	HAL_TIM_PWM_Start(&TIM_Handle, TIM_CHANNEL_4); // 开始PWM输出
    }

  • 创建ADC_InjectInit()函数,分别初始化规则通道和注入通道。

            第一步:初始化ADC规则通道4,为连续转换模式且使用软件触发。

            第二步:初始化注入通道5,为定时器1通道4的上升沿触发。

            第三步:调用TIM1_Config()函数,初始化定时器,并开启ADC通道转换。

    // ADC规则/注入通道初始化
    void ADC_InjectInit(void)
    {
    	// 初始化ADC
      	ADC_Handler.Instance = ADC1;
      	ADC_Handler.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8; // 4分频,ADCCLK = PCLK2/4 =84/4=21MHZ
      	ADC_Handler.Init.Resolution = ADC_RESOLUTION_12B; // 12位模式
      	ADC_Handler.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
      	ADC_Handler.Init.ScanConvMode = DISABLE; // 不扫描模式
      	ADC_Handler.Init.EOCSelection = DISABLE; // 开启EOC转换一次中断
      	ADC_Handler.Init.ContinuousConvMode = ENABLE; // 开启连续转换
      	ADC_Handler.Init.NbrOfConversion = 1; // 1个转换在规则序列
      	ADC_Handler.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 使用软件触发
      	ADC_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; // 使用软件触发
      	HAL_ADC_Init(&ADC_Handler); // 初始化 	
    	
    	ADC_ChannelConfTypeDef ADC_ChanneConf; // 规则通道初始化结构体
    	ADC_InjectionConfTypeDef sConfigInjected; // 注入通道初始化结构体
    	
    	// 规则通道初始化
    	ADC_ChanneConf.Channel = ADC_CHANNEL_4; // 通道4
    	ADC_ChanneConf.Rank = 1; // 第一个采样
    	ADC_ChanneConf.SamplingTime = ADC_SAMPLETIME_480CYCLES; // 周期采样时间
    	HAL_ADC_ConfigChannel(&ADC_Handler, &ADC_ChanneConf);	// 初始化规则通道
    	
    	// 注入通道初始化
      	sConfigInjected.InjectedNbrOfConversion = 1; // 注入通道转换个数
      	sConfigInjected.InjectedChannel = ADC_CHANNEL_5; // 通道5
      	sConfigInjected.InjectedRank = 1; // 注入通道执行顺序
      	sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_56CYCLES; // 注入采样周期
    	sConfigInjected.InjectedOffset = 0;
      	sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_RISING; // 使用上升沿触发
      	sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_CC4; // 使用定时器1通道4触发
      	sConfigInjected.AutoInjectedConv = DISABLE; // 不启用常规通道转换1次后注入自动转换
      	sConfigInjected.InjectedDiscontinuousConvMode = DISABLE; // 不启用注入通道连续转换
      	HAL_ADCEx_InjectedConfigChannel(&ADC_Handler, &sConfigInjected);
    
    	TIM1_Config(); // 定时器初始化
    
    	HAL_ADC_Start_IT(&ADC_Handler); // 开启ADC中断
    	
    	HAL_ADCEx_InjectedStart_IT(&ADC_Handler); // 开启注入通道转换中断
    }
    

  • 重定义HAL_ADC_MspInit()函数,初始化ADC底层引脚并使能ADC时钟和中断。
    // ADC底层引脚重定义
    void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
    {
    	GPIO_InitTypeDef GPIO_Initure;
    	
      	__HAL_RCC_ADC1_CLK_ENABLE(); // 使能ADC1时钟
      	__HAL_RCC_GPIOA_CLK_ENABLE(); // 开启GPIOA时钟
    	
      	GPIO_Initure.Pin = GPIO_PIN_4|GPIO_PIN_5; // PA4 PA5
      	GPIO_Initure.Mode = GPIO_MODE_ANALOG; // 模拟
      	GPIO_Initure.Pull = GPIO_NOPULL; // 浮空
      	HAL_GPIO_Init(GPIOA, &GPIO_Initure);
    	
    	HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); // 设置ADC中断优先级
    	HAL_NVIC_EnableIRQ(ADC_IRQn); // 使能ADC	
    }
    

    定义ADC中断服务函数,函数中调用HAL_ADC_IRQHandler()处理中断请求。

    // ADC中断服务函数
    void ADC_IRQHandler()
    {
    	HAL_ADC_IRQHandler(&ADC_Handler);
    }
    

    定义两个存储变量,分别用来存储规则通道和注入通道的值。

    uint16_t uhADCxConvertedRegValue = 0; // 存储规则通道转换值
    uint16_t uhADCxConvertedInjValue = 0; // 存储注入通道转换值
    

  • 定义注入转换完成回调函数,函数中首先获取ADC转换数字值,然后通过获取的数字值计算出电压值,最后通过串口打印电压值。
    // ADC注入通道转换值
    void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
    {
    	float adc_voltage = 0.0f;
      	uhADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(AdcHandle, ADC_INJECTED_RANK_1); // 获取ADC数字值
    	adc_voltage = uhADCxConvertedInjValue * 3.3f / 4095; // 计算电压值
    	printf("Inject adc_voltage: %.2frn", adc_voltage);
    }
    

  • 创建Regula_GetData()函数,用来处理规则通道中数据。同样函数中首先获取ADC转换数字值,然后通过获取的数字值计算出电压值,最后返回计算后的电压值。
    // 规则通道数据计算
    float Regula_GetData(void)
    {
    	float adc_voltage = 0.0f;
      	uhADCxConvertedRegValue = HAL_ADC_GetValue(&ADC_Handler); // 获取ADC数字值
    	adc_voltage = uhADCxConvertedRegValue * 3.3f / 4095; // 计算电压值
    	return adc_voltage;
    }
    

  • 主函数main程序如下:

            第一步:初始化系统时钟和串口。

            第二步:调用ADC_InjectInit()函数初始化ADC两个通道。

            第三步:在while()循环中获取规则通道转换电压值,使用printf将电压值通过串口每隔500ms打印出来。

    int main()
    {
    	CLOCK_Init(); // 时钟初始化
    	UART_Init(); // 串口初始化
    
    	ADC_InjectInit(); // 注入模式初始化
    	
    	while(1)
    	{
    		printf("Regulation adc_voltage: %.2frn", Regula_GetData());
    		HAL_Delay(500);
    	}
    }
    
    现象

            将程序下载到开发板中,可以看到注入通道数据每隔1秒钟打印一次,规则通道500ms打印一次,当规则通道打印两次数据的时候,注入通道打印一次数据。(此时规则通道4连接的3.3v引脚,注入通道5连接的GND引脚)。

  • 转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/744551.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号