Коды для пультов на attiny13

Здесь обсуждаем устройства на МК и программы для них
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение rhf-admin »

Where is the source code??? (попробуем так)
Все изменения в каком коде? Пример на сайте под PIC, а ты пишешь под AVR.
С уважением, администрация сайта.
xorkrus
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 14 мар 2012, 17:35
Откуда: Тамбов
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение xorkrus »

Прошу прощения, что подзабил на это дело. Не было времени. Попробую все изложить аккуратно.
Итак.
Задача: зашить это в Attiny2313 и чтоб работало.
Код для Attiny13 вот тут был.
Измененный код выглядит так:
код

Код: Выделить всё

;---------------------------------------------------------
.device ATtiny2313
.include "tn2313def.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=22        ; длительность 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         ; кол-во интервалов для межпакетной паузы
                    ; (MP=10 соответствует интервалу около 240 мс)
.equ  AL=0b00000100 ; адрес 04h (заданный младший байт адреса)
.equ  AH=0b11001011 ; адрес CBh (заданный старший байт адреса)
.equ  CMD_1=0x4A    ; код команды 1
.equ  CMD_2=0x4B    ; код команды 2
.equ  CMD_3=0x4C    ; код команды 3
.equ  CMD_4=0x4D    ; код команды 4
;-- Используемые регистры
; GTCCR - управление таймером (обнуление предделителя)
; TCNT0 - регистр таймера
; TCCR0B - управление таймером (биты 0-2: 000 - стоп, 100 - включен с
; делителем на 256, 101 - включен с делителем на 1024)
; TIMSK0 - прерывания от таймера (бит 1=1 - прерывание при переполнении)
; SREG - глобальное разреш.прерываний (бит 7=1 - прерывания разрешены)
;-- начало программного кода
.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      ; и определяем начальное состояние выходов

   ;PD0/PD1-n.c.
   ;PB7-2N2222A-ir
        ldi w,0b10000000 ; определяем входы и выходы порта
        out DDRB,w
   ldi w,0b01111111 ; включаем подтягивающие резисторы
   out PORTB,w      ; и определяем начальное состояние выходов
        ldi w,0b00000000 ; определяем входы и выходы порта
        out DDRD,w
   ldi w,0b00000000 ; включаем подтягивающие резисторы
   out PORTD,w      ; и определяем начальное состояние выходов
        ldi w,0b00000000 ; определяем входы и выходы порта
        out DDRA,w
   ldi w,0b00000000 ; включаем подтягивающие резисторы
   out PORTA,w      ; и определяем начальное состояние выходов

;-- Формируем младший и старший байт адреса
      ldi  B1,AL        ; в первый байт пишем младший байт адреса
      ldi  B2,AH        ; во второй байт - старший байт адреса
;-- Сканирование клавиатуры
Scan: sbis PINB,4       ; если на входе PB4 низкий уровень - нажата КН1
      rjmp Tx_CMD1
      sbis PINB,2       ; если на входе PB2 низкий уровень - нажата КН2
      rjmp Tx_CMD2
      sbis PINB,0       ; если на входе PB0 низкий уровень - нажата КН3
      rjmp Tx_CMD3
      sbis PINB,1       ; если на входе PB1 низкий уровень - нажата КН4
      rjmp Tx_CMD4
      rjmp Scan
;-- формирование младшего байта пакета
Tx_CMD1:
      ldi  B3,CMD_1     ; записываем в третий байт номер команды 1
      rjmp Form_Com
Tx_CMD2:
      ldi  B3,CMD_2     ; записываем в третий байт номер команды 2
      rjmp Form_Com
Tx_CMD3:
      ldi  B3,CMD_3     ; записываем в третий байт номер команды 3
      rjmp Form_Com
Tx_CMD4:
      ldi  B3,CMD_4     ; записываем в третий байт номер команды 4
Form_Com:
      mov  B4,B3        ; записываем в четвёртый байт номер команды
      com  B4           ; инвертируем его
;-- Сбрасываем счётчик импульсов, загружаем в таймер время передачи
;-- высокого уровня первого полубита и включаем прерывания от таймера
      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  TIMSK,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,66
      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
;---------------------------------------------------------
Изменения как я уже говорил минимальны.
По аппаратной части: на PB7 через транзистор висит ИК диод.
Итог: компиляция без проблем. прошивка без проблем. Реакция на нажатие кнопок - отсутствует.
Демократии нет и не будет!
Государство - это я!
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение rhf-admin »

Хм, сам код вроде правильный.

Как определяется что реакции на нажатие кнопок нет? Осциллографом или каким-то интегральным фотоприёмником?
Как выставлены фьюзы? На внутренний генератор или ты в схему внешний кварц на 9,6 МГц поставил?

Камень-то другой. И внутренний генератор у него на другую частоту. Соответственно, если этот код запустить на внутреннем генераторе 2313, то все частоты ИК-импульсов съедут, включая несущую. В этом случае осциллограф будет показывать генерацию посылок (но с неправильными частотами), а фотоприёмник перестанет что-либо видеть (поскольку интегральные фотоприёмники имеют внутри полосовой фильтр и хорошо видят только сигналы на определённой частоте несущей).
С уважением, администрация сайта.
xorkrus
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 14 мар 2012, 17:35
Откуда: Тамбов
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение xorkrus »

Определяется камерой телефона. Для проверки схемы\ИК диода зашивал простой блинк - все светит-моргает. Кварца нет, генератор внутренний ибо все ноги на клавиатуре. Для того собственно и прижимаются все ноги. Фьюзы Low: 0xE4 High: 0xDF
Уплывающая частота, думаю, дело второе. Пока хотя бы заставить вообще работать. Думал может дело в настройках регистров\ног, но если правильно... попробую даташитики поглядеть внимательней.
Демократии нет и не будет!
Государство - это я!
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение rhf-admin »

Насколько я понимаю, запрограммированы фьюзы SPIEN, SUT0, CKSEL3, CKSEL1, CKSEL0.
То есть стоит внутренний генератор на 4 МГц. Попробуй хотя бы на 8 МГц поменять (всё же ближе будет к 9,6).

P.S. А то, что пин PA2 работает как RESET, если его специально не выключить, надеюсь ты учитываешь? Соответственно, его нужно к питанию через резистор пристёгивать, чтобы камень в вечном ресете не висел. Это я к тому, что:
Смысл - прижать все ноги А\Д портов к земле а Б проверять
С уважением, администрация сайта.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение rhf-admin »

Короче, всё, что выше - неверно, я понял в чём косяк. Косяк не совсем в коде, косяк - в таблице прерываний.
У ATTiny13 - всего 10 векторов прерываний, а у ATTiny2313 - 19 штук, да и сами вектора не совпадают. Соответственно, если скомпилить код с таблицей векторов от tiny13 под 2313, то переход по вектору

Код: Выделить всё

rjmp  Timer      ; Timer (переход к обработч.прерывания от таймера)
будет выполняться не при переполнении таймера TIMER0, а от модуля Input Capture Unit, который нам нафиг не нужен и вообще у нас такое событие не запрограммировано. А для переполнения TIMER0 у нас в 2313 используется не 4-й вектор, а 7-й.
Короче, чтобы всё заработало - нужно исправить таблицу векторов. Для 2313 она должна выглядеть так:

Код: Выделить всё

      rjmp Init      ; переход на начало программы
;-- вектора прерываний
      reti           ; INT0
      reti           ; INT1
      reti           ; TIMER1_CAPT
      reti           ; TIMER1_COMPA
      reti           ; TIMER1_OVF
      rjmp Timer     ; переход к обработч.прерывания от таймера. Вот этот вектор как раз TIMER0_OVF
      reti           ; USART0, TX
      reti           ; ANALOG_COMP
      reti           ; PCINT
      reti           ; TIMER1_COMPB
      reti           ; TIMER0_COMPA
      reti           ; TIMER0_COMPB
      reti           ; USI_START
      reti           ; USI_OVF
      reti           ; EE_READY
      reti           ; WDT_OVF
С уважением, администрация сайта.
Аватара пользователя
Virtual2
Читатель
Читатель
Сообщения: 160
Зарегистрирован: 23 май 2016, 22:12

Re: Коды для пультов на attiny13

Сообщение Virtual2 »

2 rhf-admin
пользуй хидеры, не учи людей злу. :ugeek:
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение rhf-admin »

В данном случае это добро. Пусть пока учатся - читают доки на камни. Вот когда научатся - сами догадаются как по-другому написать.
Специально для тебя:

Код: Выделить всё

org 0          ; следующий за этой директивой код начинается по адресу 0
   rjmp Init   ; переход на начало программы
org OVF0addr   ; по адресу вектора переполнения таймера 0
   rjmp Timer  ; переходим на обработчик прерывания от переполнения
org WDTaddr+1  ; следующий код будет сразу за таблицей прерываний
Init: .....    ; начало программы
С уважением, администрация сайта.
xorkrus
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 14 мар 2012, 17:35
Откуда: Тамбов
Контактная информация:

Re: Коды для пультов на attiny13

Сообщение xorkrus »

Пока читал столкнулся с несовпадением таблицы векторов, но осознание не успело дойти до прочтения вашего поста. Вечером попробую и отпишусь о результате.
Демократии нет и не будет!
Государство - это я!
Аватара пользователя
Virtual2
Читатель
Читатель
Сообщения: 160
Зарегистрирован: 23 май 2016, 22:12

Re: Коды для пультов на attiny13

Сообщение Virtual2 »

2 xorkrus
делай как в пр посте с применением хидеров., так буит работать на обоих чипах!.

Код: Выделить всё

.include "tn2313def.inc"
как раз нужен для того дабы не забивать голову картой регистров и векторов ;)
Ответить

Вернуться в «Устройства на микроконтроллерах»