0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MM32F3270 ADC注入通道

jf_pJlTbmA9 来源:灵动MM32MCU 作者:灵动MM32MCU 2023-09-27 15:59 次阅读

MM32F3270系列的ADC支持注入通道功能,每个ADC模块具有4个注入通道。每个注入通道具有独立的数据寄存器,注入通道具有比规则通道更高的优先级。

规则通道是按照指定的通道顺序进行转换。注入通道是指在规则通道转换过程中,如果突然需要进行其他某个通道的采样,则会在规则通道该次转换完成后停止转换,进行注入通道转换直到转换结束,再继续规则通道转换。

在一些特定场合使用ADC时可能会遇到很多情况,不仅仅简单的按规则通道来采样,有时候需要立刻采样,这就要用到注入通道。

注入通道模式介绍

注入通道工作模式分为自动注入和事件注入两种模式:

a) 自动注入:任意通道工作完成后自动开始注入通道工作;

b) 事件注入:注入事件到来, A/D转换完成当前转换后开始注入通道转换,完成注入通道转换后继续执行任意通道转换。

自动注入转换模式

任意通道配置通道转换完成后,自动开始注入通道转换。如果任意通道是连续扫描模式,需要清除ADST才能停止转换。配置自动注入转换模式应禁止注入事件发生。

wKgaomUD8aKAci4CAAGUYc_uk7U265.png 自动注入模式-通道转换时序图

事件注入工作模式

注入事件下禁止自动注入模式。注入事件发生后(包括软件和触发),如果当前转换正在进行,则完成当前转换后开始注入通道转换。

wKgZomUD8aSAbSGJAAG2PrjJ6LA216.png 任意通道转换时注入事件转换通道时序图

在注入通道转换期间有任意通道事件产生,注入转换不会结束,但会保存任意通道事件。完成本次转换序列后,开始任意通道事件的转换。

wKgaomUD8aaATYywAAHCv7VworI950.png 注入通道转换时任意事件转换通道发生时序图

使用触发开始注入通道转换,必须保证触发事件的间隔长与注入序列,注入通道转换期间发生注入事件将被忽略。

触发信号

ADC转换的触发源包括软件触发、定时器和外部事件。

在触发信号产生后,延时N个PCLK2的时钟周期再开始采样。如果是触发扫描模式,只有第一个通道采样被延时,其余通道是在上一个采样结束后立即开始。

设置ADC_ANY_CR寄存器的JTRGEN位可以使用外部事件触发注入通道转换。设置ADC_ANY_CR寄存器的JTRGSEL位可以选择注入通道外部触发源。

具体的外部触发源选择情况,可以参考AD控制寄存器(ADC_ADCR.TRGSEL 或ADC_ANY_CR.JTRGSEL)相关位的描述。外部触发可设置延时控制,具体参考AD控制寄存器(ADC_ADCR.TRGSHIFT 或 ADC_ANY_CR.J TRGSHIFT)相关位的描述。

实验

本次实验使用ADC的注入通道:将ADC1的通道0配置为规则通道模式,通过软件触发,并使用DMA传输数据。将ADC1的通道1配置为注入通道模式,通过外部事件触发,并使用中断,在中断服务子程序中,就可以获取AD值。

开始只有ADC1的通道0进行AD转换,通道1不进行AD转换。当外部事件发生后,通道0当前转换结束后停止,通道1开始进行转换直至结束,通道0继续进行AD转换,经MCU处理将电压数据打印出来。

程序设计

ADC1 配置初始化

void ADC1BasicConfigWithParameter(void)
{
    ADC_InitTypeDef  ADC_InitStruct;
    ADC_TypeDef* ADCn;
    ADCn = ADC1;
    ADC_StructInit( ADC_InitStruct);

    ADCxClockSet(ADCn, ENABLE);        
    ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16;
    ADC_InitStruct.ADC_Mode = ADC_Mode_Continue;
    ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

    ADC_Init(ADCn,  ADC_InitStruct);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 0, ADC_SMPR1_SAMCTL0_240_5);   

    ADC_InjectedSequencerConfig(ADC1, ADC_ANY_CR_JTRGSEL_EXTI12, ADC_ANY_CR_JTRGSHIFT_64);
    ADC_InjectedSequencerLengthConfig(ADC1, ADC_Inject_Seqen_Len1);    
    ADC_InjectedSequencerChannelConfig(ADC1, ADC_InjectedChannel_1, ADC_Channel_1);  

    ADC1->ANYCR |= (1<<4);
    DMAInit();
    ADC_DMACmd(ADCn, ENABLE);
    ADC_Cmd(ADCn, ENABLE);   
}

外部事件初始化

ADC触发源选择外部事件触发方式,配置EXTI_Line12下降沿触发外部中断,通过PB12复用为外部中断/事件线。

void EXTIX_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG, ENABLE);

    //Set to pull-up input
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);
    GPIO_StructInit( GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
    GPIO_Init(GPIOB,  GPIO_InitStructure);

    //GPIOB.12
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);
    EXTI_StructInit( EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_Line12;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
    //Falling edge trigger
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init( EXTI_InitStructure);
}

ADC1中断服务函数

外部事件触发ADC注入通道采样,转换完成便会触发ADC中断,在中断服务子程序中获取AD值。

void ADC1_2_IRQHandler(void)
{
    if(RESET != ADC_SREXT_JEOSIF) 
    {
        ADC1->SREXT |= (1 << 20);   //Clear the bit by writing about 1 
        ADCVAL = ADC_GetInjectedCurrentConvertedValue(ADC1);
        Flag_InjectConvert = 1;
        if(RESET != EXTI_GetFlagStatus(EXTI_Line12))  {
            EXTI_ClearITPendingBit(EXTI_Line12);
        }
    }
}

DMA中断服务函数

规则通道使用DMA中断进行数据传输,在DMA中断服务函数中调用ADCFilter()函数对获取的AD值做滤波处理。

void DMA1_Channel1_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC1))  {
        DMA_ClearITPendingBit(DMA1_IT_TC1);
        ADCFilter();
    }
}

主函数

示例中将获取的AD值与3.3V比对,转换为ADC输入通道的电压,并间隔300ms打印。

s32 main(void)
{
    DELAY_Init();
    CONSOLE_Init(115200);
    ADC1_ConfigInit();
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(1) 
    {
        if(Flag_InjectConvert)
        {
            Flag_InjectConvert = 0;
            fValue = ((float)ADCVAL / 4095) * 3.3; 
            // ADC injection channel
            printf("ADC1_CH_1 = %fVrnn", fValue);
        }   
        if(Flag_ADCFilter) 
        {
            Flag_ADCFilter = 0;
            //Convert the filtered value to voltage  
            ADCVolatge = ((float)ADCFilterValue / 4095) * 3.3;
            //ADC regular channels
            printf("ADC1_CH_0 = %fVrnn", ADCVolatge);
            ADC_SoftwareStartConvCmd(ADC1, ENABLE); 
        }
        DELAY_Ms(300);
    }
}

演示

在开发板上将PA0(ADC1通道0)连接板上GND,将PA1(ADC1通道1)连接板上3.3V。

运行程序,开始时只有ADC1通道0(规则通道)进行AD转换。给PB12一个下降沿信号,此时外部事件触发ADC1通道1(注入通道)进行AD转换,通道0当前转换完成后停止AD转换,通道1进行转换直到结束,通道0进行AD转换。串口调试助手显示如下:

wKgZomUD8aiAf9F9AAE0ko-aJq4383.png

各通道输出数据和采样电压一致,与预期相符。在一些ADC应用场合中,通常将注入通道和规则通道混合使用,在规则通道转换的过程中立刻进行注入通道采样,充分发挥ADC外设的特性。

来源:灵动MM32MCU

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17123

    浏览量

    350986
  • adc
    adc
    +关注

    关注

    98

    文章

    6495

    浏览量

    544466
  • 时序图
    +关注

    关注

    2

    文章

    58

    浏览量

    22443
收藏 人收藏

    评论

    相关推荐

    MM32F3270系列32位MCU的特点有哪些

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 11-03 07:20

    灵动微课堂 (第195讲) | MM32F3270 ADC注入通道

    MM32F3270系列的ADC支持注入通道功能,每个ADC模块具有4个注入
    发表于 01-10 11:35

    灵动微电子MM32F3270系列MCU的特点介绍

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 03-22 16:57 2156次阅读

    【国产MCU移植】MM32F3270 EVBoard

    【国产MCU移植】MM32F3270 EVBoard
    发表于 12-03 17:21 5次下载
    【国产MCU移植】<b class='flag-5'>MM32F3270</b> EVBoard

    基于MM32F3270 以太网 Client使用

    接下来给大家介绍基于TCP包的通讯。内容分为基于MM32F3270以太网Client的使用与基于MM32F3270以太网Server的使用。
    发表于 02-08 15:10 0次下载
    基于<b class='flag-5'>MM32F3270</b> 以太网 Client使用

    MM32F3270 产品手册(中文版)

    MM32F3270 产品手册(中文版)
    发表于 02-23 18:40 0次下载
    <b class='flag-5'>MM32F3270</b> 产品手册(中文版)

    MM32F3270 勘误表(中文版)

    MM32F3270 勘误表(中文版)
    发表于 02-23 18:42 0次下载
    <b class='flag-5'>MM32F3270</b> 勘误表(中文版)

    MM32F3270 勘误表(英文版)

    MM32F3270 勘误表(英文版)
    发表于 02-23 18:43 0次下载
    <b class='flag-5'>MM32F3270</b> 勘误表(英文版)

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植
    的头像 发表于 10-27 10:15 757次阅读
    使用<b class='flag-5'>MM32F3270</b>基于Azure RTOS (ThreadX) 的移植

    基于MM32F3270 I2S使用

    基于MM32F3270 I2S使用
    的头像 发表于 09-27 15:50 797次阅读
    基于<b class='flag-5'>MM32F3270</b> I2S使用

    使用MM32F3270 FSMC驱动OLED

    使用MM32F3270 FSMC驱动OLED
    的头像 发表于 09-27 15:30 942次阅读
    使用<b class='flag-5'>MM32F3270</b> FSMC驱动OLED

    使用MM32F3270 FSMC驱动TFT-LCD

    使用MM32F3270 FSMC驱动TFT-LCD
    的头像 发表于 09-27 15:34 1008次阅读
    使用<b class='flag-5'>MM32F3270</b> FSMC驱动TFT-LCD

    基于MM32F3270以太网Client使用

    基于MM32F3270以太网Client使用
    的头像 发表于 09-27 15:44 695次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网Client使用

    基于MM32F3270以太网UDP使用

    基于MM32F3270以太网 UDP使用
    的头像 发表于 09-27 15:42 495次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网UDP使用

    基于MM32F3270以太网Client_Socket使用

    基于MM32F3270以太网Client_Socket使用
    的头像 发表于 09-27 15:37 538次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网Client_Socket使用