Zdravim Vas, potreboval by som generovat prerusenie kazdu 1us co sa mi pri Fcpu 16Mhz a 8bit casovaci v normalnom rezime nedari, nakolko najnizsiu hodnotu ktoru mozem dosiahnut je 16us(1/Fcpu*2^8). Viem ze existuje moznost kde dokazem nastavit do registra OCR0A hodnotu pri ktorej by sa vyvolalo prerusenie, co by v mojom pripade bola hodnota 16 a vtedy by som mal prerusenie kazdu 1us no nedari sa mi nastavit T0 do rezimu CTC. Vedel by niekto pomoct ako to v bascome nastavit? Samozrejme datasheet som pozeral, viem ze registre maju byt nastavene na WGM01=1, WGM00=0 a ze musim zapisat hodnotu OCR0A = 16 ale aj tak sa mi nedari rozbehnut to. V normalnom rezime mi to na tych 16tich us chodi bezproblemov, no potrebujem kratsi cas. Dakujem
musis mat povolene prerusenie OCIE0A v registri TIMSK0, a napisat pre toto prerusenie obsluhu.
V Bascome nerobim, ale snad som poradil.
Přerušení 1us v BASCOM při 16 MHz? Zbláznil ses? To nemůžeš dosáhnout. I v assembleru bys měl co dělat, abys do toho času vecpal pár instrukcí, a na hlavní program by ani nezbyl čas.
A aky najkratsi cas by bolo podla teba mozne dosiahnut? Nikdy som s tak kratkym casom nerobil tak neviem co ma caka
Těch 16us je pro BASCOM asi tak minimum času na obsluhu přerušení. To je průměrně asi 200 strojových instrukcí. Ale i tak je třeba hlavní smyčku i obsluhu přerušení psát dost úspornou a přerušení bude procesor dost zatěžovat (např. 100 instrukcí na přerušení a 100 na hlavní smyčku).
V preruseni len inkrementujem premenne a na zaklade ich hodnoty potom v hlavnej slucke vyhodnocujem co dalej. Ide mi o to ze potrebujen generovat kratke impulzy (podla potreby 8-10-12…20us) pre spinanie tyristorov a chcel som az sa tato hodnota da nastavit co mozno najpresnejsie(neskor softverovo). Teraz to mam vyriesene pomocou waitov(delay) ale sam vies ze to nieje dobre a uz vobec nie pokial pracujem s tak kratkymi casmi. V niektorych aplikaciach bude 16us v pohode, inde uz to bude velmi dlha doba
No nevím, já bych řekl, že je to naopak. Dlouhé waity v hlavním programu nemají být.
Ale těch pár mikrosekund by většinou nemělo vadit.
No ale mne v hlavnej slucke bezi komparator ktory porovnava pilu s nejakym referencnym napatim a na zaklade toho v akom stave tento komparator je ja hadzem impulzy a teda sa obcas stane ze mi ten impulz ‘‘uleti’’ o tych ± 20us
Udělej přerušení pro komparátor a v něm pošli ten impuls.
Aj tak by to islo, no rozmyslam ze asi skor zacnem uvazovat na nejakou Xmegou. Sice som o nich zatial len cital no vyzeraju pouzitelne. Vdaka dvojnasobnej Fcpu by som mohol s casom ist teoreticky az na 8us co by mi celkom vyhovovalo no a ako dalsie plus je tam rychlejsi AD prevod a zabudovany DA prevodnik. Co hovorite na tieto procesory?
Generuj pulsy raději hardwarově, výstupem z čítače přímo na port. Je to mnohem přesnější a umožní i krátké časy.
Moc som nepochopil ako si to myslel s tym generovanim pulzov, mohol by si mi to prosim upresnit? Ja ale celkovo budem musiet najst iny MCU nakolko by som velmi rad generoval aj vystupny pilovity signal ktory by som vyrabal z obdlznikoveho. S tymto MCU som to robil cez PWM a dostal som sa na max frekvenciu okolo 1,2kHz kedy sa este signal podobal na pilu. Tieto Xmegy co som pozeral tak umoznuju aj vyssi vypoctovy vykon a maju v sebe aj DA prevodnik s ktorym by som sa mozno dostal aj na vyssiu frekvenciu. Treba to asi jedine vyskusat, ked nic ine tak aspon nazbieram skusenosti s tymto svabom
Vykon Xmegy (32MHz) by som v sucasnosti uz ani nebral za relevantny. To za oproti 20MHz pre ATmega nie je take terno, aby sa oplatilo ucit pracu s novym prostredim, atd, atd.
Za cenu nizsiu su k dispozicii STM32F05x (48MHz), STM32F2xx (120MHz), … Ak uz chces prejst na nieco nove tak potom ta namaha za trochu dlhsi cas pre nastudovanie 32b technologie urcite stoji za to a vydrzis s tym do dochodku urcite. A na 32b technologii nemusis samo o sebe nic studovat, Vsetko za Teba aj tak poriesi prekladac C-cka. Jedine co musis nastudovat, je ako pracuju periferie. Ale to je pri kazdej zmene procesora.
Inak pre generovanie pily kludne pouzi ATmega s 8b paralelnym DA prevodnikom. Rychlost dosiahnes daleko vyssiu. Nepises co potrebujes prakticky dosiahnut.
Ak potrebujes generovat pilu, da sa to aj tak, ze si spravis zdroj prudu (jeden OZ, jedna BSS123 a par pasivnych elementov). Referencne napatie mozes generovat tym PWM, ale od jevo velkosti bude zavisiet velkost prudu na vystupe toho prevodnika napatie/prud. No a ked tym prudom budes nabijat kondenzator, tak na nom bude prakticky pekna hrana s uhlom sklonu podla velkosti toho prudu. Po dosiahnuti nejakej zelanej hranice kondenzator kratkym pulzom skratni a dej sa Ti bude opakovat. A mas generator pily s premenlivou frekvenciou ako vysity. Ked pouzijes DA, aj tak sa nejakym dalsim suciastkam nevyhnes ako je urcite OZ a par dalsich pasivnych elementov. Toto je o nieco komplikovanejsie, ale fakt ze len o nieco.
Nevím, co všechno potřebuješ, protože z diskuze nejsem úplně moudrej. Napsal jsem Ti příklad, jak generovat pulzy pomocí časovače. Jen mám trošku obavu, jestli dokážeš dosahnout takovouhle přesnost v BASCOMu.
;==============================================================================
; Generování impulzu pro tyristory
; Délka impulzu 1-128 us
; Odchylka délky pulzu max. +4 takty MCU v případě,
; že nebude použito žádné jiné přerušení
; Fmcu = 16 MHz
;==============================================================================
#include <m644def.inc>
;------------------------------------------------------------------------------
; Definice registrových proměnných
.def Temp=R16 ; Pomocná proměnná
.def Temp2=R17 ; Pomocná proměnná pro přerušení
;------------------------------------------------------------------------------
; Definice konstant
#define Tyristor_PORT portb
#define Tyristor0 0
#define Tyristor1 1
#define Tyristor2 2
#define Tyristor3 3
#define Tyristor4 4
#define Tyristor5 5
#define Tyristor6 6
#define Tyristor7 7
#define Delka_Pulzu_us 1 ; Požadovaná délka impulzu v us (1-128)
;------------------------------------------------------------------------------
; Definice paměťových proměnných
.dseg
SRAM_Tyristory: .byte 1 ; Sem se ukládá, které tyristory se mají zapnout
SRAM_Delka_Pulzu: .byte 1 ; Sem se ukládá vypočtená hodnota pro požadovanou délku impulzu
;------------------------------------------------------------------------------
; Tabulka skoků
.cseg
.org 0
rjmp RESET ; Reset Handler
rjmp INT0_INT ; External Interrupt Request 0
rjmp INT1_INT ; External Interrupt Request 1
rjmp INT2_INT ; External Interrupt Request 2
rjmp PCINT0_INT ; Pin Change Interrupt Request 0
rjmp PCINT1_INT ; Pin Change Interrupt Request 1
rjmp PCINT2_INT ; Pin Change Interrupt Request 2
rjmp PCINT3_INT ; Pin Change Interrupt Request 3
rjmp WDT_INT ; Watchdog Time-out Interrupt
rjmp TIMER2_COMPA ; Timer/Counter2 Compare Match A
rjmp TIMER2_COMPB ; Timer/Counter2 Compare Match B
rjmp TIMER2_OVF ; Timer/Counter2 Overflow
rjmp TIMER1_CAPT ; Timer/Counter1 Capture Event
rjmp TIMER1_COMPA ; Timer/Counter1 Compare Match A
rjmp TIMER1_COMPB ; Timer/Counter1 Compare Match B
rjmp TIMER1_OVF ; Timer/Counter1 Overflow
rjmp TIMER0_COMPA ; Timer/Counter0 Compare Match A
rjmp TIMER0_COMPB ; Timer/Counter0 Compare match B
rjmp TIMER0_OVF ; Timer/Counter0 Overflow
rjmp SPI_STC ; SPI Serial Transfer Complete
rjmp USART0_RX ; USART0 Rx Complete
rjmp USART0_UDRE ; USART0 Data Register Empty
rjmp USART0_TX ; USART0 Tx Complete
rjmp ANALOG_COMP ; Analog Comparator
rjmp ADC_INT ; ADC Conversion Complete
rjmp EE_READY ; EEPROM Ready
rjmp TWI_INT ; two-wire Serial Interface
rjmp SPM_READY ; Store Program Memory Ready
rjmp USART1_RX ; USART1 Rx Complete
rjmp USART1_UDRE ; USART1 Data Register Empty
rjmp USART1_TX ; USART1 Tx Complete
rjmp TIMER3_CAPT ; Timer/Counter3 Capture Event
rjmp TIMER3_COMPA ; Timer/Counter3 Compare Match A
rjmp TIMER3_COMPB ; Timer/Counter3 Compare Match B
rjmp TIMER3_OVF ; Timer/Counter3 Overflow
;------------------------------------------------------------------------------
; Rutiny obsluhy přerušení
TIMER3_COMPA: ; Timer/Counter3 Compare Match A
; Z nějakého záhadného důvodu v simulátoru AVR Studia skáče Timer 0 Compare Match A
; na adresu Timer 3 Compare Match A
; Proto je tu i tento jinak nepoužitý vektor přerušení, který má pouze MCU ATmega1284.
; MCU na vyzkoušení nemám.
TIMER0_COMPA: ; Timer/Counter0 Compare Match A
ldi Temp2, 0
out Tyristor_PORT, Temp2 ; Vypnout všechny tyristory
out TCCR0B, Temp2 ; Zastavit čítač
out TCNT0, Temp2 ; Vynulovat čítač
reti
;------------------------------------------------------------------------------
; Nepoužité vektory přerušení
INT0_INT: ; External Interrupt Request 0
INT1_INT: ; External Interrupt Request 1
INT2_INT: ; External Interrupt Request 2
PCINT0_INT: ; Pin Change Interrupt Request 0
PCINT1_INT: ; Pin Change Interrupt Request 1
PCINT2_INT: ; Pin Change Interrupt Request 2
PCINT3_INT: ; Pin Change Interrupt Request 3
WDT_INT: ; Watchdog Time-out Interrupt
TIMER2_COMPA: ; Timer/Counter2 Compare Match A
TIMER2_COMPB: ; Timer/Counter2 Compare Match B
TIMER2_OVF: ; Timer/Counter2 Overflow
TIMER1_CAPT: ; Timer/Counter1 Capture Event
TIMER1_COMPA: ; Timer/Counter1 Compare Match A
TIMER1_COMPB: ; Timer/Counter1 Compare Match B
TIMER1_OVF: ; Timer/Counter1 Overflow
TIMER0_COMPB: ; Timer/Counter0 Compare match B
TIMER0_OVF: ; Timer/Counter0 Overflow
SPI_STC: ; SPI Serial Transfer Complete
USART0_RX: ; USART0 Rx Complete
USART0_UDRE: ; USART0 Data Register Empty
USART0_TX: ; USART0 Tx Complete
ANALOG_COMP: ; Analog Comparator
ADC_INT: ; ADC Conversion Complete
EE_READY: ; EEPROM Ready
TWI_INT: ; two-wire Serial Interface
SPM_READY: ; Store Program Memory Ready
USART1_RX: ; USART1 Rx Complete
USART1_UDRE: ; USART1 Data Register Empty
USART1_TX: ; USART1 Tx Complete
TIMER3_CAPT: ; Timer/Counter3 Capture Event
TIMER3_COMPB: ; Timer/Counter3 Compare Match B
TIMER3_OVF: ; Timer/Counter3 Overflow
reti
;------------------------------------------------------------------------------
; Hlavní program - inicializace MCU
RESET:
ldi Temp,high(RAMEND)
out SPH,Temp
ldi Temp,low(RAMEND)
out SPL,Temp
ldi XH, high(SRAM_SIZE)
ldi XL, low(SRAM_SIZE)
ldi YH, high(SRAM_START)
ldi YL, low(SRAM_START)
clr temp
Init_RAM:
st Y+, temp
sbiw XL, 1
brne Init_RAM
clr r0
clr r1
clr r2
clr r3
clr r4
clr r5
clr r6
clr r7
clr r8
clr r9
clr r10
clr r11
clr r12
clr r13
clr r14
clr r15
clr r16
clr r17
clr r18
clr r19
clr r20
clr r21
clr r22
clr r23
clr r24
clr r25
clr r26
clr r27
clr r28
clr r29
clr r30
clr r31
out SREG, r0
; Hlavní program - konec inicializace MCU
;------------------------------------------------------------------------------
; Hlavní program
rcall Inicializace_Citace_A_Portu
sei ; Povolit přerušení
Temp, (1<<Tyristor0)|(1<<Tyristor3) ; Zapnout tyristory 1 a 3
sts SRAM_Tyristory, Temp ; Sem se ukládá, které tyristory se mají zapnout
ldi Temp, Delka_Pulzu_us*2-1 ; Vypočítat hodnotu OCIE0A pro požadovanou délku impulzu
sts SRAM_Delka_Pulzu, Temp ; Sem se ukládá hodnota OCIE0A pro požadovanou délku impulzu
rcall Start_Impulzu
Hlavni_Smycka:
rjmp Hlavni_Smycka
;------------------------------------------------------------------------------
Inicializace_Citace_A_Portu:
ldi Temp, 0
out TCNT0, Temp ; Vynulovat čítač
out TCCR0A, Temp ; Nastavit normální režim čítače
out TCCR0B, Temp ; Nastavit normální režim čítače, NESPOUŠTĚT ČÍTAČ
ldi Temp, 255
out TIFR0, Temp ; Pro jistotu vynulovat všechny příznaky přerušení
ldi Temp, (1<<OCIE0A)
sts TIMSK0, Temp ; Povolit přerušení při překročení hodnoty v OCIE0A
ldi Temp, 0
out Tyristor_PORT, Temp ; Vynulovat port (pokud jsou tyristory zapínané log. 1)
ldi Temp, 255
out ddrb, Temp ; Nastavit port jako výstupní
ret
;------------------------------------------------------------------------------
Start_Impulzu:
lds Temp, SRAM_Delka_Pulzu ; Načíst z RAM délku impulzu
out OCR0A, Temp
ldi Temp, (1<<CS01)
out TCCR0B, Temp ; Spustit čítač - Prescaler=8
; Počkat 4 takty mcu kvůli synchronizaci
nop
nop
nop
nop
lds Temp, SRAM_Tyristory ; Načíst z RAM které tyristory se mají zapnout
out Tyristor_PORT, Temp ; Zapnout tyristory
ret
;------------------------------------------------------------------------------
Prográmek je psaný v AVR Studiu.
Před dalším zapnutím jiného nebo jiných tyristorů musíš počkat, než dojde k vypnutí těch zapnutých - neboli než se ukončí cyklus. U délky pulzu 1 us to není až takový problém, protože od zapnutí do vypnutí procesor vykoná max. 16 instrukcí (včetně instrukce ret a části přerušovacího vektoru do vypnutí tyristorů), takže času na ostatní věci je opravdu minimum, ale u delších impulzů by bylo potřeba tohle ještě ošetřit.
Šlo by to třeba takhle :[code]
Start_Impulzu:
in Temp, Tyristor_PORT ; Načíst stav portu tyristorů
tst Temp ; Test na nulu
brne Start_Impulzu ; Není-li port nulový, opakovat
lds Temp, SRAM_Delka_Pulzu ; Načíst z RAM délku impulzu
out OCR0A, Temp
ldi Temp, (1<<CS01)
out TCCR0B, Temp ; Spustit čítač - Prescaler=8
; Počkat 4 takty mcu kvůli synchronizaci
nop
nop
nop
nop
lds Temp, SRAM_Tyristory ; Načíst z RAM které tyristory se mají zapnout
out Tyristor_PORT, Temp ; Zapnout tyristory
ret
;------------------------------------------------------------------------------ [/code]
Zavoláš rutinu pro spuštění pulzu a ta čeká, dokud je některý z tyristorů zapnutý.
V Ccku nerobim, ale ako vidim tak coskoro budem musiet na to prejst lebo sem tam sa vyskytne zapojenie ako teraz kde uz Basic nestaci. Samozrejme ale dakujem za kod a skusim si ho vecer prejst a pokusit sa pochopit ako si to myslel. Konkretne ide o riadenie tyristoroveho striedaca, tzn budem potrebovat generovat dva impulzy s urcitou dlzkou(10-25us) a samozrejme s urcitou frekvenciou. Ono je to na dlhe pisanie a takto cez net sa to ani poriadne neda vysvetlit co vsetko tam vlastne bude a hlavne ako to ma fungovat lebo je tam toho viacero aj ked viem ze zasa pre Vas je tazko mi radit ked neviete o co ide. V podstate 80% si dokazem spravit aj sam, akurat toto generovanie casu mi robi problem + generovanie piloveho signalu ale skusim to s tym operakom a prudovym zdrojom, to znie ako velmi dobry napad no treba si to vyskusat. Ale aj tu xmegu by som si rad skusil, hlavne tie DA prevodniky, s tym som este nemal tu cest pracovat a ked nic ine tak aspon sa zasa cosi naucim, na skodu to urcite nebude
Jenom drobnost - to není Cčko, ale Assembler …
Cčko má podobný problém jako BASCOM. Nevíš přesně, co všechno tam kompiler přihodí za bižuterii, takže je hodně těžké udělat tak přesné časování jako právě v Assembleru, kde co napíšeš, to se zkompiluje a nic se k tomu nepřilepí.
No jasne, somar pozrel som si zaciatok kde bolo include a define a to viem ze sa pouziva aj v Ccku, takze sa ospravedlnujem …na asm si zatial veru netrufam, ale raz mozno…no nic skusim este cosi vymysliet, skusim tu xmegu, pripadne nejaky 32b no a uvidi sa co dalej. Zatial Vam vsetkym velmi pekne dakujem za cas a ochotu, no a ked sa posuniem niekde dalej tak sa urcite ozvem
Tak po dlhsej dobe som opat spat, akurat som skusil na moju M644ku pripojit DA prevodnik TLC7226 a generovat s nim pilu. Pri vyske pily cca. 3,5V som sa dostal na f=2kHz co oproti PWMke nieje ziadna vyhra, snad jedine plus je ze nemusim pri zmene frekvencie menit RC clen a nemusim mat zapojeny vybijaci tranzistor paralelne s kapacitou
Obecně řečeno - na některé úlohy programově ani poměrně rychlé MCU nestačí a řeší se to integrovaným HW případně externím HW (PLD, CPLD, FPGA) jako jsou pole čítačů/komparátorů + DMA a podobně.
Z diskuze jsem nijak zvlášť nepochopil co je cílem Tvého snažení, ale někdo Ti tu radil rodinu ARM STM32F/L ( z osmibitů je ještě celkem schopná rodina 80C51F) tak si prostuduj a napasuj svoje požadavky na vhodný MCU