Страница 1 из 1

ATiny13 формирование сигнала 4 канала

Добавлено: Вт фев 09, 2016 08:36:05
DarkWolf
Всем доброго времени суток! Сталкнулся с такой задачей: необходимо сформировать сигнал на 4 пинах. Делаю с помощью таймера. Сигнал следующего вида- "низкий уровень -> высокий уровень (85 мс) -> низкий уровень (30мс) -> высокий уровень (85мс) -> низкий уровень (300 мс)

что сделано:
Таймер настраиваю на 85 мс. При частоте контроллера 1250000 (после делителя)

Код: Выделить всё

void InitTimer0()
{
    TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
    // Делитель 1024
    TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
    TCNT0=0x00;
    OCR0A= 0x67;    //(85мс)   
    OCR0B=0x00;
    TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
}
обработка прерывания от таймера

Код: Выделить всё

interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
    inc++;
    if (inc == 2)
    {   
        PORTB  ^=  (1<<PORTB5);
        PORTB  ^=  (1<<PORTB4);
        delay_ms(30);
        PORTB  ^=  (1<<PORTB5);
        PORTB  ^=  (1<<PORTB4);
    } 
    if (inc == 4)
     {
        delay_ms(215);
        inc = 0;
     } 
    if ((inc != 2)&&(inc != 4))
     {
        PORTB  ^=  (1<<PORTB5);
        //PORTB  ^=  (1<<PORTB6);
        //PORTB  ^=  (1<<PORTB7);
        PORTB  ^=  (1<<PORTB4);  
     }
}
Понимаю что коряво реализованно, поэтому и не работает, но это все на что сейчас способен мой мозг( Буд рад любой помощи.

Re: ATiny13 формирование сигнала 4 канала

Добавлено: Вт фев 09, 2016 18:08:05
GRAF
Очень коряво. Особенно задержки больше периода срабатывания прерывания в обработчике этого прерывания.
Настройте таймер на прерывание каждую 1 мс, например, ставьте флаг по прерыванию. В основном цикле проверяете флаг, инкрементируете переменную-счетчик, сбрасываете флаг. Контролируете переменную-счетчик и по ней выставляете нужное состояние на порте.

Взял кусок из своей проги для ATmega8A. Обработчик прерывания T/C0 по переполнению.

Код: Выделить всё

interrupt [TIM0_OVF] void tc0_ovf_isr(void) 
{
    TCNT0=68;//1ms interrupt
    timer|=0x02;
}
В основном цикле while(1):

Код: Выделить всё

if(timer&0x02)//timer&tc0
{
     timer&=0xFD;//clear tc0 flag
     clock10++;
}

if(clock10==НУЖНОЕ ВАМ ЗНАЧЕНИЕ)
{
    TO DO.........
}

И Т.Д,

Re: ATiny13 формирование сигнала 4 канала

Добавлено: Пт фев 19, 2016 03:16:33
pokk
Как ещё один из вариантов вместо delay_ms(30); сделайте перенастройку таймера.
т.е это будет примерно так:
Спойлер

Код: Выделить всё

enum{
	high_85ms,
	low_30ms,
	high2_85ms,
	low_300ms,
};



unsigned char mode=high_85ms;

//До входа в таймер настроили порты на выход и выдаёте ноль 
//в таймере находится это 

switch(mode){
	case high_85ms:{
		//Выдать в порты 1 
		//Перенастроить таймер на 30ms
		mode=low_30ms;
		break;
	}
	case low_30ms:{
		//Выдать в порты 0 
		//Перенастроить таймер на 85ms
		mode=low_30ms;		
		break;
	}
	case high2_85ms:{
		//Выдать в порты 1 
		//Перенастроить таймер на 300ms
		mode=low_30ms;				
		break;
	}
	case low_300ms:{
		//Выдать в порты 0 
		//Перенастроить таймер на 85ms
		//------------------------------
		mode=high_85ms;		//Начать всё с начала
							// или делаете ещё один case из которого нету выхода
							//и переходите туда что бы остановить генерацию сигнала 		
		break;
	}
}
Преимущества:
1) Можно формировать сигналы с периодами микросекунды, что не особо получится в том подходе как предложил GRAF
2) Меньше прерываний главного цикла(нету лишних).
Недостатки:
1) В случае необходимости формировании сигнала на разных выводах с разными таймингами, переделать очень сложно.В таком случае лучше подходим вариант описанный GRAF.