Генератор меандра на atmel ATtiny13.

На просторах интернета предлагается обилие различных генераторов прямоугольных сигналов(меандра).
Используются или логические микросхемы или таймер 555.
Вашему вниманию предлагается генератор на микроконтроллере. Он состоит всего из 3х деталей.

Схема генератора меандра

В данном устройстве не используется ШИМ.

Принцип формирования сигнала состоит в «измерении» длины выходного импульса, и по достижению заданного значения происходит смена логического уровня.

По умолчанию на выходе сигнал с частотой ~1000гц. Похож на гудок в старых, проводных телефонах. Когда поднял трубку.

Для питания и отладки  используется программатор USBASP.
На плате распаян резистор и динамик с мобильника. Это позволяет проверять программу «на слух».
Кнопки регулируют частоту на выходе генератора. Больше/меньше. Шаг задан в коде программы.

В вечном цикле , увеличиваем  значение длины импульса, находящееся в переменной.
Сравниваем с заданным значением. Как только достигаем его – очищаем счетчик длины, и изменяем на выводе логический уровень. Фактически инвертируем его.

//#define F_CPU 4800000UL
#define START_PULSE_LENGTH 200; //Default on mcu start.
#define MIN_PULSE_LENGTH 2
#define MAX_PULSE_LENGTH 400000 //2Hz
#define PULSE_LENGTH_STEP 20
#include <Util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t timeCounter1 = 0; //Software counter for button.
uint32_t pulseLength = 0; //Setup pulse length.
uint32_t pulseLengthCounter = 0; //Pulse length counter.
uint8_t pulseLevel = 0; //Level on output 1/0.
//Timer/Counter0 Overflow
ISR(TIM0_OVF_vect){
    //Software counter.
    timeCounter1 ++;
    if(timeCounter1 >= 5)
    {
        timeCounter1 = 0; //Clear software counter.
        
            uint8_t btnDown = PINB & 0b00010000;
            if(btnDown == 0 & pulseLength <= MAX_PULSE_LENGTH) //Push this button.
            {
                pulseLength+= PULSE_LENGTH_STEP;
            }
            uint8_t btnUp = PINB & 0b00001000;
            if(btnUp == 0 & pulseLength >= MIN_PULSE_LENGTH)
            {
                pulseLength-= PULSE_LENGTH_STEP;
            }    
    }    
}
//Change level on output.
void changeLevelOnOutput()
{
    if(pulseLevel == 1)
    {
        PORTB&= 0b11111110; //0 level.
        pulseLevel = 0;
    }
    else
    {
        pulseLevel = 1;
        PORTB|= 0x01; //1 level.
    }
}
int main(void)
{     
    TCCR0B = 0b00000100; //Mcu clock/256
    TIMSK0 = 0b00000010; //Allow interrupt for tc0.    
    DDRB = 1; //Setup output on PB0.
    PORTB = 0x18; //Internal resistors for button to plus line.
    
    sei(); //Allow all interupts.
    
    changeLevelOnOutput(); //Setup logic 1.
    pulseLength = START_PULSE_LENGTH;
   while (1) 
   {
        pulseLengthCounter++; //Count pulse length.
        
        if(pulseLengthCounter > pulseLength)
        {
            pulseLengthCounter = 0;
            changeLevelOnOutput();
        }
   }
}

Для кнопок настраивается таймер/счетчик. Он тактируется от встроенного RC генератор, через делитель на 256.
По переполнению  – возникнет прерывание.
В нем смотрим нажал ли пользователь кнопки.  И ограничиваем интервал максимального и минимального значения частоты на выходе.
Размер прошивки 416 байт.  Это где то 40% объема памяти микроконтроллера с 1к флеш.
Оставшиеся 60% можно использовать для  своих доработок.
Это могут быть фиксированные значения с помощью перемычек. 
Так же, генератор может заменить промышленное реле времени вышедшее из строя. И будет потреблять гораздо меньше тока.

На выходе генератора высокий уровень равен напряжению питания, низкий стремиться к нулю. Точные значения можно посмотреть в даташите на микроконтроллер.

Прошивка заливается программой AVRDUDEPROG.

Фузы

Скачать исходники