rhf-admin писал(а):Код переделанный можно посмотреть? Без кода что-то не очень понятно.
Привожу код, тайминги пока не менял.
Код: Выделить всё
;---------------------------------------------------------
;---------------------------------------------------------
.device ATtiny13
.include "tn13def.inc"
.list
;-- определяем свои переменные
.def w=r16 ; это будет наш аккумулятор
.def T_Cr=r17 ; таймер несущей
.def C_imp=r18 ; счётчик кол-ва импульсов
.def N_bit=r19 ; номер посылаемого бита
.def B1=r20 ; первый байт для передачи
.def B2=r21 ; второй байт для передачи
.def B3=r22 ; третий байт для передачи
.def B4=r23 ; четвёртый байт для передачи
;-- определяем константы
.equ Cr1=12 ; длительность 1 несущей
.equ Cr0=64 ; длительность 0 несущей
.equ Th=239 ; 255-длительность высокого уровня (252)
.equ Tl1=199 ; 255-длительность низкого уровня 1-го бита (242)
.equ Tl0=231 ; 255-длительность низкого уровня 0-го бита (250)
.equ Tsl=213 ; 255-длит-ть низкого уровня в стартовой послед-ти
.equ Tsh=172 ; 255-длит-ть высокого уровня в стартовой послед-ти
.equ MP=10 ; кол-во интервалов для межпакетной паузы
.cseg
.org 0
rjmp Init ; переход на начало программы
;-- вектора прерываний
reti ; INT0
reti ; Pin Change
rjmp Timer ; Timer (переход к обработч.прерывания от таймера)
reti ; EEPROM
reti ; comparator
reti ; timer compare match A
reti ; timer compare match B
reti ; watchdog
reti ; ADC
;-- начало прграммы
Init: ldi w,RAMEND ; устанавливаем указатель вершины
out SPL,w ; стека на старший байт RAM
sbi ACSR,7 ; выключаем компаратор
ldi w,0b00001000 ; определяем входы и выходы порта
out DDRB,w
ldi w,0b11110111 ; включаем подтягивающие резисторы
out PORTB,w ; и определяем начальное состояние выходов
;
;-- Сканирование клавиатуры
Scan: sbis PINB,0 ; если на входе PB4 низкий уровень - нажата КН1
rjmp Form_Com
rjmp Scan
;-- формирование младшего байта пакета
; записываем в третий байт номер команды 4
Form_Com:
ldi r20, 0xff
ldi r21, 0xff
ldi r22, 0xff
ldi r23, 0xff
ldi r24, 0xff
ldi r25, 0xff
ldi r26, 0xff
ldi r27, 0xff
ldi r28, 0x00
;-- Сбрасываем счётчик импульсов, загружаем в таймер время передачи
;-- высокого уровня первого полубита и включаем прерывания от таймера
clr C_imp ; очистить счётчик импульсов
ldi w,Tsh
out TCNT0,w ; загр.в таймер время высокого уровня старт бита
ldi w,0b00000001
out GTCCR,w ; сбросить предделитель
ldi w,0b00000101
out TCCR0B,w ; запустить таймер с делителем на 1024
ldi w,0b00000010
out TIMSK0,w ; разрешить прерывания от таймера
sei ; разрешить немаскированные прерывания
;---------------------------------------------------------
;--- ПОДПРОГРАММЫ ПЕРЕДАЧИ ВЫСОКОГО И НИЗКОГО УРОВНЕЙ ----
;--- передача высокого уровня ----------------------------
Hlevel:
ldi T_Cr,Cr1 ; загрузить длительность импульса
sbi PORTB,3 ; установить 1 на выходе
Cr1_Y:
dec T_Cr
brne Cr1_Y ; точная подстройка частоты несущей
cbi PORTB,3 ; установить 0 на выходе
ldi T_Cr,Cr0 ; длительность паузы в импульсе
Cr0_Y:
dec T_Cr
brne Cr0_Y ; точная подстройка частоты несущей
rjmp Hlevel
;-- передача низкого уровня
Llevel:
nop
rjmp Llevel
;---------------------------------------------------------
;--- ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ ТАЙМЕРА --------------------
Timer:
cbi PORTB,3 ; сбросить выход (флаг переполн.сбросится аппаратно)
pop w ; выгрузить адрес из стека (2 байта),
pop w ; чтобы указатель не сдвигался
ldi w,0b00000000
out TCCR0B,w ; выключить таймер
brts ETransf ; если T=1 - мы отсчитыв.интерв. для межпак.паузы
; если флаг не установлен - передаём данные
tst C_imp ; проверить C_imp на ноль
breq Send_Start0 ; если счётчик равен нулю - переход на Send_Start0
sbrc C_imp,0 ; если нулевой бит сброшен - пропускаем команду
rjmp Send_HL
ldi w,138
cpse C_imp,w ; если счётчик равен 66 - пропускаем следующ.команду
rjmp Send_LL
set ; ставим флаг, означающий, что мы закончили передачу
ldi C_imp,MP ; загружаем в C_imp кол-во интерв.для межпак.паузы
ETransf:
dec C_imp
breq EPause ; если отсчитали MP интервалов - отсчитали паузу
clr w
out TCNT0,w ; обнуляем таймер
ldi w,0b00000101
out TCCR0B,w ; включаем таймер с делителем на 1024
sei
rjmp Llevel ; и нифига не делаем, пока прерывание не случится
EPause:
clt ; сбрасываем флаг T
rjmp Scan
Send_LL:
ld w,X ; читаем в w байт по адресу X
and w,N_bit
brne Send_L1 ; если флаг Z не установился, то передаваемый бит=1
Send_L0:
ldi w,Tl0
out TCNT0,w ; загрузить в таймер время низкого уровня 0-го бита
rjmp Next
Send_L1:
ldi w,Tl1
out TCNT0,w ; загрузить в таймер время низкого уровня 1-го бита
Next: inc C_imp ; увеличить счётчик импульсов
clc ; сбросить флаг переноса
rol N_bit ; сдвинуть влево регистр N_bit
brcc Next2 ; если флаг не установился - переходим
rol N_bit ; ещё раз сдвигаем влево
inc XL ; увеличиваем адрес указателя
Next2:
ldi w,0b00000100
out TCCR0B,w ; включаем таймер с делителем на 256
sei ; разрешаем прерывания
rjmp Llevel
;---------------------------------------------------------
Send_HL:
inc C_imp
ldi w,Th
out TCNT0,w ; загрузить в таймер время высокого уровня бита
ldi w,0b00000100
out TCCR0B,w ; включаем таймер с делителем на 256
sei
rjmp Hlevel
;---------------------------------------------------------
Send_Start0:
inc C_imp
clr N_bit ; очистить регистр N_bit
sbr N_bit,0b00000001 ; и установить в нём нулевой бит
ldi XL,0x14 ; загружаем в XL указатель на регистр r20
ldi w,Tsl
out TCNT0,w ; загр.в таймер время низк.уровня старт.послед.
ldi w,0b00000101
out TCCR0B,w ; включаем таймер с делителем на 1024
sei
rjmp Llevel
;----------------------------------------------------------
Перепрошил еще раз сегодня. Уже не теряет биты последние, но вот шлет неправильный код. И все-таки грешу на то, что влезаю своими байтами даных в регистры пар. Вот заметил, что меняя Х, Y, Z получаю разными последние байты, хотя только последний должен быть нулевым
Код: Выделить всё
111111111111111111111111111111111111111111111 11101011 00011111 11100001 x
111111111111111111111111111111111111111111111 11111111 11111111 11100001 y
111111111111111111111111111111111111111111111 11111111 11111111 11100001 z
Как определяю: имеется собранное на атмеге8515 устройство, что ловит код и потом по USART'у выплевывает мне его в терминалку. Код и схему улавливателя команды могу привести, но в нем-то сомнений нету) Со всех пультов считывает одинаково команды.
Спасибо!