реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Работа с таймерами в Xmega, Проблема с настройкой режима захвата
Nosaer
сообщение Feb 8 2015, 03:37
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 85
Регистрация: 6-02-15
Пользователь №: 84 967



Добрый день.
Помогите пожалуйста с настройкой таймеров Xmega32A4.
Что то я в этих регистрах настройки совсем запутался... wacko.gif
По задумке, 3 таймера счетчика активированы на PC0, PD0, PE0.
Настроены на захват длительности импульса по падающему фронту.
Ну и соответственно при запуске все три ничего не считают.

Работоспособность проверяю в AVR Studio 6.

Надеюсь на вашу помощь. Спасибо)
CODE
void StartTimers(void) // Запускаем режим захвата по трем каналам таймера
{
TCC0.CTRLA = TC_CLKSEL_EVCH0_gc; // Выбираем источником тактов нулевой канал порта
TCD0.CTRLA = TC_CLKSEL_EVCH0_gc;
TCE0.CTRLA = TC_CLKSEL_EVCH0_gc;
}

void StopTimers(void) // Останавливаем работу таймеров
{
TCC0.CTRLA = TC_CLKSEL_OFF_gc;
TCD0.CTRLA = TC_CLKSEL_OFF_gc;
TCE0.CTRLA = TC_CLKSEL_OFF_gc;
}

int main(void)
{
// Настройка работы от внешнего кварца в 4МГц
cli(); // Отключение прерываний
OSC.XOSCCTRL = 0x4B; // 2-9 МГц без режима сбережения и со стабильной частотой во время запуска (01001011)
OSC.CTRL = 0x08; // Разрешение работы внешнего генератора
while((OSC.STATUS & 0x08) == 0); // Ожидание сигнала о включении внешнего генератора

// Настройка портов
PORTC.DIR = 0x1C; // PC0 - T/C-X
PORTD.DIR = 0x00; // PD0 - T/C-Y
PORTE.DIR = 0x00; // PE0 - T/C-Z

PORTC.PIN0CTRL = PORT_OPC_WIREDORPULL_gc | PORT_ISC_FALLING_gc; // Установка чувствительности по заднему фронту
PORTD.PIN0CTRL = PORT_OPC_WIREDORPULL_gc | PORT_ISC_FALLING_gc;
PORTE.PIN0CTRL = PORT_OPC_WIREDORPULL_gc | PORT_ISC_FALLING_gc;

PORTC.INTCTRL = PORT_INT0LVL_HI_gc; // Настройка высокого уровня прерываний
PORTD.INTCTRL = PORT_INT0LVL_HI_gc;
PORTE.INTCTRL = PORT_INT0LVL_HI_gc;
PORTR.INTCTRL = PORT_INT0LVL_HI_gc;
PMIC.CTRL|=PMIC_HILVLEN_bm|PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm; // Разрешаем все уровни прерываний

//Единоразовая настройка таймеров
TCC0.CTRLB = 0x00; // Выбрали режим: Normal
TCD0.CTRLB = 0x00;
TCE0.CTRLB = 0x00;
TCC0.CTRLD = 0xC8; // Захват длительности импульса по 0 каналу
TCD0.CTRLD = 0xC8; // EVACT = 110 - захват длительности; 001 - входной захват
TCE0.CTRLD = 0xC8; // EVSEL = 1000 - выбор 0 канала для захвата
TCC0.INTCTRLA = 0x01; // Разрешаем прерывания низкого уровня по переполнению
TCD0.INTCTRLA = 0x01; // 0x01 - низкий уровень; 0x02 - средний; 0x03- высокий уровень...
TCE0.INTCTRLA = 0x01;

sei(); // Включение прерываний


Сообщение отредактировал IgorKossak - Feb 8 2015, 12:04
Причина редактирования: [codebox] для длинного кода, [code] - для короткого
Go to the top of the page
 
+Quote Post
Xenia
сообщение Feb 8 2015, 04:45
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(Nosaer @ Feb 8 2015, 06:37) *
По задумке, 3 таймера счетчика активированы на PC0, PD0, PE0.
Настроены на захват длительности импульса по падающему фронту.
Ну и соответственно при запуске все три ничего не считают.


Счетные пины портов с входом таймера жестко не связаны, а соединяются через систему событий. А вот выход генерации у таймеров (PWM) уже связан жестко с конкретным пином.

Например, выход частоты с таймера TCC0 поступает на пин PС0 жестко, его никак нельзя поменять на какой-то другой пин (правда в описании упоминается возможность выхода на область PС0-PC3, но лично мне этого сделать не удалось). Поэтому, если вы рассчитываете вывести наружу частоту, генерируемую таймером, то должны позаботиться, чтобы пин PС0 под другие цели не был занят.

Напротив, если вы расчитываете использовать таймер не для генерации сигнала, а исключительно для счета внешних сигналов, то вход для такого сигнала можно подключить не только на порт PС, но и на любой из пинов портов PС, PD, PE, PF.

А связь между конкретным пином и таймером производится через систему событий, имеющую 8 каналов.

Делается это так:
1) выбираете нужный вам пин среди портов С,D,E,F. Пусть это будет PF3. Устанавливаете ему чувствительность:
PORTF.PIN3CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_FALLING_gc; // Pull-down, sense falling edge PF3

2) Выбираете канал передачи события, пусть это будет канал 0. Направляете на него импульс с PF3
EVSYS.CH0MUX = EVSYS_CHMUX_PORTF_PIN3_gc; // EV channel 0 <- PF3 (sensor)

3) Выбирате таймер, пусть это будет таймер TCC0. Устанавливаете ему источником счета канал 0 событий.
TCC0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH0_gc; // external capture <- EV channel 0
(насчет TC_EVACT_CAPT_gc не уверена, что он тут необходим)

Всё остальное не описываю, т.к. главная логика здесь такая:
PF3 ---> CH0 ---> TCC0
Пин PF3 можно заменить на другой (менять на PC0 я бы остереглась). При этом изменятся команды 1 и 2.
EV-канал CH0 тоже можно заменить на любой от CH0 до CH7 (они все одинаковые). При этом изменятся команды 2 и 3.
Таймер TCC0 можно заменить на любой другой. При этом изменится команда 3.

Никакие прерывания в этом механизме передачи возбуждения с пина порта на счет таймера не используются. Сама система событий EVSYS тоже вроде бы ни в какой предварительной инициализации не нуждается. А таймеры программируются общим порядком, с тем лишь единственным исключением, что в CTRLD подставляется нетипичный источник.

P.S. От одного EV-канала можно запускать на счет (или сброс) сразу несколько таймеров, если им указать этот канал в виде источника счета (или сброса), но вход EV-канала всегда может быть только один.
P.P.S. Выход с EV-канала может быть (параллельно) использован и для других целей - возбуждения прерывания или DMA. Или можно соединить два таймера в каскад, если передавать по каналу переполнение от одного из них на счетный вход другого. К моему большому сожалению его нельзя использовать для дрыгания другими ножками портов, а то бы этой системе просто цены не было! sm.gif
Go to the top of the page
 
+Quote Post
Nosaer
сообщение Mar 6 2015, 06:58
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 85
Регистрация: 6-02-15
Пользователь №: 84 967



Извините за долгий ответ, работа.
Спасибо большое. Очень доступно объяснили, так скажем расставили все точки над i.
С первого раза все заработало.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 00:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.01362 секунд с 7
ELECTRONIX ©2004-2016