Arduino èasování
Moderátor: Moderátoři
- pocitujlasku
- Příspěvky: 1757
- Registrován: 12 pro 2005, 01:00
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.
Do obsluhy přerušení stačí dopsat požadovanou funkčnost.
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)
{
}
}
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
. .
. .
. .