Re: Самодельный локомотивный декодер.
Добавлено: Пн апр 16, 2012 5:19 pm
Для тех кому интересно. Реализация чтения команды (осторожно, ассемблер
)
Последний вариант выглядит примерно так:
1) Настраиваем таймер (например 0-й) с предделителем 8 (пример для Fclk=8МГц)
2) Настраиваем прерывание по перепаду и для этого прерывания пишем следующий обработчик:
3) В главном цикле проверяем флаг DCC_CMD_READY, и если установлен идем в обработчик команд (там сбрасываем флаг и указатель).
Интересно посмотреть другие варианты.
![Mr. Green :mrgreen:](./images/smilies/icon_mrgreen.gif)
Последний вариант выглядит примерно так:
1) Настраиваем таймер (например 0-й) с предделителем 8 (пример для Fclk=8МГц)
2) Настраиваем прерывание по перепаду и для этого прерывания пишем следующий обработчик:
Код: Выделить всё
DCC_READ:
PUSH r16 ;сохраняем R16
IN R16,SREG ;и SREG
PUSH R16
IN r16,TCNT1L ;читаем прошедший интервал (нужно младших 8 бит)
SUBI R16,-32 ;некоторые преобразования
COM R16 ;которые позволяют интервал превратить в соответствующий бит (60 us - 1, 120us - 0)
OUT TCNT1L,ZERO ;обнуляем таймер
SBIC PINA,0 ;реагируем только на каждый 2-й перепад
RJMP I_RET ;остальные игнорируем
BST R16,7 ;сохраняем "результат измерения" в Т
CJNE XL,low(cmd-1),C_START ;если прием команды не был начат, переход на C_START
BRTC BITZERO ;если Т=0, преамбула кончилась, переход на BITZERO
INC BITCOUNT ;иначе считаем "1"-ы
RJMP I_RET ;выходим
BITZERO:CJLO BITCOUNT,12,RESCMD ;если "1"-ц меньше 12, ошибка приема, переход на сброс
LDI XL,low(cmd) ;иначе, переводим указатель на первый адрес команды
RJMP RESBIT ;сброс счетчика битов
C_START:CJEQ XL,low(cmd+7),RESCMD ;если байт>7, слишком длинная команда, переход на сброс
INC BITCOUNT ;увеличиваем биты
CJEQ BITCOUNT,9,BIT9 ;если битов 9, переход на BIT9
LSL CurrByte ;сдвигаем байт
BLD CurrByte,0 ;загружаем в MSB "результат измерения"
RJMP I_RET ;выходим
BIT9: ST X+,CurrByte ;сохраняем байт в ОЗУ
BRTC RESBIT ;если 9-й бит 0, выходим
SBR CON1,(1<<DCC_CMD_READY) ;если нет, ставим флаг что команда принята полностью
RJMP RESBIT ;и выходим
RESCMD: LDI XL,low(cmd-1) ;сброс указателя
RESBIT: CLR BITCOUNT ;и счетчика бит
I_RET: POP R16 ;восстанавливаем R16
OUT SREG,R16 ;и SREG
POP r16
RETI ;выход из прерывания
Интересно посмотреть другие варианты.