Нужно получить импульсы некоторой определенной, меняющейся длины. Имеем ATMega32U4, 16ти разрядный третий таймер ,СТС режим, и алгоритм где я:
сбрасываю значения счетчиков, загружаю регистры сравнения (в смысле старший и младший их байт) и разрешаю счет таймеру, модуль сравнения А которого настроен на Toggle вывода OC3A. В прерывании совпадения с регистром сравнения запрещаю дальнейший счет.
Не врубаю откуда лишние три микросекунды на выходе данного формирователя берутся? Вот данные:
загружаю в OCR3A
0x01 на выходе импульс длиной 3,125 us
0x10 на выходе импульс длиной 5,000 us
0x20 на выходе импульс длиной 7,000 us
Невже так долго Create_Front выполняется? Пока писал родилась идея поставить
TCCR3C |= (1<<FOC3A);
непосредственно перед разрешением счета!
Код:
...
static void Init_Timer3 (void) {
TCCR3A |= (1<<COM3A0);
TCCR3B |= (1<<WGM32)|(1<<CS30);
TIMSK3 |= (1<<OCIE3A);
}
...
#pragma vector=TIMER3_COMPA_vect
__interrupt void TIMER3_COMPA_vect_(void) {
TCCR3B &= !(1<<CS30); // запрещаем счет
}
void Create_Front(INT16U pulse_length) {
while (TEST_PORT_BIT(TCCR3B,CS30)) // ждем пока предыдущий интервал окончится
;
TCNT3 = 0;
OCR3A = pulse_length;
TCCR3B |= (1<<CS30); // разрешаем счет
}
void Create_Pulse (INT16U value) {
TCCR3C |= (1<<FOC3A); // создадим передний/первый фронт
Create_Front(value); //создадим задний фронт на расстоянии "value" от переднего
}
void main (void) {
InitDevice ();
while (1) {
if (UARTDataInReceiveBuffer()){ // если есть что-то в буфере приемника, то:
if (UARTReceiveByte() == 0x55){ // аля "синхронизация"
Create_Pulse((UARTReceiveByte()<<8) | UARTReceiveByte ()); //два следующих байта за 0x55 передадим в функцию создающую импульс
}
}
}
}