Hej NG, jeg prøver på at lave en puls-generator. Den skal kunne styres fra en PC og skal kunne kommanderes til at give mellem 0-255 pulser per ms (eller 0-128 per ½ ms eller 0-64 per 1/4 ms, osv). Pulserne skal fordeles jævnt over det ene millisekund (ikke nødvendigvis 100% jævnt, men
Det første jeg tænkte var også at jeg ville bruge MCU'en til det, men jeg tror simpelthen ikke at den kan gøre det hurtigt nok... Hvis jeg skal toggle 6 output-ben 255 gange på et ms uafhængigt af hinanden, samtidig med at jeg også skal have en del cycles i overskud til kommunikation med PC, checksums, osv, tror jeg ikke at det kan gøres (på min 14MHz AVR).
Med 14 MHz får jeg ~27 cycles mellem hver gang jeg skal ændre et ben (når jeg kører 255 pulser/ms); selv uden PC-kommunikation tror jeg ikke at det er nok når jeg skal styre 6 udgange uafhængigt.
Jeg har skam forsøgt (dog ikke implementeret) og talt ca. antal instruktioner, det kommer en del over 27... Husk på at jeg jo ikke bare kan sætte en timer op for hver af de 6 puls-ben, de skal jo køre uafhængigt (bortset fra synkronisering). Men jeg vil da gerne udlove en "dusør" til dig hvis du kan gøre det. :-)
Spec's er ikke særligt præcise og jeg aldrig brugt en AVR til noget, men, ... et 256KHz timer interrupt med det her i er det ikke tæt på at ku' gøre det ? juster på r11 - r16 ...
clr r7 add r1,r11 rol r7 add r2,r12 rol r7 add r3,r13 rol r7 add r4,r14 rol r7 add r5,r15 rol r7 add r6,r16 rol r7
Jeg havde jo ikke regnet med at få en fuld MCU løsning... :-)
Det ser ligegodt ud til at være meget tæt på at kunne lade sig gøre.
clr r7 i andensidste kommando tror jeg ikke er korrekt.
Og man skal også tage højde for at r1-r6 skal clr'es hvert ms(?) samt at interupr-håndteringen også tager et par cycles.
Desuden skal der jo også kommunikeres med PC'en (eller nok mere realistisk med en anden AVR), men timer interruptet har vist højest prioritet (så er spørgsmålet om man kan bruge nestede interrupts i AVR'en).
Men jeg er ligegodt tilbøjelig til at give dig en dusør (nu havde vi jo ikke aftalt noget, men mon ikke vi kan finde på noget :-)).
Takker mange gange, jeg prøver at gå videre med det...
Jeg er faktisk lige ved at tro at det godt kan lade sig gøre... Jeg vender tilbage når jeg har implementeret det, det bliver ret interessant, men der er ingen tvivl om at det kommer til at være trængt... :-)
med de to sidste linier burde du få et 77ns "blip" for hver "roll-over", der ka' nok flyttes rundt på det for at få en puls der er længere. Uden de to linier blir pulsen 1/256ms men så kan du ikke få 256 pulser på et ms
kommer an på hvad du skal bruge, hvis du bare skal bruge frekvenserne behøver du ikke at cleare du kan bare ændre increment værdierne on-the-fly
hvis ikke mcu'en skal bruges til andet ka' du ligeså godt polle uart'en i main loopet det er nok heller ikke realistisk at have flere interrupts, det koster sikkert cycles at komme ind og ud ...
For at løse problemet vil jeg bruge noget ram (F.eks. ATmega8) og simpelhen have en bitmaske af portene i ram, det eneste der så skal gøres er at kopiere en byte fra ram til en port hvert halve msec (dobbelt af max. pulshastighed), det giver 7 clocks per opdatering.
Det kan godt nås hvis det er hovedprogrammet, men ikke i en interrupt rutine:
in SaveStatus,sreg ld r20,X+ andi r20,$fe ;Hold X indenfor 512 bytes out porta,r20 out sreg,SaveStatus reti
Men 103c er for meget... Selv hvis jeg kører AVR'en på 16MHz (men hvis jeg skal bruge den direkte til seriel komm med PC'en bliver jeg nødt til at køre den ved ~14MHz).
OK, nu tror jeg at jeg forstår det. Jeg bliver nok nødt til at sætte et par nop'er ind da udgangen max. må være 2.5 MHz. Men det er der så vidt jeg kan se også masser af tid til.
Jeg har primært brug for at der kommer et helt præcist antal pulser per ms. Men det kan vist ordnes med endnu et register der tæller op til 256 hver gang, og clr'e registrene samt opdaterer de nye når det overløber.
Helt enig... :-) Den skal lave nogle andre småting, men hvis bare ovenstående kan klares i en rimelig procent-del af tiden, bliver der jo en del til overs i main-loopet.
Hvis du ændre hastighed hele tiden, så kan løsningen ikke bruges. Den virker kun hvis du sjældent skifter hastighed. Regenerering af bitmasken tager heller ikke så lang tid, du sørger selvfølgelig for at bruge AND/OR, så du kun ændre den relevante bit.
For hurtige skift i hastigheden er Lasses løsning bedst, men der er du begrænset til 256 trin. Hvis du skal bruge flere trin koster det mere tid (og flere registre).
Jeps, det mente jeg nok. Jeg havde selv prøvet noget lignende i mit andet AVR-forsøg. :-)
Det har jeg også tænkt på, men faktisk tror jeg aldrig at jeg skal bruge mere end ~180 pulser per ms, så der er stadig plads til lidt mere. Og endelig kan man jo ændre interrupt-frekvensen (selvom det så går ud over MCU-load burde der kunne hentes ~50% mere der).
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.