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

三十三、CH32V103应用教程——ADC-模拟看门狗

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

CH32V103应用教程——ADC-模拟看门狗

本章主要在第十章ADC和第三十一章ADC-单通道中断读取方式的基础上进行ADC模拟看门狗实验。

1、ADC简介及相关函数介绍
关于ADC模拟看门狗:如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。阀值设置位于ADC_WDHTR和 ADC_WDLTR寄存器的最低12个有效位中。通过设置ADC_CTLR1寄存器的 AWDIE位以允许产生相应中断。
模拟看门狗阈值区:
配置ADC_CTLR1寄存器的AWDSGL、RAWDEN、IAWDEN及AWDCH[4:0]位选择模拟看门狗警戒的通道,具体关系见下表:
模拟看门狗通道选择:
关于ADC具体信息,可参考CH32V103应用手册。关于ADC库函数,在第十章节已进行过介绍,在此不再赘述。

2、硬件设计
本章教程通过读取ADC1通道1的值,当ADC值超过模拟看门狗阈值区,则产生相应中断。

3软件设计
本章主要进行ADC模拟看门狗实验,本章教程在第十章ADC和第三十一章ADC-单通道中断读取方式基础上进行,相关内容可参考前面章节。ADC模拟看门狗应用程序具体如下:
adc.h文件
#ifndef __ADC_H
#define __ADC_H

#include "ch32v10x_conf.h"

void ADC_Function_Init(void);
u16 Get_ADC_Val(u8 ch);
void ADC1_2_IRQHandler(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_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

/* Higher Threshold:3500, Lower Threshold:2000 */
    ADC_AnalogWatchdogThresholdsConfig(ADC1, 3500, 2000);
    ADC_AnalogWatchdogSingleChannelConfig( ADC1, ADC_Channel_1);
    ADC_AnalogWatchdogCmd( ADC1, ADC_AnalogWatchdog_SingleRegEnable);

    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_AWD, ENABLE);
    ADC_Cmd(ADC1, ENABLE);

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

/*******************************************************************************
* Function Name  : Get_ADC_Val
* Description    : Returns ADCx conversion result data.
* Input          : ch: ADC channel.
*                    ADC_Channel_0: ADC Channel0 selected.
*                    ADC_Channel_1: ADC Channel1 selected.
*                    ADC_Channel_2: ADC Channel2 selected.
*                    ADC_Channel_3: ADC Channel3 selected.
*                    ADC_Channel_4: ADC Channel4 selected.
*                    ADC_Channel_5: ADC Channel5 selected.
*                    ADC_Channel_6: ADC Channel6 selected.
*                    ADC_Channel_7: ADC Channel7 selected.
*                    ADC_Channel_8: ADC Channel8 selected.
*                    ADC_Channel_9: ADC Channel9 selected.
*                    ADC_Channel_10: ADC Channel10 selected.
*                    ADC_Channel_11: ADC Channel11 selected.
*                    ADC_Channel_12: ADC Channel12 selected.
*                    ADC_Channel_13: ADC Channel13 selected.
*                    ADC_Channel_14: ADC Channel14 selected.
*                    ADC_Channel_15: ADC Channel15 selected.
*                    ADC_Channel_16: ADC Channel16 selected.
*                    ADC_Channel_17: ADC Channel17 selected.
* Return         : val: The Data conversion value.
*******************************************************************************/
u16 Get_ADC_Val(u8 ch)
{
    u16 val;

    ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));

    val = ADC_GetConversionValue(ADC1);

    return val;
}


/*******************************************************************************
* Function Name  : ADC1_2_IRQHandler
* Description    : This function handles analog wathdog exception.
* Input          : None
* Return         : None
*******************************************************************************/
void ADC1_2_IRQHandler(void)
{
    if(ADC_GetITStatus( ADC1, ADC_IT_AWD))
    {
        printf( "Enter AnalogWatchdog Interrupt\r\n" );
    }

    ADC_ClearITPendingBit( ADC1, ADC_IT_AWD);
}
adc.c文件主要进行ADC模拟看门狗初始化配置,在第十章ADC初始化基础上,主要进行如下改动:
因为本次为ADC模拟看门狗,因此需要对模拟看门狗的高低阈值进行配置;此外,还需对ADC模拟看门狗所用单通道进行配置;最后使能单通道模拟看门狗,具体程序如下:
/* Higher Threshold:3500, Lower Threshold:2000 */
    ADC_AnalogWatchdogThresholdsConfig(ADC1, 3500, 2000);
    ADC_AnalogWatchdogSingleChannelConfig( ADC1, ADC_Channel_1);
    ADC_AnalogWatchdogCmd( ADC1, ADC_AnalogWatchdog_SingleRegEnable);
因为需要用到中断,因此需要对NVIC进行初始化配置;
    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_AWD, ENABLE);
关于中断服务函数,当ADC值不在模拟看门狗阈值范围内时,就会进入中断,关于中断服务函数,具体如下:
void ADC1_2_IRQHandler(void)
{
    if(ADC_GetITStatus( ADC1, ADC_IT_AWD))
    {
        printf( "Enter AnalogWatchdog Interrupt\r\n" );
    }

    ADC_ClearITPendingBit( ADC1, ADC_IT_AWD);
}
main.c文件
int main(void)
{
    u16 ADC_val;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        Delay_Init();
        USART_Printf_Init(115200);
        ADC_Function_Init();
        printf("SystemClk:%d\r\n",SystemCoreClock);
        printf("This is ADC example\r\n");

        while(1)
        {
            ADC_val = Get_ADC_Val( ADC_Channel_1);
            Delay_Ms(500);
            printf( "%d\r\n", ADC_val );
            Delay_Ms(2);
        }
}
main.c文件主要进行函数初始化以及ADC值打印输出。

4下载验证
将编译好的程序下载到开发板并复位,当PA1引脚接3.3V或GND时,不在阈值范围内,串口显示如下:



32、ADC-模拟看门狗.rar

488.39 KB

使用特权

评论回复

相关帖子

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

本版积分规则

132

主题

293

帖子

41

粉丝