Attiny 13 časovač

Zdravím
Už jsem tady dlouho nebyl odradilo mě ta změna vizáže tohoto fóra no nic změna je asi život…
Potřeboval bych na švába Attiny 13 program kde jedou hodiny a určitou dobu kterou si sám určím mě nahodí pin( který je volný ten pin aby nekolidoval programovacími piny) a vydržel třeba 2 hodiny a to v jeden den několikrát.Mám kompiler GCC nějak díky

Ahoj.
Takový program není problém, ale :

  1. Co to přesně znamená “kde jedou hodiny”
  2. Jak si určíš dobu/doby, kdy se nahodí pin.
  3. Chceš, aby délka sepnutí byla pevná nebo nastavitelná ?

Když chceš pin, který nebude kolidovat s programovacími piny, tak na celém IO zbývají 2.
Máš nějaký zvláštní důvod k tomuto požadavku (tedy samozřejmě kromě toho, aby se Ti výstup nespínal během programování) ?

  1. v attiny 13
  2. změním v programu podle situace
  3. ano chci aby délka byla nastavitelná
    A co se týká programovací prostředí nejlepší v arduinu mám i atmel studio 6 ale v něm jsem dlouho nedělal musel bych se do toho vpravit díky

Dobře - zeptám se přesněji : jaké hodiny más na mysli ?
Něco jako RTC nebo jenom odpočítávání doby ?
V případě RTC musíš nějak řešit přesnost, protože interní RC oscilátor zrovna přesností a teplotní stabilitou nevyniká.
Jako, jestli to chceš, že přes pin spustíš časování, tak tam interní RC stačí. Při délce výstupního pulzu 2 hodiny se odchýlíš maximálně o pár vteřin.

Arduino nepoužívám, pokud to budu psát, tak Atmel Studio 7.

Ty vnitřní hodiny ,tam krystal by se tam ani nevlezl do čeho to zamýšlím , sekunda sem sekunda tam na tom nezáleží

Čí to byl nápad přejít na tento styl fóra ? :sleepy:

OK. Jak si představuješ start pulzu ? Při zapnutí ? Nebo nějakým pinem (tlačítkem) ? Nastavení času jsem myslel třeba trimrem na druhém volném vstupu MCU, když už nechceš používat programovací piny.

Já bych nekomplikoval tím trimrem já to potřebuji co nejmenší prostě jen attiny13 a to je vše díky

/*
 * Meloun1_AtTiny13A_PulsNaPinu.cpp
 *
 * Created: 21.5.2022 16:54:51
 * Author : Balů
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/atomic.h>

// Přednastavení délky impulzu
#define HourPreset (0)
#define MinPreset  (0)
#define SecPreset  (3)

//Pokud chceš pulz aktivní v 0, odkomentuj následující řádek.
//#define PulseActiveLow

#define KeyIn (PINB&(1<<PINB3))

#define PulsePin (PORTB4)
#if defined(PulseActiveLow)
#pragma message "Output active low"
    #define PulseOn (PORTB &= (~(1<<PulsePin)))
    #define PulseOff (PORTB |= (1<<PulsePin))
#else
#pragma message "Output active high"
    #define PulseOn (PORTB |= (1<<PulsePin))
    #define PulseOff (PORTB &= (~(1<<PulsePin)))
#endif

#define OneSecondPreset (72) // Frekvence přerušení 73,2421875 - počítá se 72 až 0 => 73
unsigned char OneSecondTimer;
#define OneSecondCorrectionPreset (3) // Kompenzace toho cca 0,25 impulzu
unsigned char OneSecondCorrection;

typedef struct PulseTimerStruct
{
    unsigned char Hour;
    unsigned char Min;
    unsigned char Sec;
} PulseTimerStruct;

volatile PulseTimerStruct PulseTimer;

unsigned char KeyDebounce;

ISR(TIM0_OVF_vect)
{
    KeyDebounce <<= 1;
    if (!(KeyIn)) KeyDebounce++;
    
    if (!OneSecondTimer)
    {
        if ((PulseTimer.Hour)||(PulseTimer.Min)||(PulseTimer.Sec))
        {
            OneSecondTimer = OneSecondPreset;
            if (OneSecondCorrection)
            {
                OneSecondCorrection--;
            }
            else
            {
                OneSecondTimer++;
                OneSecondCorrection = OneSecondCorrectionPreset;
            }
            PulseOn;
        }
        else
        {
            PulseOff;
        }

        if (PulseTimer.Sec)
        {
            PulseTimer.Sec--;
        }
        else
        {
            if ((PulseTimer.Hour) || (PulseTimer.Min))
            {
                PulseTimer.Sec = 59;
                if (PulseTimer.Min)
                {
                    PulseTimer.Min--;
                }
                else
                {
                    PulseTimer.Min = 59;
                    PulseTimer.Hour--;
                }
            }
        }
    }
    else
    {
        OneSecondTimer--;
    }
}

void HW_Setup( void )
{
#if defined(PulseActiveLow)
  PORTB = 0xFF;
#else
  PORTB = ~(1<<PulsePin);
#endif
  DDRB = (1<<PulsePin);
  

  TCCR0A = 0;
  TCCR0B = (0<<CS02)|(1<<CS01)|(1<<CS00);
  TIFR0 = 255;
  TIMSK0 = (1<<TOIE0);

  sei();
  set_sleep_mode(SLEEP_MODE_IDLE);
}

int main(void)
{
    HW_Setup();

    while (1)
    {
        sleep_enable();
        sleep_cpu();
        sleep_disable();

        if (KeyDebounce == 0xFF)
        {
            ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
            {
                PulseTimer.Hour = HourPreset;
                PulseTimer.Min = MinPreset;
                PulseTimer.Sec = SecPreset;
            }
        }
    }
}

Připojením vstupu B3 (tlačítko, externí signál) na GND (log. 0) se zapne impulz na pinu B4 (aktivní podle nastavení v programu) a délka pulzu se nastaví na požadovanou dobu. Pokud je impulz aktivní, tak se jen čas na požadovanou dobu nastaví (prodlouží).

Program je tak jednonuchý, že nebylo třeba ho dělit do více souborů. Vytvoř si projekt v Atmel Studiu a program tam zkopíruj. Pojistky procesoru nech v default - tím pádem by procesor měl běžet na 1,2MHz.

Pulz se dá nastavit na 1s až 255h, 255min, 255sekund - nehlídám, jestli si nastavíš začátek na nesmysly…

Na druhou stranu, když chceš třeba 150 minut nebo vteřin, tak to nemusíš přepočítávat. Jediné, čím jsi limitovaný je, že se jedná o 8-bitovou hodnotu, tedy maximálně 255.

P.S.: Do programu se vloudila malá chybička, byla opravena 21.5.2022 v 11:07 - pokud si někdo zkopíroval prográmek předtím, zkopírujte si tento.

1 Like