Страница 1 из 2

ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 11:21:45
RossiaForever
Привет всем !
Стараюсь сделать программу " бегущий огонь " , остановился на ниже приведенной .
Программа запускается , но останавливается на " бесконечном цикле " ( есть гипотеза что не выполняется прерывание ) . С чем это может быть связано ? ( точнее в чем ошибка ).
МК ATmega8 , частота 8 МГц , схема без кварцевого резонатора ( код взят с данного сайта ).
Исходный код программы :

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

.include "m8def.inc"
.def     Temp=R16
.def     Temp1=R17
.org 0
.cseg

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 Temp,0b11111111   ;настройка портов
          out DDRB,Temp

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

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

          ldi Temp,0x27        ;инициализация компаратора
          out OCR1AH,Temp
          ldi Temp,0x10
          out OCR1AL,Temp
      LDI R16,Low(RAMEND)       ;установка указателя стека
      OUT SPL,R16         
      LDI R16,High(RAMEND)
      OUT SPH,R16   
         

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

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

          sei                   ;разрешить прерывания


;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf:      rjmp Inf              ;бесконечный цикл


;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************

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


Shift:   cpi Temp1,0b10000000  ;сравнить с крайним знач.
         breq Init             ;если равно - загрузка нач. знач.

         lsl Temp1             ;иначе - сдвиг влево
         rjmp Output           ;перейти на вывод в порт

Init:    ldi Temp1,0b00000001  ;загрузить нач. значение
Output:  out PortB,Temp1       ;вывод в порт

         reti                  ;выход из обработчика

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 11:59:32
orinoko
А что говорит отладчик? Может вы не то прерывание включили? И рекомендуется перед инициализацией запретить прерывания

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 12:02:31
Enigm
А зачем вам компаратор ?
Просто по таймеру прерывания делать?
Вы откуда код стянули ?

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 12:24:52
RossiaForever
Enigm писал(а):А зачем вам компаратор ?
Просто по таймеру прерывания делать?
Вы откуда код стянули ?


Код взят с данного сайта .

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 12:47:13
Vov123
Правильно тебе говорят,смотри в даташит и в отладчик.

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

.org 0
.cseg

rjmp Reset            ;вектора прерываний
reti
reti
reti                  
reti
reti
rjmp Timer1_comp1         
reti
reti
reti
reti


;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset:    ldi Temp,0b11111111   ;настройка портов
          out DDRB,Temp

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

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

          ldi Temp,0x27        ;инициализация компаратора
          out OCR1AH,Temp
          ldi Temp,0x10
          out OCR1AL,Temp
      LDI R16,Low(RAMEND)       ;установка указателя стека
      OUT SPL,R16         
      LDI R16,High(RAMEND)
      OUT SPH,R16   
         

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

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

          sei                   ;разрешить прерывания

Как говорится-почувствуй разницу.

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 13:28:15
Enigm
RossiaForever писал(а):
Enigm писал(а):А зачем вам компаратор ?
Просто по таймеру прерывания делать?
Вы откуда код стянули ?


Код взят с данного сайта .

Предлагаеш мне искать где он написан ?
Ну что же удачи

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 13:34:10
RossiaForever
Enigm писал(а):Предлагаеш мне искать где он написан ?
Ну что же удачи


http://radiokot.ru/start/mcu_fpga/avr/11/

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 13:52:30
Vov123
Это просто праздник какой-то,уже всё написал,осталось только скопировать и вставить это в свой кривой код,и этот "участник форума",будущее,так сказать,России,с громким ником,прочитать не может. :))) :))) :)))

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 14:25:41
Enigm
Бывает )))
Печалит только то что , все больше и больше, потребителей.

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 14:33:04
zero648
LDI R16,Low(RAMEND) ;установка указателя стека
OUT SPL,R16
LDI R16,High(RAMEND)
OUT SPH,R16

Механизм записи для всех двухбайтовых регистров одинаковый, сначала старший потом младший, а стек исключение чтоли?

LDI R16,High(RAMEND)
OUT SPH,R16
LDI R16,Low(RAMEND) ;установка указателя стека
OUT SPL,R16

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 14:42:59
akl
zero648 писал(а):а стек исключение чтоли?
В случае со стеком, да. Смотрим, например, DS на mega8.
The AVR Stack Pointer is implemented as two 8-bit registers in the I/O space.
Больше никаких указаний на порядок установки нет, в отличие от специально выделенного порядка установки/чтения регистров таймеров, что, по мне, весьма разумно.

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 20:09:55
RossiaForever
Писать мне программу целиком не просил никогда , хотел всего то чтобы навели на ошибку .
Мне просто немного трудно понять " реализацию настроек таймера в коде " .Т.е. трудно написать .

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 22:53:07
Enigm
Вам уже дали готовый кусок, замените и все ))

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Пт мар 08, 2013 23:22:43
zero648
RossiaForever писал(а):Писать мне программу целиком не просил никогда , хотел всего то чтобы навели на ошибку .
Мне просто немного трудно понять " реализацию настроек таймера в коде " .Т.е. трудно написать .

В TIMSK включаете не тот вектор, нужно OCIE1A, во-вторых нужно задать режим таймера СТС, т.е. включить WGM12 в TCCR1B. И не надо в обработчике обнулять счетчик.

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 16:05:55
RossiaForever
Очень старался , пользовался литературой :

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


.include "m8def.inc"
.def     Temp=R16
.def     Temp1=R17
.def     Count_Time=R18
.org 0
.cseg
 rjmp _Reset

;----------

; ***** ВЕКТОРА ПРЕРЫВАНИЙ *****

rjmp INT_0
rjmp Timer0_OVF0

INT_0:
Timer0_OVF0:
reti

;----------

; ***** ИНИЦИАЛИЗАЦИЯ *****

_Reset:
 
ldi Temp,0b11111111 ; настройка порта D на выход
out DDRD,Temp
 
 LDI R16,High(RAMEND)
 OUT SPH,R16
 LDI R16,Low(RAMEND) ; установка указателя стека   
 OUT SPL,R16         
 
ldi Temp,0b00000010   ;разрешить прерывание по переполнению
out TIMSK,Temp

ldi Temp,0b00000100   ;тактовый сигнал = CK/256
out TCCR0,Temp

ldi Count_Time, 5

 sei                   ;разрешить прерывания

;----------

; ***** ОСНОВНОЙ ЦИКЛ *****

Inf:      rjmp Inf              ;бесконечный цикл

;----------

; ***** ОБРАБОТЧИК ПРЕРЫВАНИЯ ТАЙМЕРА *****

TIM0 :
ldi Temp,0            ;обнуление таймера
out TCNT0,Temp
dec Count_Time ; регистр для отсчета прерываний
breq end_timer
reti
end_timer:

Init: Ldi Temp1 , 0b00000001 ; начало тела программы
Shift :
cpi Temp1,0b10000000
breq Init
lsl Temp1
rjmp Shift  ; конец тела программы

reti



Обязательно критикуем , наводя на ошибки .
Заранее спасибо !!!

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 16:09:54
RossiaForever
akl писал(а):
zero648 писал(а):а стек исключение чтоли?
В случае со стеком, да. Смотрим, например, DS на mega8.
The AVR Stack Pointer is implemented as two 8-bit registers in the I/O space.
Больше никаких указаний на порядок установки нет, в отличие от специально выделенного порядка установки/чтения регистров таймеров, что, по мне, весьма разумно.


В литературе встречал сначала младший , потом старший ( под авторством Ревича Ю.В. ) .

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 16:50:23
ChipKiller
RossiaForever писал(а):Обязательно критикуем , наводя на ошибку
...наверное ошибкИ, потому что их несколько.....
1. Разберитесь как работать с таймером
2. В чем смысл Count_Time?
3 ....

... используйте константы вместо чисел - проще самому понять
... используйте, для начала, хотя-бы простые макросы - текст программы будет короче

Писать мне программу целиком не просил никогда , хотел всего то чтобы навели на ошибку .
... ?

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 17:05:16
RossiaForever
ChipKiller писал(а):
RossiaForever писал(а):Обязательно критикуем , наводя на ошибку
...наверное ошибкИ, потому что их несколько.....
1. Разберитесь как работать с таймером
2. В чем смысл Count_Time?
3 ....

... используйте константы вместо чисел - проще самому понять
... используйте, для начала, хотя-бы простые макросы - текст программы будет короче



Ошибок много , но пока трудно усвоить .
Count_Time - регистр , в который заносим число прерываний , необходимое для получения нужного нам времени .
Чтобы использовать макросы , для начала мне их нужно будет выучить , но это позже ( недавно начал изучение программирования AVR ) .
Использовать числа вместо констант мне пока проще .
Чтобы разобраться с таймером , зашел на форум , на чужих примерах очень трудно понять . Поэтому хочу исправить " свою " .

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 17:21:06
akl
Вам уже не Ревича, а DS от производителя нужно изучать. Поиск у них прекрасно работает. :)
По коду. Установите студию 4, ну или 3.56, если найдете, и прокрутите Ваш текст и все увидите
AVR_STUDIO_3.56.GIF

посмотрите Ваш текст с исправлениями
Спойлер

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

.include "m8def.inc"
.def     Temp=R16
.def     Temp1=R17
.def     Count_Time=R18
.org 0
.cseg

 rjmp _Reset

;----------

; ***** ВЕКТОРА ПРЕРЫВАНИЙ *****
.org $0001
rjmp INT_0
.org $0009
   RJMP   TIM0
;rjmp Timer0_OVF0

INT_0:
;Timer0_OVF0:
reti
;*******************************************

;----------

; ***** ИНИЦИАЛИЗАЦИЯ *****

_Reset:
 
ldi Temp,0b11111111 ; настройка порта D на выход
out DDRD,Temp
 
 LDI R16,Low(RAMEND)
 OUT SPL,R16
 LDI R16,High(RAMEND) ; установка указателя стека   для стека можно и так
 OUT SPh,R16         

; LDI R16,High(RAMEND)
; OUT SPH,R16
; LDI R16,Low(RAMEND) ; установка указателя стека   
; OUT SPL,R16         
;*******************************************************
ldi Temp,0b00000001   ;разрешить прерывание по переполнению
out TIMSK,Temp

;ldi Temp,0b00000010   ;????????????????разрешить прерывание по переполнению
;out TIMSK,Temp
;*******************************************************
ldi Temp,0b00000100   ;тактовый сигнал = CK/256
out TCCR0,Temp

ldi Count_Time, 5

 sei                   ;разрешить прерывания

;----------

; ***** ОСНОВНОЙ ЦИКЛ *****

Inf:      rjmp Inf              ;бесконечный цикл

;----------

; ***** ОБРАБОТЧИК ПРЕРЫВАНИЯ ТАЙМЕРА *****

TIM0:
ldi Temp,0            ;обнуление таймера
out TCNT0,Temp
dec Count_Time ; регистр для отсчета прерываний
breq end_timer
reti
end_timer:

Init: Ldi Temp1 , 0b00000001 ; начало тела программы
Shift :
cpi Temp1,0b10000000
breq Init
lsl Temp1
;********************************************
   OUT   PORTD,TEMP1
;********************************************
rjmp Shift  ; конец тела программы

reti

Re: ATmega8 . Таймер .Бегущий огонь .

Добавлено: Сб мар 09, 2013 19:19:46
RossiaForever
akl писал(а):Вам уже не Ревича, а DS от производителя нужно изучать. Поиск у них прекрасно работает. :)
По коду. Установите студию 4, ну или 3.56, если найдете, и прокрутите Ваш текст и все увидите
AVR_STUDIO_3.56.GIF

посмотрите Ваш текст с исправлениями
Спойлер

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

.include "m8def.inc"
.def     Temp=R16
.def     Temp1=R17
.def     Count_Time=R18
.org 0
.cseg

 rjmp _Reset

;----------

; ***** ВЕКТОРА ПРЕРЫВАНИЙ *****
.org $0001
rjmp INT_0
.org $0009
   RJMP   TIM0
;rjmp Timer0_OVF0

INT_0:
;Timer0_OVF0:
reti
;*******************************************

;----------

; ***** ИНИЦИАЛИЗАЦИЯ *****

_Reset:
 
ldi Temp,0b11111111 ; настройка порта D на выход
out DDRD,Temp
 
 LDI R16,Low(RAMEND)
 OUT SPL,R16
 LDI R16,High(RAMEND) ; установка указателя стека   для стека можно и так
 OUT SPh,R16         

; LDI R16,High(RAMEND)
; OUT SPH,R16
; LDI R16,Low(RAMEND) ; установка указателя стека   
; OUT SPL,R16         
;*******************************************************
ldi Temp,0b00000001   ;разрешить прерывание по переполнению
out TIMSK,Temp

;ldi Temp,0b00000010   ;????????????????разрешить прерывание по переполнению
;out TIMSK,Temp
;*******************************************************
ldi Temp,0b00000100   ;тактовый сигнал = CK/256
out TCCR0,Temp

ldi Count_Time, 5

 sei                   ;разрешить прерывания

;----------

; ***** ОСНОВНОЙ ЦИКЛ *****

Inf:      rjmp Inf              ;бесконечный цикл

;----------

; ***** ОБРАБОТЧИК ПРЕРЫВАНИЯ ТАЙМЕРА *****

TIM0:
ldi Temp,0            ;обнуление таймера
out TCNT0,Temp
dec Count_Time ; регистр для отсчета прерываний
breq end_timer
reti
end_timer:

Init: Ldi Temp1 , 0b00000001 ; начало тела программы
Shift :
cpi Temp1,0b10000000
breq Init
lsl Temp1
;********************************************
   OUT   PORTD,TEMP1
;********************************************
rjmp Shift  ; конец тела программы

reti


Спасибо большое за ответ !
пользуюсь AVRStudio 4 . моделирую схемы в Proteus .
Отпишусь о результатах позже .