Re: Přerušení časovačem na AtMega

Martin Záruba swz na volny.cz
Středa Říjen 11 07:40:43 CEST 2023


To je na mě moc složité, já byl zvyklý programovat především PC i když 
kdysi i sálový počítač v assembleru. Ale tam byl všechno jinak.

Je to Arduino Mega2560. Potřebuji udělat přerušení každých 100uS (Nemusí 
to být přesně a hodilo by se mi, kdybych změnou nějaké konstanty mohl 
zvolit optimální hodnotu někde mezi 60 - 200 uS.

V přerušení bude tato sekvence:


byte hodA[50],hodC[50],hodL[50];

// Obsluha přerušení od časovače Timer/Counter1
ISR(TIMER1_OVF_vect){
for(byte i=0;i<=50;i++){
    PORTA=hodA[i];
    PORTC=hodC[i];
    PORTL=hodL[i];
}
  PORTA=0;
  PORTC=0;
  PORTL=0;
}
To přerušení jsem změřil, že trvá 28uS, takže by na ostatní mělo zbýt 
dost času. I když pole naplním hodnotami, aby vznikl široký pulz, cuká 
to stále, takže osciloskop za to nemůže.

A potřebuji aby alespoň jeden další port byl schopen klasické PWM, 
frekvence celkem není důležitá, vyhovuje cokoli mezi 200 Hz až 1kHz.

Ale hodiny mi běží na 16Mhz, proto těch 10kHz, jinak není šance to 
stihnout.

Já vlastně potřebuji udělat různě široké pulzy na 24 portech s opakovací 
frekvencí cca 5 - 20 kHz. Stačí mi ale 50 kroků. Nic lepšího mě 
nenapadlo, než přerušení časovačem a v obsluze to, co jsem popsal. 
Naplnění, těch polí už je snadné. Funkce je asi jasná, prostě příslušné 
bity prvků pole naplním 1 podle toho, jak dlouhý ten pulz má být. Jkmile 
má skončit, bity až do konce pole [50] jsou nulové.

Ty pulzy mi to generuje a šířka je stabilní, takže je vidět, že 
přerušovací rutina proběhne spojitě, ale pak ta prodleva je nestejná, ač 
by měla být ovlivněna jen nastavením časovače.

Jak mám změnit defaultní nastavení časovače1? To moje nastavení je 
zjevně blbě, ale nevím proč?

Martin Záruba

Dne 11.10.2023 v 0:29 Pavel Hudeček napsal(a):
> https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
> *10.3.1 Default Clock Source *
> The device is shipped with internal RC oscillator at 8.0MHz and with 
> the fuse CKDIV8 programmed, *resulting in 1.0MHz* system clock. The 
> startup time is set to maximum and time-out period enabled. (CKSEL = 
> "0010", SUT = "10", CKDIV8 = "0"). The default setting ensures that 
> all users can make their desired clock source setting using any 
> available programming interface.
>
> Takže "nic nenastavoval" znamená 1 MHz
>
> Pustil jsem wizard c codevisionu, naklikal 1 MHz CLK, mode CTC, 
> přerušení od OCR1A a nechal vygenerovat:
> (Používá jinou syntaxi přerušení, ale zbytek by měl fungovat)
> --------------
> // Timer/Counter 0 initialization
> // Clock source: System Clock
> // Clock value: 1000,000 kHz
> // Mode: CTC top=OCR0A
> // OC0A output: Disconnected
> // OC0B output: Disconnected
> // Timer Period: 0,1 ms
> TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | 
> (1<<WGM01) | (0<<WGM00);
> TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
> TCNT0=0x00;
> OCR0A=0x63;
> OCR0B=0x00;
>
> // Timer/Counter 0 Interrupt(s) initialization
> TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
>
>
> // Timer 0 output compare A interrupt service routine
> interrupt [TIM0_COMPA] void timer0_compa_isr(void)
> {
> // Place your code here
>
> }
> ----------------
> Takhle bych postupoval já, kdybych chtěl přerušení 10 kHz.
>
> Kdybych chtěl fast PWM na 10 kHz a k tomu přerušení, tak:
> // Timer/Counter 0 initialization
> // Clock source: System Clock
> // Clock value: 1000,000 kHz
> // Mode: Fast PWM top=OCR0A
> // OC0A output: Disconnected
> // OC0B output: Non-Inverted PWM
> // Timer Period: 0,1 ms
> // Output Pulse(s):
> // OC0B Period: 0,1 ms Width: 0,049495 ms
> TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | 
> (1<<WGM01) | (1<<WGM00);
> TCCR0B=(1<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
> TCNT0=0x00;
> OCR0A=0x63;
> OCR0B=0x31;
>
> Ale pak je otázka, co teda dělá to Vaše:
> Pokud by to byla opravdu default nastavená 2560, tak by to po tom 
> dělení 64 a ještě 24 mělo dávat 651,... Hz. Není to Arduino, tedy 2560 
> je již nastavená dle Arduino zvyklostí?
>
> Ještě je otázka, jak bylo zobrazeno to
> "cca 100uS ale chaoticky kolísá"
> Protože krátké pulzíky dělají synchronizacím některých osciloskopů 
> potíže. Zkusil bych do toho přerušení dát
> PORTA=~PORTA;
> Pak bude poloviční frekvence a střída 50 %, to snad žádný osciloskop 
> nezkazí.
>
> PH
>
> Dne 10.10.2023 v 21:33 Martin Záruba napsal(a):
>>
>> ATMega2560.
>>
>> Jak zjistím CLK? Nic jiného jsem nenastavoval.
>>
>> Martin Záruba
>> Dne 10.10.2023 v 20:26 Pavel Hudeček napsal(a):
>>> Přerušení se samo zakáže vstupem do jeho obsluhy a samo povolí jejím 
>>> ukončením, takže cli a sei vyhodit.
>>>
>>> Dále by to chtělo vědět, která ATmega, případně i zda/jak má 
>>> nastavené s CLK související fuse bity.
>>>
>>> PH
>>>
>>> Dne 10.10.2023 v 19:52 Martin Záruba napsal(a):
>>>>
>>>> Nastavil jsem
>>>>
>>>>   TCCR1A = 0;// Vynulování registru TCCR1A
>>>>   TCCR1B = 0;// Vynulování registru TCCR1B
>>>>   // Nastavení režimu Fast PWM (TOP = ICR1)
>>>>   TCCR1A |= (1<< WGM11);
>>>>   TCCR1B |= (1<< WGM13)| (1<< WGM12);
>>>>   // Nastavení hodinového děliče na 64 (frekvence časovače = 
>>>> frekvence CPU / 64)
>>>>   TCCR1B |= (1<< CS11)| (1<< CS10);
>>>>   // Nastavení intervalu pro generování přerušení (100 us) - pro 
>>>> frekvenci CPU 16 MHz
>>>>   // ICR1 = (F_CPU / (časový interval * hodinový dělič)) - 1
>>>>   ICR1 = 24;// 100 us při frekvenci CPU 16 MHz a hodinovém děliči 64
>>>>   // Povolení přerušení od časovače Timer/Counter1
>>>>   TIMSK1 |= (1<< TOIE1);
>>>> a rutina přerušení je zatím zcela triviální
>>>> ISR(TIMER1_OVF_vect){
>>>> cli();// Vypnutí globálních přerušení
>>>>  PORTA=0;
>>>>  PORTA=0xFF;
>>>> sei();// Zapnutí globálních přerušení
>>>> }
>>>> Na všech bitech portu A jsou krásné obdélnikové pulzy. Ale perioda 
>>>> vyvolání pulzů je sice cca 100uS ale chaoticky kolísá. Co dělám blbě?
>
>
> _______________________________________________
> HW-list mailing list  -  sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20231011/7d3507bc/attachment.htm>


Další informace o konferenci Hw-list