这个例程展示了怎么样配置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;
}
最后的运行结果:显示了准确的捕捉。
|