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

Обсуждаем контроллеры компании Atmel.
Ответить
DarkWolf
Встал на лапы
Сообщения: 117
Зарегистрирован: Ср ноя 05, 2014 19:04:31

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

Сообщение 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); 
     }
}


Понимаю что коряво реализованно, поэтому и не работает, но это все на что сейчас способен мой мозг( Буд рад любой помощи.
Аватара пользователя
GRAF
Мудрый кот
Сообщения: 1867
Зарегистрирован: Ср янв 23, 2008 22:11:54
Откуда: Калининград

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

Сообщение 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.........
}

И Т.Д,
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение 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.
Ответить

Вернуться в «AVR»