Arduino časování

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
pocitujlasku
Příspěvky: 2764
Registrován: 12 pro 2005, 00:00
Bydliště: SR, Poprad

#16 Příspěvek od pocitujlasku »

mluno, ano, ten milis pouzivam aj ja casto, najma, ked su to veci kde +- desiatky milisekund nehraju rolu. Idealne, ked napr. ked mam viac veci, ktore sa maju periodicky vykonavat v roznych intervaloch. tak si len nahadzem vo while if... a hotovo
No vidis, a tak si sa bal
Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 00:00
Bydliště: Praha

#17 Příspěvek od FHonza »

Používat arduino na takto jednoduchou úlohu je zcela zbytečné. Stačí vzít nejlevnější ATTiny a doslova pár řádků kódu. Příklad je pro ATTiny13, nastaven interní oscilátor na 128kHz.

Kód: Vybrat vše

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 128000

ISR(TIM0_COMPA_vect)
{
   // vola se jednou za sekundu
}


int main(void)
{
  cli();     
  TCNT0 = 0; 
  OCR0A = 124;  // frekvence 1 Hz  ( 128000 / ((124 + 1) * 1024))
  TCCR0A = (1 << WGM01); // CTC 
  TCCR0B = (1 << CS02) | (1 << CS00); // Prescaler 1024     
  TIMSK0 = (1 << OCIE0A); // povoleni preruseni Output Compare Match A
  sei(); 
   
  while (1)
  {
  }
}


Do obsluhy přerušení stačí dopsat požadovanou funkčnost.
Uživatelský avatar
Cowley
Příspěvky: 3557
Registrován: 04 úno 2005, 00:00

#18 Příspěvek od Cowley »

...Po vypnutí PC relé opět sepne na 1sec...


Já jsem nepochopil, kde chce vzít napětí pro 1s impuls po VYPNUTÍ USB. Z nějakého externího zdroje ? nebo z toho akumulátoru ?
Uživatelský avatar
bdn
Příspěvky: 560
Registrován: 16 led 2020, 00:00

#19 Příspěvek od bdn »

funkce millis() vrací unsigned long, což je 4 bytová hodnota. Časem i tady dojde k přetečení. Aby nevznikaly 'falešné zákmity' používá se trik se signed proměnnou. Tam při porovnání 'současné'-'minulé' hodnoty toto nehrozí.

Kód: Vybrat vše

// priklad 
// volani funkce ibn_toggle() automaticky kazdych 1s
// attiny1604

volatile int16_t tcnta_cnt;
int16_t mem_cnt;

// - - - - - -
ISR(TCA0_CMP0_vect)
{
   tcnta_cnt++; // automaticky kazdych 1ms
   BSET(TCA0.SINGLE.INTFLAGS, TCA_SINGLE_CMP0_bm);
}

// - - - - - -
void test_loop( void)
{
   int16_t temp;

   cli();
   temp = tcnta_cnt;
   sei();

   if((signed)(temp-mem_cnt-1000)>=0) // automaticky kazdych 1s
   {
      mem_cnt = temp;
      ibn_toggle();
   }
}

// - - - - - -
int main(void)
{
   /* Initializes MCU, drivers and middleware */
   atmel_start_init();
   sei();
   /* Replace with your application code */
   while (1)
   {
      test_loop();
   }
}

Kód: Vybrat vše

mem_cnt (int16_t)
hex   dec
0x03e8  1000
0x07d0  2000
0x0bb8  3000
.      .
.      .
.      .
0x6d60  28000
0x7148  29000
0x7530  30000
0x7918  31000
0x7d00  32000
0x80e8  -32536 <--přetečení
0x84d0  -31536
0x88b8  -30536
0x8ca0  -29536
.      .
.      .
.      .
0xf618  -2536
0xfa00  -1536
0xfde8  -536
0x01d0  464 <--přetečení
0x05b8  1464
0x09a0  2464
.      .
.      .
.      .
Uživatelský avatar
net
Příspěvky: 205
Registrován: 07 kvě 2004, 00:00

#20 Příspěvek od net »

Děkuji za vaše reakce, nějak jsem to poskládal a zatím vypadá, že to bude fungovat.
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“