打印
[RISC-V MCU 应用开发]

三十二、CH32V103应用教程——ADC-外部触发转换

[复制链接]
1471|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
RISCVLAR|  楼主 | 2020-12-23 18:51 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 RISCVLAR 于 2020-12-23 20:35 编辑

CH32V103应用教程——ADC-外部触发转换

本章主要在上一章ADC-单通道中断读取方式的基础上进行ADC外部触发转换,本章主要进行规则组的外部触发转换,并在中断服务函数中读取ADC值。

1、ADC简介及相关函数介绍
ADC转换的启动事件可以由外部事件触发。如果设置了ADC_CTLR2寄存器(ADC控制寄存器2)的REXTTRI或IEXTTRIG位,则可分别通过外部事件触发规则组或注入组通道的转换。此时,REXTSEL[2:0]和IEXTSEL[2:0]位的配置决定规则组和注入组的外部事件源,具体如下:
规则通道组的外部触发源:
注入通道组的外部触发源:
本章通过EXTI线11触发规则通道组AD转换。
关于ADC具体信息,可参考CH32V103应用手册。关于ADC库函数,在第十章节已进行过介绍,在此不再赘述。

2、硬件设计
本章教程通过PA11(EXTI线11)连接GND引脚触发规则通道组AD转换,此时可通过ADC1通道1读取开发板3.3V引脚或GND引脚ADC值,并通过串口调试助手打印显示出来。其中ADC1通道1对应PA1引脚,在进行使用测试时只需用杜邦线将PA1引脚与3.3V 引脚和GND引脚连接即可。

3软件设计
本章主要进行ADC规则通道组的外部触发转换,本章教程在ADC单通道中断读取方式基础上进行,关于ADC和中断基本介绍以及应用,可参考前面相关章节。ADC外部触发转换方式应用程序具体如下:
adc.h文件
#ifndef __ADC_H
#define __ADC_H

#include "ch32v10x_conf.h"

void ADC_Function_Init(void);
void EXTI_Event_Init(void);

#endif
adc.h文件主要进行函数的声明;
adc.c文件
#include "adc.h"

void ADC1_2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

/*******************************************************************************
* Function Name  : ADC_Function_Init
* Description    : Initializes ADC collection.
* Input          : None
* Return         : None
*******************************************************************************/
void ADC_Function_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef  ADC_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);

    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO; //启用外部触发,此处由EXTI线11触发
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);


    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);

    ADC_ExternalTrigConvCmd(ADC1, ENABLE); //使能通过外部触发器启用ADC转换

    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    ADC_ITConfig( ADC1, ADC_IT_EOC, ENABLE);
    ADC_Cmd(ADC1, ENABLE);

    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
}

/*******************************************************************************
* Function Name  : EXTI_Event_Init
* Description    : Initializes EXTI.
* Input          : None
* Return         : None
*******************************************************************************/
void EXTI_Event_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE );

    GPIO_EXTILineConfig( GPIO_PortSourceGPIOA, GPIO_PinSource11 );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入模式
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    EXTI_InitStructure.EXTI_Line = EXTI_Line11;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

/*******************************************************************************
* Function Name  : ADC1_2_IRQHandler
* Description    : This function handles analog watchdog exception.
* Input          : None
* Return         : None
*******************************************************************************/
void ADC1_2_IRQHandler()
{
    u16 ADC_val;

    if(ADC_GetITStatus( ADC1, ADC_IT_EOC)==SET)
    {
        printf("ADC Extline trigger conversion...\r\n");
        ADC_val = ADC_GetConversionValue(ADC1);
        printf( "ADC=%d\r\n", ADC_val );
    }

    ADC_ClearITPendingBit( ADC1, ADC_IT_EOC);
}
adc.c文件主要进行ADC对应GPIO初始化配置、ADC初始化配置、NVIC初始化配置以及EXTI初始化配置,其相较于上一章ADC单通道中断读取方式,主要进行以下修改:
在ADC初始化配置中,启用外部触发,此处由EXTI线11触发规则通道组AD转换,具体如下:
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO; //启用外部触发,此处由EXTI线11触发
由于启用外部触发,ADC初始化配置中需使能通过外部触发器启用ADC转换,具体如下:
 ADC_ExternalTrigConvCmd(ADC1, ENABLE); //使能通过外部触发器启用ADC转换
关于EXTI初始化配置,可参考第四章教程EXTI,在此不再赘述;
关于ADC中断服务函数,当ADC转换结束完成,读取当前ADC值,并打印显示,具体如下:
void ADC1_2_IRQHandler()
{
    u16 ADC_val;

    if(ADC_GetITStatus( ADC1, ADC_IT_EOC)==SET)
    {
        printf("ADC Extline trigger conversion...\r\n");
        ADC_val = ADC_GetConversionValue(ADC1);
        printf( "ADC=%d\r\n", ADC_val );
    }

    ADC_ClearITPendingBit( ADC1, ADC_IT_EOC);
}
main.c文件
int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n",SystemCoreClock);

        printf("This is ADC example\r\n");

    ADC_Function_Init();
    EXTI_Event_Init();

        while(1)
        {
        }
}
mian.c文件主要进行函数初始化。

4下载验证
将编译好的程序下载到开发板并复位,串口显示如下:
将PA1与开发板3.3V引脚连接起来,同时将PA11与GND引脚连接起来(下降沿触发),串口显示如下:
将PA1与开发板GND引脚连接起来,串口显示如下:
因为此处配置ADC连续转换模式,因此只需要触发一次,ADC即可进行不停转换;当配置ADC非连续转换模式时,触发一次即进行一次转换。


31、ADC-外部触发.rar

483.95 KB

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

132

主题

293

帖子

41

粉丝