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ý.