Zdravim Vas, potreboval by som vyrobit zariadenie ktore bude generovat obdlznikovy signal s rozsahom frekvencie cca. 1-20kHz pricom tato frekvencia ma byt laditelna potenciometrom. Ma niekto nejaky napad ako to zrealizovat pomocou MCU ? Napadlo ma skusit to PWMkou len neviem ci by to bol dobry napad. Dakujem
PS: pre uplnost, touto frekvenciou sa bude riadit vykonovy IGBT, ktory bude spinat LC clen a zmenou frekvencie sa bude tento obvod ladit do rezonancie
Nacitaj hodnotiu z AD na ktoey privedies napatie z potenciometra - trivialnost popisana v datasheete.
K nacitanej hodnote z AD pripocitaj konstantu (tu si vypocitas na zaklade najvyssej frekvencie ktoeu chces dosiahnut). Maximalna vystupna hodnota ma zodpovedat najnizssej frekvencii. hodnotu vloz do 16b caspvaca (OCx) ktory je nastaveny v mode generovania frekvencie 1:1 nacitanim impulzov do hodnoty predvolby OCx.
Tiez trivialnost popisana v datasheete. Priklady su ale v ASM alebo v C. Bascom je urcite okrajovejsi zaner
Pro generování obdélníků se používá timer v módu CTC.
V datašítu v tabulce “Waveform Generation Mode Bit Description” se podívej jak se nastavují módy čítače pomocí bitů WGMxx v registrech TCCRxA a TCCRxB.
[code]$regfile = “m88def.dat”
$crystal = 8000000
$hwstack = 128
$swstack = 64
$framesize = 64
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Timer1 = Timer , Prescale = 1
Set Tccr1b.wgm12 'mód 4 - CTC, TOP=OCR1A
Set Tccr1a.com1a0 'invertuj výstup při shodě
'změnou OCR1A měníme frekvenci podle vzorce
'OCR1A = F_CPU[Hz] / (2 * frekvence[Hz] * prescaler) - 1
'Ocr1a = 3999 '1000 Hz
'Ocr1a = 199 '20000 Hz
Dim Adc_value As Word
Dim Ocr_value As Long
'výstup = OC1A = portb.1
Set Ddrb.1
Do
'Adc_value = Getadc(0) 'pin ADC0
' přepočítej Adc_value takto:
' Adc_value = 0 ...... Ocr_value = 199
' Adc_value = 1023 ... Ocr_value = 3999
'
' a vlož do OCR1A
Ocr1a = Ocr_value
Loop
End
[/code]
Ospravedlnujem sa za vypadok ale bol som dlhsi cas mimo, no teraz sa vraciam k teme. Dakujem za tip ale podla toho co si napisal mi to nechodi. Mozno robim niekde chybu, preto pripajam moju upravenu verziu ktoru som spravil podla tvojho vzoru:
Skusal som do programu vlozit aj odstartovanie ADC a TIMER1 a podobne veci, pozeral som aj nejake ine fora no nic taketo som nenasiel
Tvůj kód nejde ani přeložit, protože používáš desetinnou čárku místo tečky.
Set Tccr1b.wgm02
[/code]má být [code]
Set Tccr1b.wgm12
Piš do kódu i $hwstack, $swstack a $framesize.
Adc a timery se nastartují už příkazem Config…
Pro první test můžeš zkusit bez Adc:
Do
OCR1A = 1000
Loop
Měl bys dostat na výstupu tón asi 1 kHz.
Tomu s tou ciarkou a bodkou som trocha nepochopil, nakolko tam bodku/tecku mam a s ciarkou by podla mna ani korektne nepresla kompilacia. Skusal som to samozrejme aj tak ze som mu zadal natvrdo hodnotu no vysledok bol rovnaky. Mozem skusit zapisal do kodu aj $hwstack, $swstack a $framesize no myslim ze v tom problem nebude
Já tam vidím čárku
Ocr_value = Adc_value * 3,905
A ještě musíš nastavit pin OC1A jako výstup.
Jasne to mas pravdu ja som myslel ze mam ciarku v prikaze
Problem uz je z casti vyrieseny za co dakujem a chybu som spravil v tom ze som neoznacil PD5(OC1A) ako vystup. Problem ktory ale stale mam je ten ze som si chcel nasimulovat zmenu frekvencie v rozsahu 1-10kHz. Pociatocna frekvencia je, po vynasobeni hodnoty z AD0 mojou konstantou, spravna ale nedokazem nastavit hornu hranicu, teda aby pri napati na AD0=5V bolo na vystupe tych 10kHz. Prevodnik je 10bit, tzn. mal by pracovat v rozsahu 0-1023 kde 0=0V a 1023=5V ak tomu spravne rozumiem. Mne vsak frekvencia ide od 1kHz do maximalnej (taktovacej?) frekvencie. Ako by som dokazal nastavit tuto hornu hranicu? Dakujem
PS: prikaz ‘‘Start ADC’’ som musel pouzit nakolko bez tohoto prikazu som mal pociatocnu hodnotu na ADC0=1023
Je to naopak. Čím vyšší napětí, tím nižší kmitočet.
Podívej se znovu na můj kód. Je tam vzorec pro výpočet hodnoty OCR1A pro požadovanou frekvenci.
Pro 10 kHz vychází OCR1A = 400
Pro 1 kHz OCR1A = 4000 (zaokrouhleno)
Takže musíš upravit přepočet adc_value takto:
Při adc_value = 0 bude hodnota OCR1A = 400
Při adc_value = 1023 bude hodnota OCR1A = 4000
Postup určitě zvládneš sám. Je to trojčlenka z osmé třídy.
Nie je to nahodou tak, ze cim vyssie cislo v OCR1A tak tym je frekvencia NIZSIA?
Takze vzorec by mal vyzerat nejako takto
OCR1A = K1 - K2 *AD;
kde:
AD je hodnota z AD v rozsahu 0 -1023
K1 je predvolba pre minimalnu frekvenciu (PpMINF)
K2 = (K1 - PpMAXF)/1023; // PpMAXF je predvolba pre maximalnu frekvenciu
Je to tak, ze cim je hodnota v OCR1A vyssia tak tym je frekvencia nizsia a preto mi to aj robi problem ktory popisujem nakolko som si myslel ze je to opacne a teda ze staci hodnotu z AD0 vynasobit nejakou konstantou a mam to. Tvoj vzorec vyzera byt spravny ked som si to skusil na papiery prepocitat takze by to mohlo fungovat no ozvem sa az ked budem doma a skusim to v realnom zapojeni
Tak vcera som program upravil a pouzil som vyssie uvedeny vzorec a teraz vsetko bezi tak ako ma. Problem na ktory som narazil je ze pokial pouzijem na prepocet cislo 0.xxxx tak nedokazem menit frekvenciu. Vyzera to ze v OCR1A je ulozena jedna hodnota(K1) a bascom ma pravdepodobne problem s vypoctom. Vyriesil som to tak ze tuto hodnotu som vynasobil nejakym cislom tak aby bolo >1 a tymto istym cislom som ho potom vydelil priamo v OCR1A a potom to chodi bez problemov. Takze dakujem Vam vsetkym za rady a cas
OCR1A urcite nie je zavedene na floating point aritmetiku.
Only uint8/uint16 please
To som nevedel, ale na druhej strane ak bolo cislo nad 1 tak desatinna ciarka mohla byt pouzita a chodilo to avsak neviem ci bralo do uvahy aj to co bolo za nou:)
Samozrejme ze nie. Do OCR vkladas cislo s ktorym sa porovnava stav citaca. Ako Ta mohlo napadnut ze citac pocita vo floating? Co by si pri kazdom impulze do citaca pripocitaval desatinu cisla, tisicinu, ci miliontinu?
Jeden impulz je predsa 1, dva impulzy 2, tri impulzy 3, …
takze preto cele cislo.
Tak takto som nad tym neuvazoval a pritom je to uplne logicke ze to nemoze byt float Dakujem Vam este raz vsetkym za pomoc a cas