Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7A3 Генерация импульсов ШИМ
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
KSN
По каналу PWM2 геренирую прямоугольные импульсы, частотой 40Кгц, частотя ядра 60МГц. Выход PWM2 использую как вход тактовых импульсов для таймера0. Таймер0 настроил в режим подсчета импульсов. Хочу сгенерить 1 импульс. В итоге получаю:
на осцилле вижу 2 импульса, а счетчик таймера насчитал 1. В чем дело, не могу понять.
Объясните, где просмотрел или не учел что-то?
Ставлю любое количество импульсов, в итоге получаю расхождение на 1 импульс.
Код привожу ниже:
pSD->End_cnt = 1; // Число генерируемых импульсов.
PORT_STEP->PIO_PDR = BIT_STEP; // config PB16 - output PWMC2
PORT_STEP->PIO_BSR = BIT_STEP;
PORT_COUNTER->PIO_PDR = BIT_COUNTER; // config PB10 - input timer0
PORT_COUNTER->PIO_ASR = BIT_COUNTER;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
temp = AT91C_BASE_TC0->TC_SR;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKI|AT91C_TC_CLKS_XC1|AT91C_TC_WAVESEL_UP|AT91C_TC_WAVE;
AT91C_BASE_TC0->TC_RC = pSD->End_cnt%65536;
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) timer_handler;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR&PRIORITY_TCO);
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);
if( (pSD->End_cnt > 65535) ) { AT91C_BASE_TC0->TC_IER = AT91C_TC_COVFS; }
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PWMC);
AT91C_BASE_PWMC->PWMC_MR = 0;

AT91C_BASE_PWMC_CH2->PWMC_CMR = (AT91C_PWMC_CPRE&1)|AT91C_PWMC_CPD;
AT91C_BASE_PWMC_CH2->PWMC_CPRDR = (AT91B_MCK/2)/40000;
AT91C_BASE_PWMC_CH2->PWMC_CDTYR = ((AT91B_MCK/2)/40000)/2;
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_PWMC);
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PWMC] = (unsigned long) pwmc_handler;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PWMC] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR & PRIORITY_PWMC);
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_PWMC);
AT91C_BASE_PWMC->PWMC_ENA = AT91C_PWMC_CHID2;
KSN
Разобрался. Лишний раз убедился, ВНИМАТЕЛЬНО, надо читать даташин. Кому интересно, все дело в синхронизации и двух строчках кода:
// разрешаю тактирование таймера
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
// Сброс значения счетчика и начало счета.
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
Сброс происходит синхронно, с поступлением тактового импульса. Вот и получается, первый импульс -
сбрасывает счетчик, а второй импульс инкрементируется счетчик.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.