Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.51/41: Рейтинг темы: голосов - 41, средняя оценка - 4.51
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
1

Таймер

14.12.2012, 13:36. Показов 7989. Ответов 40
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
После выполнения подпрограммы выход из неё происходит в секцию Init, а не в rcall Timer. Где косяк ?
Код
.include "m8def.yms"
.list
;=====================

.def temp= r16
.def Mark240= r17
.def Counter= r18

;=====================
; Начало программы

rjmp Init           ;Первая выполняемая команда

;Подпрограмы:
Timer:

ldi temp,0b00000001; ????????????
out TIMSK,temp;      ????????????

ldi temp,0b00000001; Включаем таймер
out TCCR0,temp;      Частота T/C0  равна CK/???

ldi temp,0b11000000;
out SREG,temp;

brne timer

;=====================
Init:
ldi temp,0b00000001; 1 пин порта В выход, остальные входы
out DDRB, temp;

clr temp
out PortB, temp; Все выводы пота В выкл.

ldi Mark240,241;
ldi Counter,5
;=====================
Start:
sbi PortB,0 ; включаем СИД

rcall Timer

rjmp Start
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.12.2012, 13:36
Ответы с готовыми решениями:

Таймер
Народ, помогите настроить таймер... ATmega8A 16mHz Нужно просто в определенные моменты...

не работает таймер
всем доброго времени суток. не пинайте я только учусь. вот //B.0;B.1-две кнопки. //В.2-свето...

Таймер на attiny2313
Приветствую всех. Как на 2313 рассчитать значение для записи в эти регистры, если я хочу получить...

Опятьже таймер...
Прошу помощи! вернее уже готовый код проги (ТУПОЙ!!!) работы таймера1 в atmega16 которая...

40
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 2,309
15.12.2012, 14:55 21
Author24 — интернет-сервис помощи студентам
Кстати да. При частом вызове подпрограммы timer и без использования команды ret рискуешь словить переполнение стека, в итоге стек будет изменять память с регистрами и получится каша. Если не хочешь использовать ret, то хотя бы при завершении подпрограммы таймера, корректируй указатель стека.

Вообще как-то очень криво все написано. Можно обойтись гораздо красивее. Правда я так и не понял что в целом делать должна программа... че-то я туплю последнее время...
0
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
17.12.2012, 01:06 22
[QUOTE="tostid_kriim"][QUOTE="Финский"]
В книге Ефстифеева написано "При переходе таймера/счетчика из состояния""$FF"в состояние "$00" устанавливается флаг TOV0 регистра TIFR и генерируется запрос на прерывание.
Только флаг Z в регистре SREG к этому не имеет ни малейшего отношения.
Люди разные, кому легко даетяс, комуто хуже, лучше бы помог.
Я спрошу еще раз -
Какая задача стоит? Что программа делать должна?
записать во временный регистр допустим число 25, потом его отправить в таймер, потом таймер доходит до 255, и возвращается к месту откуда была запущена подпрограмма, потом следующее число 65, записать в таймер, и что бы он снова дошел до 255, произошло переполнение и он снова вышел из подпрограммы. И так еще несколько чисел.
"Уж сколько раз твердили миру..." обычно принято в начале программы инициализировать указатель стека. Или нет?
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
20.12.2012, 20:18 23
Код
.include "m8def.yms"
.list
;=====================

.def temp= r16
.def Mark240= r17
.def Counter= r18

;=====================
; Начало программы

rjmp Init           ;Первая выполняемая команда

;Подпрограмы:
Timer:
ldi temp,0b00000001;
out TIMSK,temp;

ldi temp,0b00000001; Включаем таймер
out TCCR0,temp;      Частота T/C0  равна CK/???

sei;

in temp, TCNT0
cpi temp, 255
brlo Timer
ret
;=====================
Init:
ldi temp,0b00000001; 1 пин порта В выход, остальные входы
out DDRB, temp;

clr temp
out PortB, temp; Все выводы пота В выкл.

ldi Mark240,241;
ldi Counter,5
;=====================
Start:

cli ;Запрет всех прерываний
ldi r16,low(ROMEND) ;Загрузка указателя стека
out SPL,r16 ;
ldi r16,high(ROMEND) ;
out SPH,r16 ;
wdr ;Сброс WDT

ldi temp,50
out TCNT0,temp;
sbi PortB,0 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,100
out TCNT0,temp;
sbi PortB,1 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,150
out TCNT0,temp;
sbi PortB,2 ; включаем СИД
rcall Timer
;---------------------------
rjmp Start
Всё равно не получается, после того как таймер отсчитал, то выход из подпрограммы происходит в начало основной программы, а не после rcall Timer.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
20.12.2012, 20:55 24
Код
.include "m8def.yms"
.list
;=====================

.def temp= r16
.def Mark240= r17
.def Counter= r18

;=====================
; Начало программы

rjmp Init           ;Первая выполняемая команда

;Подпрограмы:
Timer:
ldi temp,0b00000001; Включаем таймер
out TCCR0,temp;      Частота T/C0  равна CK/???
Timer1:
in temp, TCNT0
cpi temp, 255
brlo Timer1
ret
;=====================
Init:
cli ;Запрет всех прерываний
ldi r16,low(ROMEND) ;Загрузка указателя стека
out SPL,r16 ;
ldi r16,high(ROMEND) ;
out SPH,r16 ;

ldi temp,0b00000001; 1 пин порта В выход, остальные входы
out DDRB, temp;

clr temp
out PortB, temp; Все выводы пота В выкл.

ldi Mark240,241;
ldi Counter,5
;=====================
Start:
ldi temp,50
out TCNT0,temp;
sbi PortB,0 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,100
out TCNT0,temp;
sbi PortB,1 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,150
out TCNT0,temp;
sbi PortB,2 ; включаем СИД
rcall Timer
;---------------------------
rjmp Start
Похоже Вы даже не читаете , ответы.
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
20.12.2012, 21:46 25
Цитата Сообщение от YTYOUT
Код:
.include "m8def.yms"
.list
;=====================

.def temp= r16
.def Mark240= r17
.def Counter= r18

;=====================
; Начало программы

rjmp Init ;Первая выполняемая команда

;Подпрограмы:
Timer:
ldi temp,0b00000001; Включаем таймер
out TCCR0,temp; Частота T/C0 равна CK/???
Timer1:
in temp, TCNT0
cpi temp, 255
brlo Timer1
ret
;=====================
Init:
cli ;Запрет всех прерываний
ldi r16,low(ROMEND) ;Загрузка указателя стека
out SPL,r16 ;
ldi r16,high(ROMEND) ;
out SPH,r16 ;

ldi temp,0b00000001; 1 пин порта В выход, остальные входы
out DDRB, temp;

clr temp
out PortB, temp; Все выводы пота В выкл.

ldi Mark240,241;
ldi Counter,5
;=====================
Start:
ldi temp,50
out TCNT0,temp;
sbi PortB,0 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,100
out TCNT0,temp;
sbi PortB,1 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,150
out TCNT0,temp;
sbi PortB,2 ; включаем СИД
rcall Timer
;---------------------------
rjmp Start

Похоже Вы даже не читаете , ответы.
Я читал ответы, но многое не понял. Понял то, что смог, в итоге получилось то, что я написал.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
21.12.2012, 00:20 26
Интересно , Вы мой то ответ внимательно прочли или только ,что я в конце написал
0
0 / 0 / 0
Регистрация: 12.04.2010
Сообщений: 3,260
21.12.2012, 09:51 27
Не понял - переспроси, уточни условия.
0
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 53
21.12.2012, 13:00 28
У тебя в цикле нет сброса сторожевого таймера (WDT). Поэтому (или скорее всего) он и сбрасывает программу в начальный адрес через заданное время. Это время задается в настройках WDT, и меняется оно по определенной процедуре. Сначала устанавливается бит разрешения изменений, а затем вводится необходимое время. Это время должно быть введено не позднее 4-х циклов, после чего бит разрешения сбросится автоматически. Лезем в даташит и читаем про WDT. Если за время WDT не произойдет его сброс командой wdr, то WDT сбросит программный счетчик в 0x0000. Это сделано для того, чтобы процессор не зависал, если его не туда послали неправильной программой. Поэтому в программе периодически надо сбрасывать WDT, особенно в длительных циклах.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 2,309
21.12.2012, 22:50 29
WDT интересная штука. Тока вот сколько я не делал проектов на AVR (и мега, и тини всякие) - везде по умолчанию после сброса WDT неактивен вовсе. И я его никогда не сбрасывал, да и вообще ниразу не трогал.
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
23.12.2012, 16:32 30
Цитата Сообщение от BykTiho
Не понял - переспроси, уточни условия.
Я хочу, что бы он возвращался в основную программу после метки rcall Timer, а не начало программы.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
23.12.2012, 17:25 31
Код
.include "m8def.yms"
.list
;=====================

.def temp= r16
.def Mark240= r17
.def Counter= r18

;=====================
; Начало программы

rjmp Init           ;Первая выполняемая команда

;Подпрограмы:
Timer:
in temp, TCNT0
cpi temp, 255
brlo Timer
ret
;=====================
Init:
cli ;Запрет всех прерываний
ldi r16,low(ROMEND) ;Загрузка указателя стека
out SPL,r16 ;
ldi r16,high(ROMEND) ;
out SPH,r16 ;

ldi temp,0b00000001; 1 пин порта В выход, остальные входы
out DDRB, temp;

clr temp
out PortB, temp; Все выводы пота В выкл.

ldi Mark240,241;
ldi Counter,5

ldi temp,0b00000001; Включаем таймер И это нахрен сюда Что-то я сразу не посмотрел.

out TCCR0,temp;      Частота T/C0  равна CK/???
;=====================
Start:
ldi temp,50
out TCNT0,temp;
sbi PortB,0 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,100
out TCNT0,temp;
sbi PortB,1 ; включаем СИД
rcall Timer
;---------------------------

ldi temp,150
out TCNT0,temp;
sbi PortB,2 ; включаем СИД
rcall Timer
;---------------------------
rjmp Start
У Вас программа пока не дойдёт до RJMP STAR из RCALL никогда сама на START не вернётся. Так уж Вы задумали.
Да кстати , я не просто так , каждый раз вставляю код.
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
23.12.2012, 17:36 32
Код
Timer:
in temp, TCNT0
cpi temp, 255
brlo Timer
ret
Что-то мне подсказывает, что brlo Timer будет выполняться всегда - Таймер0 8-мибитный, поэтому при достижении 255 - на следующем такте сбрасывается в 0 - соотв. 0 < 255 - вечный цикл. Или нет?
По крайней мере, в отладчике 6й Студии после 15 мин жмакания F11 - так и не вышло за пределы этого фрагмента.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
23.12.2012, 18:11 33
Ага, так как предделителя нет. Проц просто не успевает за таймером. Достаточно поделить на 8 - и успевает. Но это уже ответ на следующий вопрос ТС, ещё не заданный
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
23.12.2012, 18:16 34
Вот так и прокачивают ясновидение :)

А инициализация стека явно скопипизжена откуда-то - TC обозвал R16 - Temp, так почему бы не писать
Код
ldi temp,low(ROMEND) ;Загрузка указателя стека
out SPL,temp;
ldi temp,high(ROMEND) ;
out SPH,temp;
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
23.12.2012, 18:27 35
Во тоже развито ясновидение :) - DS
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
23.12.2012, 19:36 36
Люди объясните в чём косяк то, я уже просто больше не могу.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
23.12.2012, 20:22 37
Мы не знаем , о каком косяке в данный момент идёт речь. По крайней мере мой вариант Вашей программы работает. Правда я ещё изменил
ldi temp,0b00000001; Включаем таймер И это нахрен сюда Что-то я сразу не посмотрел.
На
ldi temp,0b00000010;
Иначе см. выше
Так, что озвучте чего теперь не катит
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
23.12.2012, 20:36 38
[QUOTE="YTYOUT"]Мы не знаем , о каком косяке в данный момент идёт речь. По крайней мере мой вариант Вашей программы работает. Правда я ещё изменил
[QUOTE="Цитата:[/QUOTE]
ldi temp,0b00000001; Включаем таймер И это нахрен сюда Что-то я сразу не посмотрел.
На
ldi temp,0b00000010;
Иначе см. выше
Так, что озвучте чего теперь не катит
Я согласен так работает, просто от меня требуют, что бы именно по переполнению таймера, тоесть таймер счетчик досчитал до 255 и выпрегнул из под программы, в то место откуда зашел. А тут просто два числа сравниваются и через reti он выходит. А мне нужно, что бы именно когда таймер переполнился и вышел из под программы.
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
23.12.2012, 20:39 39
Тогда вам нужно отслеживать флаг переполнения Таймера0.
0
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
23.12.2012, 20:48 40
Цитата Сообщение от Финский
Тогда вам нужно отслеживать флаг переполнения Таймера0.
Да. В момент когда т/с дошел до 255, поднимается флаг TOV0 регистра TIFR. И когда это происходит он выпрыгивает из подпрограммы, но он выпрыгивает в начало программы в секцию Init:, а не в то место где он зашел в подпрограмму, вот это я и пытаюсь понять, почему он прыгает не в то место.
0
23.12.2012, 20:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.12.2012, 20:48
Помогаю со студенческими работами здесь

16-разрядный таймер
Доброго времени суток дорогие посетители форума . Мое задание : управление светофорами , а именно...

не запускается таймер
не запускается таймер. Кто подскажет в чем ошибка? .CSEG .ORG $00 ; Riset rjmp risit .ORG $01...

Таймер времени
Возникла необходимость в создании нескольких синхронизированных очень точных таймеров, с точностью...

шим и таймер.
Во общем хочу сделать шим и выключить его по заданном интервалу времени. К примеру включили...

Таймер, мега8
Начал програмирование мк с мелкопаскаля и обламался, среда хоть и хороша новичкам но разработчики...

Таймер Attiny13
Здравствуйте! Хочу разобраться с таймером. По нажатию кнопки светодиод должен гореть примерно 5...

atmega8535 таймер
Здравствуйте. У меня всё то же устройство. Задача такая: на шине разные слова. Слова с моим...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru