реклама на сайте
подробности

 
 
> Помогите новичку с таймером на Меге16, в чем моя ошибка?
DimaSPB
сообщение Dec 1 2007, 18:52
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 22-08-07
Пользователь №: 29 972



Я - любитель и только начал разбираться с Мегой16. Глядя в книжки и даташит написал учебную программу, сигнализирующую переполнение таймера 1 в нормальном режиме хотя бы один раз. Ниже прилагаю код. Увы, эффекта нет((( Ломаю голову уже 16 часов, сил больше нет...
Прошу помощи! В чем ошибка???

; АТМега16
; Учебная программа работы с таймером 1 в нормальном режиме
; Первое прерывание по любому событию таймера 1 зажигает светодиод

.include "m16def.inc" ; Присоединение файла описаний
.list ; Включение листинга

.def temp = r16 ; Определение главного рабочего регистра

;------------------------- Вектора прерывания
rjmp RESET
reti ;rjmp Прерывание 1
reti ;rjmp Прерывание 2
reti ;rjmp Прерывание 3
reti ;rjmp Прерывание 4
rjmp TIM1 ;Прерывание 5 Захват таймера-счетчика 1
rjmp TIM1 ;Прерывание 6 Совпадение А таймера-счетчика 1
rjmp TIM1 ;Прерывание 7 Совпадение В таймера-счетчика 1
rjmp TIM1 ;Прерывание 8 Переполнение таймера-счетчика 1
reti ;rjmp Прерывание 9
reti ;rjmp Прерывание 10
reti ;rjmp Прерывание 11
reti ;rjmp Прерывание 12
reti ;rjmp Прерывание 13
reti ;rjmp Прерывание 14
reti ;rjmp Прерывание 15
reti ;rjmp Прерывание 16
reti ;rjmp Прерывание 17
reti ;rjmp Прерывание 18
reti ;rjmp Прерывание 19
reti ;rjmp Прерывание 20

RESET:
cli ; общий запрет прерываний

ldi temp, 0x80 ;Выключение компаратора
out ACSR, temp

;-------------------------- Инициализация стека

ldi temp, 0x7F ; Выбор адреса вершины стека
out SPL, temp ; Запись его в регистр стека


;-------------------------- Инициализация портов ВВ
ldi temp, 0xFF ; Запись числа $FF в регистр temp
out DDRB, temp ; Запись этого числа в DDRB (порт PB на вывод)
out PORTB, temp ; Запись то же числа в PORTB (потушить светодиод)

;--------------------------- Инициализация таймера-счетчика 1
out TIMSK, temp ;Разрешение прерываний по любому событию таймеров

ldi temp,0b00000000
out TCCR1A, temp ;Нормальный режим Таймера 1

ldi temp,0b00000011 ;Нормальный режим Таймера 1, Предделитель 1/64
out TCCR1B, temp
;---------------------------

sei ; общее разрешение прерываний

;-------------------------- Основной пустой цикл
main:
nop
rjmp main ; К началу цикла

;-------------------------- Прерывания по таймеру 1
; Если хотя бы раз происходит прерывание, загорается светодиод
TIM1:
ldi temp, 0x00 ; Записываем число $00 в регистр temp
out PORTB, temp ; Записываем число 0x00 в PORTB (включить светодиод)
reti
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
Leen
сообщение Dec 2 2007, 01:14
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



Проверял в симуляторе... Прога-то работает нормально... И прерывание происходит... Вот только одного не понял, почему вдруг у меги 16 TIM1_OVF уехал на адрес 8???? Выспитесь, потом откройте ман на сабж на стр. 45. И все будет путемsmile.gif
P.S. и пара маленьких замечаний: 1) никогда (тем более при отладке) не разрешайте ВСЕХ прерываний - программа улетит куда-нибудь, потом не найдете; 2) если таймер работает в режиме нормала, странно от него ожидать генерации прерываний по захвату и сравнению...
Успехов.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 2 2007, 01:37
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Leen @ Dec 2 2007, 04:14) *
не понял, почему вдруг у меги 16 TIM1_OVF уехал на адрес 8???? Выспитесь, потом откройте ман на сабж на стр. 45. И все будет путемsmile.gif

правильно у него все, только в даташите от 1 нумерация, а у товарища от нуля. SPH он еще забыл записать, но это не причина
Go to the top of the page
 
+Quote Post
Leen
сообщение Dec 2 2007, 03:14
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



Пардон, с бодуна считать тяжеловато, оказывается... Не прав был... не 8, а 9.
Ну не знаю...
.org 0x10
rjmp TIM1

ну или везде ставить
rjmp ...
reti
Чтобы по 2 адреса занимать...
Глюк-то в том, что последняя запись rjmp TIM1 лежит по адресу 0х8, а не 0х10, как должна. Только тогда не надо reti в точке выхода из подпрограммы TIM1 ставить.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 2 2007, 03:25
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Я Вас не понял. reti равно как jmp занимают по 2 байта. TIM1OVF и так ложится куда положено, то есть на 0x10
Вообще хорошо бы у автора спросить - он без всяких прерываний светодиод то зажег ?
Go to the top of the page
 
+Quote Post
Leen
сообщение Dec 2 2007, 03:38
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



Так... Все чудесатее и чудлесатее...
хекс:
Код
:020000020000FC
:1000000014C018951895189518951FC01EC01DC0CE
:100010001CC0189518951895189518951895189549
:1000200018951895189518951895F89400E808B93A
:100030000FE70DBF0FEF07BB08BB09BF00E00FBD07
:1000400003E00EBD78940000FECF00E008BB1895D9
:00000001FF

В самом деле, здесь вроде все в порядке...

Дизасм в аврстудии
Код
11:       rjmp RESET
+00000000:   C014        RJMP    PC+0x0015        Relative jump
12:       reti;rjmp Ïðåðûâàíèå 1
+00000001:   9518        RETI                     Interrupt return
13:       reti;rjmp Ïðåðûâàíèå 2
+00000002:   9518        RETI                     Interrupt return
14:       reti;rjmp Ïðåðûâàíèå 3
+00000003:   9518        RETI                     Interrupt return
15:       reti;rjmp Ïðåðûâàíèå 4
+00000004:   9518        RETI                     Interrupt return
16:       rjmp TIM1;Ïðåðûâàíèå 5 Çàõâàò òàéìåðà-ñ÷åò÷èêà 1
+00000005:   C01F        RJMP    PC+0x0020        Relative jump
17:       rjmp TIM1;Ïðåðûâàíèå 6 Ñîâïàäåíèå À òàéìåðà-ñ÷åò÷èêà 1
+00000006:   C01E        RJMP    PC+0x001F        Relative jump
18:       rjmp TIM1;Ïðåðûâàíèå 7 Ñîâïàäåíèå  òàéìåðà-ñ÷åò÷èêà 1
+00000007:   C01D        RJMP    PC+0x001E        Relative jump
19:       rjmp TIM1; прер. 8 - переп. ТС1
+00000008:   C01C        RJMP    PC+0x001D        Relative jump
20:       reti;rjmp Ïðåðûâàíèå 9
+00000009:   9518        RETI                     Interrupt return
21:       reti;rjmp Ïðåðûâàíèå 10
+0000000A:   9518        RETI                     Interrupt return
22:       reti;rjmp Ïðåðûâàíèå 11
+0000000B:   9518        RETI                     Interrupt return
23:       reti;rjmp Ïðåðûâàíèå 12
+0000000C:   9518        RETI                     Interrupt return
24:       reti;rjmp Ïðåðûâàíèå 13
+0000000D:   9518        RETI                     Interrupt return
25:       reti;rjmp Ïðåðûâàíèå 14
+0000000E:   9518        RETI                     Interrupt return
26:       reti;rjmp Ïðåðûâàíèå 15
+0000000F:   9518        RETI                     Interrupt return
27:       reti;rjmp Ïðåðûâàíèå 16
+00000010:   9518        RETI                     Interrupt return//здесь оказываемся по прерыванию
28:       reti;rjmp Ïðåðûâàíèå 17
+00000011:   9518        RETI                     Interrupt return
29:       reti;rjmp Ïðåðûâàíèå 18
+00000012:   9518        RETI                     Interrupt return
30:       reti;rjmp Ïðåðûâàíèå 19
+00000013:   9518        RETI                     Interrupt return
31:       reti;rjmp Ïðåðûâàíèå 20
+00000014:   9518        RETI                     Interrupt return

Странно... Какие мысли? Кто не прав? Может, студия? Платформу назначил правильно, мега 16, версия студии 4.12.460.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 2 2007, 03:40
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Со студией не работал, видать она словами адреса считает, а не байтами просто
Go to the top of the page
 
+Quote Post
DimaSPB
сообщение Dec 2 2007, 07:54
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 22-08-07
Пользователь №: 29 972



Здравствуйте! Спасибо всем за участие!!! beer.gif
Я выспался wassat.gif 1111493779.gif

Таблицу прерываний я использовал из книги Евстифеева, а там ресет нулевой, а прерывания начинаются с единицы.

"1) никогда (тем более при отладке) не разрешайте ВСЕХ прерываний - программа улетит куда-нибудь, потом не найдете; 2) если таймер работает в режиме нормала, странно от него ожидать генерации прерываний по захвату и сравнению..."

Как я понимаю, у меня прерывния разрешены только от таймеров. Разве остальные не замкнуты на возврат? Все события от таймера 1 я указал от отчаяния smile3046.gif , чтобы не прозевать чего от таймера rolleyes.gif
Кстати, попутно практический вопрос - если надо использовать только одно прерывание обязательно ли воспроизводить всю таблицу, замыкая ненужные на reti?

В SPH у Меги16 записать FF?

"Вообще хорошо бы у автора спросить - он без всяких прерываний светодиод то зажег?"

Да, зажег. При переносе кода из прерывания:
ldi temp, 0x00 ; Записываем число $00 в регистр temp
out PORTB, temp ; Записываем число 0x00 в PORTB (включить светодиод)

перед основным циклом светодиод зажигается сразу после запуска. Мега стоит на макетке вместе с самодельным аналогом STK200.
К сожалению, я пока не умею работать симуляторами, код делаю в AVR-студии... Там же и эмулировать можно?

Сообщение отредактировал DimaSPB - Dec 2 2007, 07:56
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 2 2007, 08:07
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



в SPH пишите high (RAMEND)
RAMEND у Меги16 0x45F
Значит в SPL пишем 0x5f , а в SPH - 0x04
Таблицу все необязательно, но лучше как говорится на всякий случай. И все таки разрешите только прерывание OVF.
А еще лучше CTC mode попробуйте. Пока идей других нет, с Мегами давно не работал
Кстати в прерываниях еще необходимо SREG сохранять. Правда в такой простой программе это не суть важно. Да и остальные регистры, используемые в прерывании тоже надо
Go to the top of the page
 
+Quote Post
DimaSPB
сообщение Dec 2 2007, 09:47
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 22-08-07
Пользователь №: 29 972



Оставил в таблице только прерывание OVF таймера 1
В указатель стека загружать стал два байта
Увы, не помогло sad.gif

Есть в нете толковое русское описание AVR-студии?
Go to the top of the page
 
+Quote Post
Leen
сообщение Dec 2 2007, 22:47
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



По поводу проблемы с неправильным позиционированием прерывания:
У мег область флэша имеет длину 16 бит, аврстудия в дизассемблере показывает адреса в словах. Т.е. адрес 0x10 - это не 16 байт, а 16 слов, что я и видел.
Поэтому работоспособен такой код:
Код
.org 0
rjmp RESET; starting
.org 0x10
rjmp TIM1_OVF; go to interrupt service routine for timer 1 overflow

Что касается почему стартовый код (то есть таблица прерываний) уважаемого DimaSPB не работает.
Инструкция rjmp имеет длину 16 бит и укладывается в одно слово памяти программ. Чтобы такая таблица работала, после каждого ржампа надо поставить ноп, дабы занять еще одно слово. На каждый вектоп прерывания (и на ресет тоже) отводится не по 2 байта, а по два слова, чтобы туда помещался не только короткий переход (rjmp), но и длинный (jmp), занимающий 2 слова (4 байта). Смотрите AVR Instruction Set, описание вышеназванных команд.
Также в даташите по меге 16 на стр. 46 есть такие вот строчки:
Цитата
The most typical and general program setup for Reset and Interrupt Vector Addresses in ATmega16 is:
address label code comments
$000 jmp RESET ; Reset Handler
$002 jmp EXT_INT0 ; IRQ0 Handler
$004 jmp EXT_INT1 ; IRQ1 Handler
$006 jmp TIM2_COMP ; IRQ0 Handler
...

Т.е. атмелы в своем типичном примере используют 4-хбайтовую команду для прыжка. Можно сделать так же. Тогда точно работать будет.
Или так:
Код
rjmp RESET; смещение 0 слов
nop; заполняем промежуток - смещение 1 слово
rjmp EXT_INT0; смещение 2 слова
nop; заполняем промежуток - смещение 3 слово


2 DimaSPB: под разрешением всех прерываний я имел ввиду запись FF в TIMSK при настройке. Это вредно - ведь Вы разрешаете не только то прерывание, которое хотите использовать, но и неиспользуемые. Зачем? Просто
Код
ldi temp, 4
out TIMSK, temp


[quote]Есть в нете толковое русское описание AVR-студии?[/qoute]Лучше подучите английский. Всяко полезней будет. А описание я не встречал, кроме встроенной справки (правда, там все по-английски smile.gif)
Go to the top of the page
 
+Quote Post
DimaSPB
сообщение Dec 4 2007, 18:05
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 22-08-07
Пользователь №: 29 972



Два дня не было нета crying.gif

Leen,
Огромное спасибо за совет! Все заработало! yeah.gif wink.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 21:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01474 секунд с 7
ELECTRONIX ©2004-2016