816|0

205

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【小华工控新品HC32F448】03.体验AOS自动运行系统的智能 [复制链接]

 

1.概述

小华HC32F488系列芯片具备了AOS自动运行系统这个外设功能,啥是AOS自动运行系统呢?难道HC32F488芯片内自带了一个能够自动运行的系统?这个系统并非我们理解上的通过代码实现的类RTOS之类的系统,根据UM手册的定义,自动运行系统(Automatic Operation System)用于在不借助CPU的情况下实现外设之间的联动。由此我想到了DMA,在配置DMA之后,使能DMA就不需要CPU的干预了,可以自动完成DMA配置的任务;其实AOS还真和DMA有相似之处,即在配置AOS功能之后,在不需要CPU干预的情况下,就可以完成我们设定的功能;更直观的说,它就是一个触发,通过触发源来执行触发的任务。在UM手册中也介绍了,利用外设产生的事件作为AOS源(比如定时器的比较匹配、定时器的计数溢出、RTC的周期信号、通信模块的收发数据的各种状态、ADC的转换结束等事件),来触发其它的外设动作。

 

2.例程

2.1.我们来实现一个通过定时器以固定周期去触发ADC转换功能的示例程序

---在没有使用AOS功能时,我们的实现应该是配置ADC,使能ADC转换完成中断、配置定时器,使能定时器中断、最后使能ADC和定时器,在定时器达到固定周期后,就会触发定时器中断,我们在中断函数中使能ADC转换,等待ADC转换完成后,我们最后进入ADC转换完成中断,以此周而复始。

---当我们使用AOS功能时,我们的实现却变成了:配置ADC,使能ADC转换完成中断,配置定时器、配置AOS,触发源是定时器,触发目标是开始ADC转换,最后使能定时器就完成了;在定时器触发条件达到时,就会自动开始ADC转换,等ADC转换完成后,就进入到ADC转换完成中断了,以些周而复始。

由此可以看出,AOS的使用节省了MCU在代码和处理时间上的开销,更稳定更可靠,更智能!

 

2.2.配置程序

/* ADC unit instance for this example. */
#define ADC_UNIT                        (CM_ADC1)
#define ADC_PERIPH_CLK                  (FCG3_PERIPH_ADC1)

/* Selects ADC channels that needed. */
#define ADC_SEQB_CH                     (ADC_CH10)
#define ADC_SEQB_CH_PORT                (GPIO_PORT_C)
#define ADC_SEQB_CH_PIN                 (GPIO_PIN_00)

#define ADC_SEQB_HARDTRIG               (ADC_HARDTRIG_EVT0)
#define ADC_SEQB_AOS_TRIG_SEL           (AOS_ADC1_0)
#define ADC_SEQB_TRIG_EVT               (EVT_SRC_TMR0_1_CMP_B)

/* Timer0 for sequence B */
#define TMR0_UNIT                       (CM_TMR0_1)
#define TMR0_CH                         (TMR0_CH_B)
#define TMR0_PERIPH_CLK                 (FCG2_PERIPH_TMR0_1)
#define TMR0_CMP_VAL                    (31250UL - 1UL)
#define TMR0_CLK_DIV                    (TMR0_CLK_DIV256)
#define TMR0_PERIPH_ENABLE()            FCG_Fcg2PeriphClockCmd(TMR0_PERIPH_CLK, ENABLE)

/* Interrupt */
#define ADC_SEQB_INT_PRIO               (DDL_IRQ_PRIO_03)
#define ADC_SEQB_INT_SRC                (INT_SRC_ADC1_EOCB)
#define ADC_SEQB_INT_IRQn               (INT015_IRQn)

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] Set specified ADC pin to analog mode.
  * @param  None
  * @retval None
  */
static void ADC_InitGPIO(void)
{
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(ADC_SEQB_CH_PORT, ADC_SEQB_CH_PIN, &stcGpioInit);
}

/**
 * @brief  ADC sequence B interrupt callback.
 * @param  None
 * @retval None
 */
static void ADC1_SEQB_IRQCallback(void)
{
    uint16_t u16AdcVal;
    u16AdcVal = ADC_GetValue(ADC_UNIT, ADC_SEQB_CH);
    ADC_ClearStatus(ADC_UNIT, ADC_FLAG_EOCB);

    DDL_Printf("ADC sequence B was triggered by TMR0 event.\r\n");
    DDL_Printf("ADC value of sequence B channel: %u\r\n", u16AdcVal);
}

/**
  * @brief  Initializes ADC.
  * @param  None
  * @retval None
  */
static void ADC_Configuration(void)
{
    stc_adc_init_t          stcAdcInit;
    stc_tmr0_init_t         stcTmr0Init;
    stc_irq_signin_config_t stcIrq;

    /* 1. Enable ADC peripheral clock. */
    FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
    /* 2. Modify the default value depends on the application. */
    (void)ADC_StructInit(&stcAdcInit);
    stcAdcInit.u16ScanMode = ADC_MD_SEQA_SEQB_SINGLESHOT;
    /* 3. Initializes ADC. */
    (void)ADC_Init(ADC_UNIT, &stcAdcInit);
    /* 4. ADC channel configuration. */
    /* 4.1 Set the ADC pin to analog input mode. */
    ADC_InitGPIO();
    /* 4.2 Enable ADC channels. */
    ADC_ChCmd(ADC_UNIT, ADC_SEQ_B, ADC_SEQB_CH, ENABLE);

    /************** Hard trigger of sequence B ****************/
    TMR0_PERIPH_ENABLE();
    /* Initials TIMER0. */
    (void)TMR0_StructInit(&stcTmr0Init);
    stcTmr0Init.u32ClockDiv     = TMR0_CLK_DIV;
    stcTmr0Init.u16CompareValue = (uint16_t)TMR0_CMP_VAL;
    (void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);

    /* Specifies the event defined by 'ADC_SEQB_TRIG_EVT' as the hard trigger of sequence B. */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    ADC_TriggerConfig(ADC_UNIT, ADC_SEQ_B, ADC_SEQB_HARDTRIG);
    AOS_SetTriggerEventSrc(ADC_SEQB_AOS_TRIG_SEL, ADC_SEQB_TRIG_EVT);
    ADC_TriggerCmd(ADC_UNIT, ADC_SEQ_B, ENABLE);

    stcIrq.enIntSrc    = ADC_SEQB_INT_SRC;
    stcIrq.enIRQn      = ADC_SEQB_INT_IRQn;
    stcIrq.pfnCallback = &ADC1_SEQB_IRQCallback;
    (void)INTC_IrqSignIn(&stcIrq);
    NVIC_ClearPendingIRQ(stcIrq.enIRQn);
    NVIC_SetPriority(stcIrq.enIRQn, ADC_SEQB_INT_PRIO);
    NVIC_EnableIRQ(stcIrq.enIRQn);
    ADC_IntCmd(ADC_UNIT, ADC_INT_EOCB, ENABLE);
}

/**
  * @brief  Main function of template project
  * @param  None
  * @retval int32_t return value, if needed
  */
int32_t main(void)
{
    /* Register write enable for some required peripherals. */
    LL_PERIPH_WE(LL_PERIPH_ALL);

    /* Initialize BSP system clock. */
    BSP_CLK_Init();

    /* Initializes UART for debug printing. Baudrate is 115200. */
    DDL_PrintfInit(BSP_PRINTF_DEVICE, 115200UL, BSP_PRINTF_Preinit);

    /* LED initialize */
    LED_Init();

    /* Configures ADC. */
    ADC_Configuration();

    /* Register write protected for some required peripherals. */
    LL_PERIPH_WP(LL_PERIPH_ALL);

    stc_clock_freq_t  stc_clock_freq;

    CLK_GetClockFreq(&stc_clock_freq);

    DDL_Printf("\r\n");
    DDL_Printf("\r\nEV_F448_LQ80_Rev1.0 %s %s", __DATE__, __TIME__);
    DDL_Printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32SysclkFreq / (double)1000000.0);
    DDL_Printf("\r\nHCLK   Frequency : %7.3f MHz", (double)stc_clock_freq.u32HclkFreq / (double)1000000.0);
    DDL_Printf("\r\nPCLK0  Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk0Freq / (double)1000000.0);
    DDL_Printf("\r\nPCLK1  Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk1Freq / (double)1000000.0);
    DDL_Printf("\r\nPCLK2  Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk2Freq / (double)1000000.0);
    DDL_Printf("\r\nPCLK3  Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk3Freq / (double)1000000.0);
    DDL_Printf("\r\nPCLK4  Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk4Freq / (double)1000000.0);
    DDL_Printf("\r\nEXCLK  Frequency : %7.3f MHz", (double)stc_clock_freq.u32ExclkFreq / (double)1000000.0);
    DDL_Printf("\r\n");

    TMR0_Start(TMR0_UNIT, TMR0_CH);

    for ( ;; )
    {
        LED_G_TOGGLE();
        DDL_DelayMS(500);
    }
}

 

2.3.运行结果

 

3.程序附件

替换HC32F448_DDL_Rev1.1.0\projects\ev_hc32f448_lqfp80目录下的template目录内容即可

template.zip (12.95 MB, 下载次数: 2)
点赞 关注
个人签名We are a team and we work as a team !
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表