打印
[牛人杂谈]

DAC的软件触发与定时器触发之对比

[复制链接]
604|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gejigeji521|  楼主 | 2024-7-13 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
软件触发示例:
/*************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
* [url=home.php?mod=space&uid=247401]@brief[/url]    Demonstrate how to trigger DAC conversion by software.
*
* [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2016 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include "stdio.h"
#include "NuMicro.h"

#if defined (__GNUC__) && !defined(__ARMCC_VERSION) && defined(OS_USE_SEMIHOSTING)
extern void initialise_monitor_handles(void);
#endif

#define PLL_CLOCK           192000000

const uint16_t sine[] = {2047, 2251, 2453, 2651, 2844, 3028, 3202, 3365, 3515, 3650, 3769, 3871, 3954,
                         4019, 4064, 4088, 4095, 4076, 4040, 3984, 3908, 3813, 3701, 3573, 3429, 3272,
                         3102, 2921, 2732, 2536, 2335, 2132, 1927, 1724, 1523, 1328, 1141,  962,  794,
                         639,  497,  371,  262,  171,   99,   45,   12,    0,    7,   35,   84,  151,
                         238,  343,  465,  602,  754,  919, 1095, 1281, 1475, 1674, 1876
                        };

static uint32_t index = 0;
const uint32_t array_size = sizeof(sine) / sizeof(uint16_t);

void DAC_IRQHandler(void)
{
    if(DAC_GET_INT_FLAG(DAC0, 0))
    {

        if(index == array_size)
            index = 0;
        else
        {
            DAC_WRITE_DATA(DAC0, 0, sine[index++]);
            DAC_START_CONV(DAC0);
            /* Clear the DAC conversion complete finish flag */
            DAC_CLR_INT_FLAG(DAC0, 0);

        }
    }
    return;
}


void SYS_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
    PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

    /* Enable HXT clock (external XTAL 12MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

    /* Wait for HXT clock ready */
    CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);
    /* Set PCLK0/PCLK1 to HCLK/2 */
    CLK->PCLKDIV = CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2;

    /* Enable DAC module clock */
    CLK_EnableModuleClock(DAC_MODULE);
    /* Set PB.12 to input mode */
    PB->MODE &= ~GPIO_MODE_MODE12_Msk;
    /* Set PB multi-function pins for DAC voltage output */
    SYS->GPB_MFPH |= SYS_GPB_MFPH_PB12MFP_DAC0_OUT;
    /* Disable digital input path of analog pin DAC0_OUT to prevent leakage */
    GPIO_DISABLE_DIGITAL_PATH(PB, (1ul << 12));
    /* Lock protected registers */
    SYS_LockReg();


}

int32_t main(void)
{

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

#if defined (__GNUC__) && !defined(__ARMCC_VERSION) && defined(OS_USE_SEMIHOSTING)
    initialise_monitor_handles();
#endif

    printf("Please hit any key to start trigger DAC by software\n");
    getchar();

    /* Set the software trigger DAC and enable D/A converter */
    DAC_Open(DAC0, 0, DAC_SOFTWARE_TRIGGER);

    /* The DAC conversion settling time is 1us */
    DAC_SetDelayTime(DAC0, 1);

    /* Set DAC 12-bit holding data */
    DAC_WRITE_DATA(DAC0, 0, 0x400);

    /* Clear the DAC conversion complete finish flag for safe */
    DAC_CLR_INT_FLAG(DAC0, 0);

    /* Enable the DAC interrupt */
    DAC_ENABLE_INT(DAC0, 0);
    NVIC_EnableIRQ(DAC_IRQn);

    /* Start A/D conversion */
    DAC_START_CONV(DAC0);

    while(1);

}

定时器触发示例
/*************************************************************************//**
* @file     main.c
* @version  V1.00
* @brief    Demonstrate how to trigger DAC by timer.
*
* @copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include "stdio.h"
#include "NuMicro.h"

#if defined (__GNUC__) && !defined(__ARMCC_VERSION) && defined(OS_USE_SEMIHOSTING)
extern void initialise_monitor_handles(void);
#endif

#define PLL_CLOCK           192000000

const uint16_t sine[] = {2047, 2251, 2453, 2651, 2844, 3028, 3202, 3365, 3515, 3650, 3769, 3871, 3954,
                         4019, 4064, 4088, 4095, 4076, 4040, 3984, 3908, 3813, 3701, 3573, 3429, 3272,
                         3102, 2921, 2732, 2536, 2335, 2132, 1927, 1724, 1523, 1328, 1141,  962,  794,
                         639,  497,  371,  262,  171,   99,   45,   12,    0,    7,   35,   84,  151,
                         238,  343,  465,  602,  754,  919, 1095, 1281, 1475, 1674, 1876
                        };

const uint32_t array_size = sizeof(sine) / sizeof(uint16_t);
static uint32_t index = 0;


void DAC_IRQHandler(void)
{
    if(DAC_GET_INT_FLAG(DAC0, 0))
    {

        if(index == array_size)
            index = 0;
        else
        {
            DAC_WRITE_DATA(DAC0, 0, sine[index++]);

            /* Clear the DAC conversion complete finish flag */
            DAC_CLR_INT_FLAG(DAC0, 0);

        }
    }
    return;
}


void SYS_Init(void)
{

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
    PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

    /* Enable HXT clock (external XTAL 12MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

    /* Wait for HXT clock ready */
    CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);
    /* Set PCLK0/PCLK1 to HCLK/2 */
    CLK->PCLKDIV = CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2;


    /* Enable DAC module clock */
    CLK_EnableModuleClock(DAC_MODULE);

    /* Enable Timer 0 module clock */
    CLK_EnableModuleClock(TMR0_MODULE);

    /* Select timer 0 module clock source as HXT */
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);
    /* Set PB.12 to input mode */
    PB->MODE &= ~GPIO_MODE_MODE12_Msk;
    /* Set PB multi-function pins for DAC voltage output */
    SYS->GPB_MFPH |= SYS_GPB_MFPH_PB12MFP_DAC0_OUT;
    /* Disable digital input path of analog pin DAC0_OUT to prevent leakage */
    GPIO_DISABLE_DIGITAL_PATH(PB, (1ul << 12));
    /* Lock protected registers */
    SYS_LockReg();
}


int32_t main(void)
{
    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

#if defined (__GNUC__) && !defined(__ARMCC_VERSION) && defined(OS_USE_SEMIHOSTING)
    initialise_monitor_handles();
#endif

    printf("\nHit any key to start!\n");
    getchar();
    /* Set the timer 0 trigger,DAC and enable D/A converter */
    DAC_Open(DAC0, 0, DAC_TIMER0_TRIGGER);

    /* The DAC conversion settling time is 1us */
    DAC_SetDelayTime(DAC0, 1);

    /* Set DAC 12-bit holding data */
    DAC_WRITE_DATA(DAC0, 0, sine[index]);

    /* Clear the DAC conversion complete finish flag for safe */
    DAC_CLR_INT_FLAG(DAC0, 0);

    /* Enable the DAC interrupt.  */
    DAC_ENABLE_INT(DAC0, 0);
    NVIC_EnableIRQ(DAC_IRQn);

    /* Configure Timer 0 frequency to 1000Hz and start it. */
    TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1000);
    TIMER_SetTriggerTarget(TIMER0, TIMER_TRG_TO_DAC);
    TIMER_Start(TIMER0);

    while(1);

}



使用特权

评论回复
沙发
gejigeji521|  楼主 | 2024-7-13 16:47 | 只看该作者
程序分析:
程序1:软件触发 DAC 转换
概述:
程序通过软件触发 DAC(数模转换器)转换。
使用中断处理器处理 DAC 转换完成的中断。
关键部分:
使用 DAC_START_CONV(DAC0) 触发 DAC 转换。
在 DAC_IRQHandler 中检查并清除 DAC 中断标志,同时更新下一个 DAC 输出数据。
主要步骤包括初始化系统时钟和 DAC 模块,设置 DAC 的转换延迟时间,开启 DAC 中断,并通过 DAC_START_CONV 触发转换。

使用特权

评论回复
板凳
gejigeji521|  楼主 | 2024-7-13 16:47 | 只看该作者
软件触发的关键步骤:
/* 主要步骤 */
SYS_Init();
DAC_Open(DAC0, 0, DAC_SOFTWARE_TRIGGER);
DAC_SetDelayTime(DAC0, 1);
DAC_WRITE_DATA(DAC0, 0, 0x400);
DAC_CLR_INT_FLAG(DAC0, 0);
DAC_ENABLE_INT(DAC0, 0);
NVIC_EnableIRQ(DAC_IRQn);
DAC_START_CONV(DAC0);

使用特权

评论回复
地板
gejigeji521|  楼主 | 2024-7-13 16:47 | 只看该作者
程序2:定时器触发 DAC 转换
概述:

程序通过定时器触发 DAC 转换。
使用中断处理器处理 DAC 转换完成的中断。
关键部分:

使用定时器 0 触发 DAC 转换。
在 DAC_IRQHandler 中检查并清除 DAC 中断标志,同时更新下一个 DAC 输出数据。
主要步骤包括初始化系统时钟、定时器和 DAC 模块,设置 DAC 的转换延迟时间,开启 DAC 中断,并通过定时器配置触发 DAC 转换。

使用特权

评论回复
5
gejigeji521|  楼主 | 2024-7-13 16:47 | 只看该作者
定时器触发的关键步骤
/* 主要步骤 */
SYS_Init();
DAC_Open(DAC0, 0, DAC_TIMER0_TRIGGER);
DAC_SetDelayTime(DAC0, 1);
DAC_WRITE_DATA(DAC0, 0, sine[index]);
DAC_CLR_INT_FLAG(DAC0, 0);
DAC_ENABLE_INT(DAC0, 0);
NVIC_EnableIRQ(DAC_IRQn);
TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1000);
TIMER_SetTriggerTarget(TIMER0, TIMER_TRG_TO_DAC);
TIMER_Start(TIMER0);

使用特权

评论回复
6
gejigeji521|  楼主 | 2024-7-13 16:52 | 只看该作者
主要不同点总结:
触发方式:

程序1 使用软件触发 (DAC_SOFTWARE_TRIGGER)。
程序2 使用定时器触发 (DAC_TIMER0_TRIGGER)。
定时器使用:

程序1 不使用定时器。
程序2 使用定时器 0 配置为 1000Hz 的周期模式,并设置定时器触发 DAC 转换。
初始化过程:

程序1 初始化过程中不涉及定时器。
程序2 初始化过程中包含定时器 0 的配置和启动。
这两个程序分别展示了如何使用不同的触发方式来进行 DAC 转换,具体使用哪种方式可以根据实际应用需求来选择。

使用特权

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

本版积分规则

177

主题

2224

帖子

8

粉丝