1/9600 длительность. вот моя подпрограмма вывода:
RSBEG:
push temp2 ;в стек temp2 in temp2,SREG ;сохран статуса push temp2 ;в стек SREG mov temp2,RSDT
;----привязка опроса кнопки к 10000 Гц RSPAUSE:
sbrs TM10000,$0 ;перескочить если бит установлен rjmp RSZ sbrc KEY,RSTEMP ;перескочить если бит сброшен rjmp RSPAUSE ;TM=1, RSTEMP=1 sbr KEY,(1<<RSTEMP) ; rjmp RSSTART ;TM=1, RSTEMP=0 RSZ: sbrs KEY,RSTEMP ;перескочить если бит установлен rjmp RSPAUSE ;TM=0, RSTEMP=0 cbr KEY,(1<<RSTEMP) ; rjmp RSSTART ;TM=0, RSTEMP=1
;переход на передачу происходит только если TM10000,$0 и RSTEMP не равны, ;т.е. по фронту TM10000,$0. для исключения преждевременной передачи, RSTEMP:= TM10000,$0 ; и следующий проход после изменения таймера TM10000.
;-------------------------RS-232
RSSTART:
cpi K,$0 ;start bit brne RS0 ;перейти если не равно cbi PORTB,PB1 ;иначе выдать 0 rjmp RSINC ; RS0: cpi K,$9 ; bit stop1 brne RS9 ;перейти если не равно sbi PORTB,PB1 ; rjmp RSINC ; RS9: cpi K,$A ; bit stop2 brne RSB ;перейти если не равно sbi PORTB,PB1 ; rjmp RSINC ; RSB: cpi K,$B ; brne RS1 ;перейти если не равно clr K cbr KEY,(1<<RSENB) ; rjmp RSSTOP ;выход
RS1: sbrs temp2,$0 ;перескочить если бит 0 установлен rjmp RS11 ;иначе sbi PORTB,PB1 ; lsr temp2 ;логически сдвинуть в право. выстав. след. бит rjmp RSINC ;
RS11: cbi PORTB,PB1 ; lsr temp2 ;логически сдвинуть в право. выстав. след. бит rjmp RSINC ;
RSINC: inc K ; rjmp RSPAUSE
RSSTOP:
;в K считаются биты и он указывает после inc на нужный бит. K=$B - окончание передачи байта. ;байт даных сдвигается в лево. передаеться младший бит. ;по окончанию передачи RSENB & KEYSTAT :=0. пока не передан байт подпрога крутиться
pop temp2 ;SREG out SREG,temp2 ;востанов из стека SREG pop temp2 ;востанов из стека temp2
ret
; вот обработчик прерываний: ;---------------TCM1A обработка прерываний от совпадения TCM1A: ;Match A
push temp2 ;в стек temp2 in temp2,SREG ;сохран статуса push temp2 ;в стек SREG
inc TM10000 ;увеличение значения счетчика по прерыванию cpi TM10000,$64 ;сравнить со 100 $64 brne noe100 ;перейти если не равно inc TM100 ;иначе нарастить 100 Гц счетчик clr TM10000 ;сброс по совпадению
noe100: cpi TM100,$32 ;сравнить со 50 $32 brne noe10 ;перейти если не равно inc TM2 ;иначе нарастить 2 Гц счетчик clr TM100 ;сброс по совпадению
noe10:
rjmp SOEND1
sbrs FLAG,KEYS ; rjmp SOEND1 ;
sbrs TM2,$0 rjmp SOEND1
SO00: sbrs TM10000,$2 rjmp SO10
sbi PORTB,PB1 rjmp SOEND1 SO10: cbi PORTB,PB1 rjmp SOEND1
SOEND1:
pop temp2 ;востан out SREG,temp2 ;востанов стека pop temp2 ;востан temp2
reti вот настройка таймера: ;----------------настройка таймера ;-TCCR1A ;-b7, b6 = 00 - режим OC1A не задействован ;-b5, b4 = 00 - режим OC1B переключения ;-b3 = 0 FOC1A: Force Output Compare Match 1A не использую ;-b2 = 0 ;-b1, b0 = 00 - PWM не использую
ldi temp1,0b00000000 ; out TCCR1A,temp1 ;
;----TCCR1B ;-Bit 7 = 1 - CTC1 очистить таймер после совпадения ;-Bit 6 = 0 - PSR1 ;-Bit 5..4 = 00 reserve ;-Bit 3..0 = 0010 k=2 4*10^6 / 2 / 256 = 7812.5 Гц
ldi temp1,0b10000010 ; out TCCR1B,temp1 ;
;----OCR1A
ldi temp1,T1COMP;значение для прерывания по совпадению out OCR1A,temp1 ;
;----OCR1C
ldi temp1,T1RES ;значение для очиски счетчика out OCR1C,temp1 ;
;------TIMSK ;b7 - - Res ;b6 = 1 OCIE1A: Timer/Counter1 Output Compare Interrupt Enable ;b5 = 0 OCF1B: Output Compare Flag 1B ;b 4..3 - Res ;b2 = 0 TOIE1: Timer/Counter1 Overflow Interrupt Enable ;b1 = 0 TOIE0: Timer/Counter0 Overflow Interrupt Enable ;b0 - - Res
ldi temp1,0b01000000 ; out TIMSK,temp1 ; естественно, это я выдернул из своей программы - надо разбираться в ней. настройку делал меняя значения в настройке счетчика и посылал FF, 00, AA, 55 для побстройки
--------------------
OrCAD, Altium,IAR, AVR....
|