Бегущий огонек на ATtiny2313 с переключением эффектов :)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Бегущий огонек на ATtiny2313 с переключением эффектов :)

Сообщение C0oo1D »

У меня возникла проблема, когда пытался адаптировать урок "Переключение между массивами. Б.О. v2.2". Ниже представил код уже полученной и глюченной программы.. выделил для работы еще 2 регистра, хотя было бы достаточно одного.. Но для начала решил сделать с двумя, лишь бы работало.
Еще думаю что код очень не оптимизирован.. Так же хочется знать, нельзя-ли писать в массивах не 8 битами а 15? (что-бы обрабатывались сразу 2 порта).. массивы специально не переводил в десятиричную систему, для удобства. Код ниже, строго не судите - я пока-что новичок и в МК и в Ассемблере :)

Ошибка, как я понял, по метке "ReadArray"
Забыл написать! Цель этой адаптации - задействовать порт D :)

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

.include "D:\Other\AVR\avrasm\APPNOTES\tn2313def.inc"

.def     Temp=R16
.def     Temp1=R17
.def     Temp2=R18
.def     Temp3=R19
.def     Temp4=R20
.def     ResCnt=R20

.cseg
.org 0


rjmp Reset
rjmp INT_0
rjmp INT_1
rjmp Timer1_capt1
rjmp Timer1_comp1
rjmp Timer1_OVF1
rjmp Timer0_OVF0
rjmp UART_RX
rjmp UART_UDRE
rjmp UART_TX
rjmp ANA_COMP

;Reset:
INT_0:
INT_1:
Timer1_capt1:
;Timer1_comp1:
Timer1_OVF1:
Timer0_OVF0:
UART_RX:
UART_UDRE:
UART_TX:
ANA_COMP:
          reti
;****************************************************************************************
;* ИНИЦИАЛИЗАЦИЯ                                                                        *
;****************************************************************************************
Reset:    ldi Temp1,0             ;Анти-дребезг
          ldi Temp2,0             ;----------
l_res:    dec Temp1               ;----------
          brne l_res              ;----------
          dec Temp2               ;----------
          brne l_res              ;----------
         
          inc ResCnt              ;инкремент счетчика сбросов

          ldi Temp,0b11111111     ;настройка портов
          out DDRB,Temp           ;----------
          ldi Temp,0b1111111      ;----------
          out DDRD,Temp           ;----------

          ldi Temp,0b01000000     ;разрешить прерывание компаратора
          out TIMSK,Temp          ;----------

          ldi Temp,0b00000010     ;тактовый сигнал = CK/8
          out TCCR1B,Temp         ;----------

          ldi Temp,0x4C           ;инициализация компаратора
          out OCR1AH,Temp         ;----------
          ldi Temp,0x4B           ;----------
          out OCR1AL,Temp         ;----------

          ldi Temp,RamEnd         ;установка указателя стека
          out SPL,Temp            ;----------

          ldi Temp1,0             ;инициализация индикатора
          ldi Temp2,0             ;----------

          ldi Temp,0              ;обнуление таймера
          out TCNT1H,Temp         ;----------
          out TCNT1L,Temp         ;----------

          sei                     ;разрешить прерывания
;****************************************************************************************
;* ОСНОВНОЙ ЦИКЛ                                                                        *
;****************************************************************************************
Inf:   rjmp Inf                    ;бесконечный цикл


;****************************************************************************************
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА                                                    *
;****************************************************************************************
Timer1_comp1:
         ldi Temp,0               ;обнуление таймера
         out TCNT1H,Temp          ;----------
         out TCNT1L,Temp          ;----------


SelectArray:                      ;выбор массива

         andi ResCnt,0b00000011   ;отсечка лишних разрядов сч. сбросов

         cpi ResCnt,0             ;сравнение счетчика сбросов с конст.
         brne Tst1                ;если не равно - след. проверка
         ldi ZH,High(ArrayB0*2)   ;загрузка начального адреса массива
         ldi ZL,Low(ArrayB0*2)    ;----------
         ldi YH,High(ArrayD0*2)   ;----------
         ldi YL,Low(ArrayD0*2)    ;----------
         rjmp ReadArray

Tst1:    cpi ResCnt,1
         brne Tst2
         ldi ZH,High(ArrayB1*2)
         ldi ZL,Low(ArrayB1*2)
         ldi YH,High(ArrayD1*2)
         ldi YL,Low(ArrayD1*2)
         rjmp ReadArray

Tst2:    cpi ResCnt,2
         brne Tst3
         ldi ZH,High(ArrayB2*2)
         ldi ZL,Low(ArrayB2*2)
         ldi YH,High(ArrayD2*2)
         ldi YL,Low(ArrayD2*2)
         rjmp ReadArray

Tst3:    ldi ZH,High(ArrayB3*2)
         ldi ZL,Low(ArrayB3*2)
         ldi YH,High(ArrayD3*2)
         ldi YL,Low(ArrayD3*2)
         rjmp ReadArray


ReadArray:

         ldi Temp,0               ;прибавление относит. адреса
         ldi Temp3,0              ;----------
         add ZL,Temp1             ;----------
         adc ZH,Temp              ;----------
         add YL,Temp2             ;----------
         adc YH,Temp3             ;----------

         lpm R0,Z                     ;загрузка из ПЗУ
         ld R1,Y                 ;----------

         mov Temp,R0              ;копирование в РОН
         mov Temp3,R1             ;----------
         cpi Temp,0               ;пороверка на нулевой элемент
         breq Init                ;если да - инициализация
         inc Temp1                ;увеличение относит адреса на 1
         inc Temp2
         rjmp Output              ;перейти на вывод в порт
         
         

Init:    ldi Temp1,0              ;вернутся к выбору массива
         ldi Temp2,0              ;----------
         rjmp SelectArray         ;----------

Output:  out PortB,Temp           ;вывод в порт
         out PortD,Temp3          ;----------
         
         reti                     ;выход из обработчика



ArrayB0:
.db  0b10000000,0b01000000,0b00100000,0b00010000
.db  0b00001000,0b00000100,0b00000010,0b00000001
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0,0

ArrayB1:
.db  0b00000001,0b00000010,0b00000100,0b00001000
.db  0b00010000,0b00100000,0b01000000,0b10000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0,0

ArrayB2:
.db  0b10000001,0b01000010,0b00100100,0b00011000
.db  0b00011000,0b00100100,0b01000010,0b10000001
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0,0

ArrayB3:
.db  0b10000000,0b01000000,0b00100000,0b00010000
.db  0b00001000,0b00000100,0b00000010,0b00000001
.db  0b00000001,0b00000010,0b00000100,0b00001000
.db  0b00010000,0b00100000,0b01000000,0b10000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000,0b00000000,0b00000000
.db  0b00000000,0b00000000
.db  0,0
ArrayD0:
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b1000000,0b0100000,0b0010000,0b0001000
.db  0b0000100,0b0000010,0b0000001,0b0000000
.db  0,0

ArrayD1:
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000001,0b0000010,0b0000100,0b0001000
.db  0b0010000,0b0100000,0b1000000,0b0000000
.db  0,0

ArrayD2:
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b1000001,0b0100010,0b0010100,0b0001000
.db  0b0001000,0b0010100,0b0100010,0b1000001
.db  0,0

ArrayD3:
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b0000000,0b0000000,0b0000000,0b0000000
.db  0b1000000,0b0100000,0b0010000,0b0001000
.db  0b0000100,0b0000010,0b0000001,0b0000001
.db  0b0000010,0b0000100,0b0001000,0b0010000
.db  0b0100000,0b1000000
.db  0,0

Спасибо заранее :)
Последний раз редактировалось C0oo1D Ср фев 04, 2009 16:30:15, всего редактировалось 1 раз.
Реклама
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

Что, никто не может ответить на этот вопрос??? По-моему он далеко не сложный.. На форуме задают гораздо сложнее как я посмотрю...
Реклама
Cat_CooLeR
Опытный кот
Сообщения: 732
Зарегистрирован: Пт авг 22, 2008 16:59:43
Контактная информация:

Сообщение Cat_CooLeR »

Непонял. Какой именно вопрос.. тут я его не увидел, то ли не понял, хотя на этот вопрос отвечу:
Так же хочется знать, нельзя-ли писать в массивах не 8 битами а 15?

Нет, так как "Порт – это пачка однобитных каналов" (в обучалке и написано). Если в порту 8 каналов, туда не пошлешь 15... Его нужно отдельно.
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Re: Как применить массив к двум портам?

Сообщение C0oo1D »

ну, в общем, если проще - хотел сделать бегущую дорожку на 15 светодиодов, с использованием массивов. Но не до конца разобрался.. В уроке было описание только для одного порта, а вот как сделать для двух портов - не знаю.. представил выше код до чего я дошел, но там есть ошибка, наверное не одна. По этому хочу узнать кто что думает насчет того, как мне эту идею воплотить в реальность :)

Cat_CooLeR писал(а):Нет, так как "Порт – это пачка однобитных каналов" (в обучалке и написано). Если в порту 8 каналов, туда не пошлешь 15... Его нужно отдельно.

Просто я думал что как-то можно сделать так, что-бы код отличал данные в массиве, чтото типо:
"если данный бит больше 8 то вывод в порт D, иначе - в порт B"
Реклама
Эиком - электронные компоненты и радиодетали
Cat_CooLeR
Опытный кот
Сообщения: 732
Зарегистрирован: Пт авг 22, 2008 16:59:43
Контактная информация:

Сообщение Cat_CooLeR »

Легче будет на С написать, в CodeVisionAVR к примеру.
Реклама
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

Cat_CooLeR писал(а):Легче будет на С написать, в CodeVisionAVR к примеру.

мм.. а идей на ассемблере нету? потому как я си не знаю..
Реклама
Cat_CooLeR
Опытный кот
Сообщения: 732
Зарегистрирован: Пт авг 22, 2008 16:59:43
Контактная информация:

Сообщение Cat_CooLeR »

Ну есть немного идей, а так нужно сесть и написать, попробую.
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

Cat_CooLeR писал(а):Ну есть немного идей, а так нужно сесть и написать, попробую.

Чем код выше - не похож на пробную?) я даже написал в каком месте там ошибка) но не знаю как исправить..
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

Есть еще идейки насчет этого кроме Си?
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

Ладно, понятно.. изменил название темы.. теперь идеи появились?? :))
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Ну например так:

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

.................................
.........Здесь без изменений....
.................................
.................................

        rcall SelectArray   ;сходим, выберем массив
        sei         ;разрешаем прерывания глобально

;***************************************************
;* Основная программа
;**************************************************
Loop:
        rjmp Loop    ;бесконечный цикл


;************************************************
;* Обработчик прерывания Таймера1 по совпадению A
;************************************************
Timer1_comp1:
        ldi Temp,0               ;обнуление таймера
        out TCNT1H,Temp          ;----------
        out TCNT1L,Temp          ;----------

ReadArray:
        lpm Temp1,Z+   ;грузим из массива байт для порта В и увеличиваем Z на 1
        lpm Temp2,Z+   ;грузим из массива байт для порта D и увеличиваем Z на 1
        cpi Temp2,0b11111111 ;проверяем не конец-ли? (код конца - 0b11111111)
        brne Output   ;если не конец, то переходим на вывод в порты
        rcall SelectArray ;идём на выбор массива (установка начальных ZH и ZL)и возвращаемся сюда
        rjmp   ReadArray

Output:
        out PortB,Temp1
        out PortD,Temp2
        reti
;*********************************************************************


;*********************************************************************
;* Подпрограмма выбора массива.
;* На входе - номер массива в ResCnt, на выходе - адрес начала массива в Z.
;*********************************************************************
SelectArray:
        andi ResCnt,0b00000011   ;отсечка лишних разрядов сч. сбросов

        cpi ResCnt,0             ;сравнение счетчика сбросов с конст.
        brne Tst1                ;если не равно - след. проверка
        ldi ZH,High(Array0*2)   ;загрузка начального адреса массива
        ldi ZL,Low(Array0*2)    ;----------
        rjmp Sel_end
Tst1:
        cpi ResCnt,1
        brne Tst2
        ldi ZH,High(Array1*2)
        rjmp Sel_end
Tst2:
        cpi ResCnt,2
        brne Tst3
        ldi ZH,High(Array2*2)
        ldi ZL,Low(Array2*2) 
        rjmp Sel_end
Tst3:
        ldi ZH,High(Array3*2)
        ldi ZL,Low(Array3*2)
Sel_end:
        ret
;*********************************************************************

;*********************************************************************
;* Массивы. Первый бат для порта B, второй - для D. Признак конца - байт 0b11111111 для порта D.
;*********************************************************************
Array0:
.db  0b10000000,0b0000000
.db  0b01000000,0b0000000
.db  0b00100000,0b0000000
.db  0b00010000,0b0000000
.db  0b00001000,0b0000000
.db  0b00000100,0b0000000
.db  0b00000010,0b0000000
.db  0b00000001,0b0000000
.db  0b00000000,0b1000000
.db  0b00000000,0b0100000
.db  0b00000000,0b0010000
.db  0b00000000,0b0001000
.db  0b00000000,0b0000100
.db  0b00000000,0b0000010
.db  0b00000000,0b0000001
.db  0b11111111,0b11111111


И не называй компаратором совпадение таймера. Это разные вещи.
Еще по-хорошему в обработчиках прерываний надо сохранять SREG при входе и восстанавливать его при выходе. В твоём случае можно без этого (прога очень проста и порча флагов ни на что не влияет).
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

2 YurkaM
Спасибище огромное!!! Я знал что не надо городить тот огород и можно сделать намного проще!!! Но не знал как))))) *берет в свои лапы тактику построения кода, рисуя на морде ехидную улыбку*

З.Ы. Вопрос снят, тему можно закрывать :)
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Ещё можно убрать эти строки, если в начале настроить таймер в режим обнуления при совпадении (CTC, кажется называется - кури даташит..)

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

        ldi Temp,0               ;обнуление таймера 
        out TCNT1H,Temp          ;----------
        out TCNT1L,Temp          ;----------


ps: я если честно, свой код не проверял, возможны мелкие ошибки/опечатки.. Но главное - общую идею показал, а дальше САМ!
C0oo1D
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пн дек 29, 2008 14:23:35
Откуда: Донецк, Украина

Сообщение C0oo1D »

была только одна ошибка, но она совсем не серьезная :)) (нехватало 1 строки)
Tst1:
cpi ResCnt,1
brne Tst2
ldi ZH,High(Array1*2)
ldi ZL,Low(Array1*2)
rjmp Sel_end




Ещё можно убрать эти строки, если в начале настроить таймер в режим обнуления при совпадении (CTC, кажется называется - кури даташит..)

Пока не мешает, но спасибо за совет)
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»