začátky v Bascomu

Funkce **timer **a counter jsou pro mě španělská vesnice, nějak jsem z helpů nepochopil jak to funguje.

poradí někdo jak se pomocí timeru udělá toto:
led na pb0 bude blikat 2Hz, mělo by to nahradit tento kód

do toggle portb.0 waitms 250 loop

Dobře napsaný help je velice užitečná a dobrá věc, ale v tomhle případě se neobejdeš bez pročítání datasheetů. Silně pochybuju, že v helpu najdeš popis registrů a význam jednotlivých bitů. V první řadě si musíš uvědomit co to je a jak pracuje čítač. Čítač je vlastně registr, který počítá od 0 do maxima, pak přeteče do nuly a počítá znova. Kolik je maximum a jak rychle počítá mu můžeš/musíš nastavit Ty. Během čítání pak umí vyvolat přerušení při přetečení (TOVx), při Output Compare (OCRxA, OCRxB) a při Input Capture (ICPx). Input Capture je de-facto externí přerušení a občas ho využívám nezávisle na Timeru. Při vyvolání Input Capture přerušení se automaticky zapisuje stav Timeru do ICP registru pro další zpracování, protože Timer běží dál. S tím samozřejmě souvisí použití přerušení - a zde přichází ke slovu opět datasheety.

A řešení Tvého probému : Nastavit čítač tak, aby přetekl 73,2421875x za sekundu, vytvořit proměnnou a nastavit ji na 18 a spustit čítač. Při přerušení odečíst od proměnné 1 a jakmile dosahne nuly, nastavit ji zpět na 18 a invertovat pin. Dostaneš 2,0345 Hz. Jde to i přesněji, ale ber tohle jako úplný začátek.

Nápověda :
Fmcu = 4,8 MHz
Šířka timeru 8 bitů (256 kroků)
Prescaler 1,8,64,256,1024

Když použiješ prescaler 256, dostaneš

F = Fmcu / kroky timeru / prescaler = 4800000/256/256 = 73,2421875 Hz

Potřebuješ 4 Hz => Fvyst = F / 4 = 73,2421875 / 4 = 18,310546875.
A protože počítáš přetečení časovače, musíš počítat s celýma číslama, tudíž číslo zaokrouhlíš = 18.

Výsledná hodnota je tedy 73,2421875 / 18 = 4,069… Hz => LEDka bliká kmitočtem 2,0345… Hz.

Jak jsem napsal, jde to i přesně, ale tohle je nejjednodušší způsob. Až si osaháš timer a přerušení, můžeš postoupit zase o kousek dál. Většinou to dělám tak, že nastavuji kmitočet přerušení o dost výš, protože ho používám třeba pro multiplexování 7-segmentových LED displejů a při té příležitosti použitím nějaké proměnné generuji i intervaly pro různé blikání apod. Pokud záleží na přesnosti, používám CTC režim timeru, kde si nastavím přetečení timeru tak, abych dostal alespoň výpočtem přesný kmitočet. Ale tím se zatím nezabývej, na to přijde čas později.

Díky za radu ještě bych potřeboval poradit s PWM?
Podle tohoto kódu by měla být funční PWM

[code]
$regfile = “attiny13a.dat”
$Crystal=9600000
$hwstack=32
$swstack=8
$framesize=16

Config Timer0 = Pwm , Prescale = 8 , Compare A Pwm = Clear Up

Config Portb.0 = Output

Defbyte B

Do
For B = 1 To 255
Pwm1a = B
Waitms 20
Next

For B = 255 To 1 Step -1
Pwm1a = B
Waitms 20
Next
Loop

End [/code]
Potřeboval bych, aby kmitočet PWM byl 4kHz a zde jsem se dočetl, že je na to vzorec f PWM = f CLK/(2 * n * TOP), tj. 9600000/(284000)=150.
A teď nevím jestli se použije Icr0=150 nebo Ocr0a=150 a kam to vložit (před a nebo za config timer)

To je špatně.
TOP je maximální hodnota do které timer počítá.
Pro osmibitovou pwm je TOP = 256.

Takže pro
n=1 … fpwm = 18823 Hz
(n=4) … fpwm = 4705 Hz
n=8 … fpwm = 2352 Hz
n=64 … fpwm = 294 Hz

Pro jemnější dělení jde ještě dělit hlavní hodiny příkazem “Config CLOCKDIV”
Pro 4700 Hz potřebuješ dělič 4. Ten v timeru není, tak nastavíš dělič timeru na 1 a dělič hlavních hodin na 4.

[code]$regfile = “attiny13a.dat”
'$crystal = 9600000
$crystal = 2400000

Config Clockdiv = 4 ’ main clock prescaler = 4

Config Portb.0 = Output ’ výstup pwm
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up

Do

  Ocr0a = 25                             'duty cycle 10%
  Wait 2
  Ocr0a = 128                            'duty cycle 50%
  Wait 2
  Ocr0a = 255                            'duty cycle 100%
  Wait 2

Loop

End
[/code]

myslel jsem, že když do toho vzorce dosadím, že TOP bude těch 9600000/(284000)=150 a prescale=8
tak by mělo platit toto

a že to jsou ty 4kHz co potřebuju
a že teda bude stačit někam vložit Ocr0a=150 ale nevím kam to vložit (před a nebo za config timer nebo do hlavní smyčky)

Nebo to takhle nefunguje?

Je to opravdu jinak.
Příkaz “Config timer…” tady nastavuje timer do módu 1 (Phase Correct PWM). V tomto módu je TOP=&hFF a nedá se měnit.

Takže nemůžeš dostat přesně 4 kHz, ale jenom diskrétní hodnoty určené nastavením předděličů, jak jsem uvedl.
Pro velkou většinu aplikací to stačí, protože přesná hodnota f_pwm není až tak důležitá. Důležité je plnění (duty cycle).

Například stmívání nějaké žárovky půjde s f_pwm=100 Hz stejně dobře jako s 50 kHz.
Pro modelářské motory se většinou používají kmitočty 2 - 8 kHz.
Atd.

Dík za vysvětlení, ještě se chci zeptat, jestli mi tohle

Config Clockdiv = 4

nebude mít vliv i na příkaz pulsein, který v tom programu mám ještě použit

Jistěže bude.
Config clockdiv=4 změní $crystal na 2400000 Hz jak je vidět v kódu.
Podle toho nastavíš PULSEIN.