打印
[Atmel]

跑一下SAM4N例程(二十五):TC捕捉功能

[复制链接]
1309|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这个例程展示了怎么样配置TC,一个从T1OA1发出波形一个从T1OA2输入波形。当TC中断发生,我们可以读RA和RB的值来计算脉冲频率和脉冲数量。


以下是发波的配置:

/** TC waveform configurations */
static const struct waveconfig_t gc_waveconfig[] = {
        {TC_CMR_TCCLKS_TIMER_CLOCK4, 178, 30},
        {TC_CMR_TCCLKS_TIMER_CLOCK3, 375, 50},
        {TC_CMR_TCCLKS_TIMER_CLOCK3, 800, 75},
        {TC_CMR_TCCLKS_TIMER_CLOCK2, 1000, 80},
        {TC_CMR_TCCLKS_TIMER_CLOCK2, 4000, 55}
};


以下是发波初始化:

static void tc_waveform_initialize(void)
{
        uint32_t ra, rc;

        /* Configure the PMC to enable the TC module. */
        sysclk_enable_peripheral_clock(ID_TC_WAVEFORM);
#if SAMG55
        /* Enable PCK output */
        pmc_disable_pck(PMC_PCK_3);
        pmc_switch_pck_to_mck(PMC_PCK_3, PMC_PCK_PRES_CLK_1);
        pmc_enable_pck(PMC_PCK_3);
#endif

        /* Init TC to waveform mode. */
        tc_init(TC, TC_CHANNEL_WAVEFORM,
                        /* Waveform Clock Selection */
                        gc_waveconfig[gs_uc_configuration].ul_intclock
                        | TC_CMR_WAVE /* Waveform mode is enabled */
                        | TC_CMR_ACPA_SET /* RA Compare Effect: set */
                        | TC_CMR_ACPC_CLEAR /* RC Compare Effect: clear */
                        | TC_CMR_CPCTRG /* UP mode with automatic trigger on RC Compare */
        );

        /* Configure waveform frequency and duty cycle. */
        rc = (sysclk_get_peripheral_bus_hz(TC) /
                        divisors[gc_waveconfig[gs_uc_configuration].ul_intclock]) /
                        gc_waveconfig[gs_uc_configuration].us_frequency;
        tc_write_rc(TC, TC_CHANNEL_WAVEFORM, rc);
        ra = (100 - gc_waveconfig[gs_uc_configuration].us_dutycycle) * rc / 100;
        tc_write_ra(TC, TC_CHANNEL_WAVEFORM, ra);

        /* Enable TC TC_CHANNEL_WAVEFORM. */
        tc_start(TC, TC_CHANNEL_WAVEFORM);
        printf("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
                        gc_waveconfig[gs_uc_configuration].us_frequency,
                        gc_waveconfig[gs_uc_configuration].us_dutycycle);
}
以下是捕捉初始化:


static void tc_capture_initialize(void)
{
        /* Configure the PMC to enable the TC module */
        sysclk_enable_peripheral_clock(ID_TC_CAPTURE);
#if SAMG55
        /* Enable PCK output */
        pmc_disable_pck(PMC_PCK_3);
        pmc_switch_pck_to_mck(PMC_PCK_3, PMC_PCK_PRES_CLK_1);
        pmc_enable_pck(PMC_PCK_3);
#endif

        /* Init TC to capture mode. */
        tc_init(TC, TC_CHANNEL_CAPTURE,
                        TC_CAPTURE_TIMER_SELECTION /* Clock Selection */
                        | TC_CMR_LDRA_RISING /* RA Loading: rising edge of TIOA */
                        | TC_CMR_LDRB_FALLING /* RB Loading: falling edge of TIOA */
                        | TC_CMR_ABETRG /* External Trigger: TIOA */
                        | TC_CMR_ETRGEDG_FALLING /* External Trigger Edge: Falling edge */
        );
}
以下是中断函数:

void TC_Handler(void)
{
        //! [tc_capture_irq_handler_start]
        //! [tc_capture_irq_handler_status]
        if ((tc_get_status(TC, TC_CHANNEL_CAPTURE) & TC_SR_LDRBS) == TC_SR_LDRBS) {
                //! [tc_capture_irq_handler_status]
                gs_ul_captured_pulses++;
                //! [tc_capture_irq_handler_read_ra]
                gs_ul_captured_ra = tc_read_ra(TC, TC_CHANNEL_CAPTURE);
                //! [tc_capture_irq_handler_read_ra]
                //! [tc_capture_irq_handler_read_rb]
                gs_ul_captured_rb = tc_read_rb(TC, TC_CHANNEL_CAPTURE);
                //! [tc_capture_irq_handler_read_rb]
        }
//! [tc_capture_irq_handler_end]
}
主循环如下:
while (1) {
                scanf("%c", (char *)&key);

                switch (key) {
                case 'h':
                        display_menu();
                        break;

                case 's':
                        if (gs_ul_captured_pulses) {
                                tc_disable_interrupt(TC, TC_CHANNEL_CAPTURE, TC_IDR_LDRBS);
                                printf("Captured %u pulses from TC%d channel %d, RA = %u, RB = %u \n\r",
                                                (unsigned)gs_ul_captured_pulses, TC_PERIPHERAL,
                                                TC_CHANNEL_CAPTURE,        (unsigned)gs_ul_captured_ra,
                                                (unsigned)gs_ul_captured_rb);
                                frequence = (sysclk_get_peripheral_bus_hz(TC) /
                                                divisors[TC_CAPTURE_TIMER_SELECTION]) /
                                                gs_ul_captured_rb;
                                dutycycle
                                        = (gs_ul_captured_rb - gs_ul_captured_ra) * 100 /
                                                gs_ul_captured_rb;
                                printf("Captured wave frequency = %d Hz, Duty cycle = %d%% \n\r",
                                                frequence, dutycycle);

                                gs_ul_captured_pulses = 0;
                                gs_ul_captured_ra = 0;
                                gs_ul_captured_rb = 0;
                        } else {
                                puts("No waveform has been captured\r");
                        }

                        puts("\n\rPress 'h' to display menu\r");
                        break;

                case 'c':
                        puts("Start capture, press 's' to stop \r");
                        //! [tc_capture_init_module_irq]
                        tc_enable_interrupt(TC, TC_CHANNEL_CAPTURE, TC_IER_LDRBS);
                        //! [tc_capture_init_module_irq]
                        /* Start the timer counter on TC TC_CHANNEL_CAPTURE */
                        //! [tc_capture_start_now]
                        tc_start(TC, TC_CHANNEL_CAPTURE);
                        //! [tc_capture_start_now]
                        break;

                default:
                        /* Set waveform configuration #n */
                        if ((key >= '0') && (key <= ('0' + gc_uc_nbconfig - 1))) {
                                if (!gs_ul_captured_pulses) {
                                        gs_uc_configuration = key - '0';
                                        tc_waveform_initialize();
                                } else {
                                        puts("Capturing ... , press 's' to stop capture first \r");
                                }
                        }

                        break;
                }
最后的运行结果:显示了准确的捕捉。




相关帖子

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

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2399

主题

6963

帖子

68

粉丝