Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
RiSt0R
1

atmega8 проблема с таймером TIM0_OVF

05.11.2016, 21:20. Просмотров 2655. Ответов 12
Метки нет (Все метки)

Здравствуйте, уважаемые! Подскажите, пожалуйста, в чём может быть дело. Бьюсь уже четвёртый день. Проблема в следующем - имеется 8-ми битный таймер по переполнению. При определённых условия он работает. Если условия меняются - не работает. Коротко о программе: часы (Что не делай на AVR, в итоге получаются часы, ога) на 7-сегментом индикаторе с общим анодом (подключено к PORTB). Катод подключен к PORTD. Цифры отображаются корректно. На PIN7 порта D - сектор ":". Динный таймер должен обрабатывать нажатия кнопок, но для он как-то странно работает, поэтому я решил его проверить и повесить туда моргание сектора ":" и увеличить время срабатывания. Избыточный код для простоты я вырезал. Вот в чём проблема:
Конкретно, если в секции "risit" инициализация регистров секунды, минуты, часы для часов на 7-сегментом индикаторе:
Код
ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x05
Тогда таймер работает, двоеточие моргает. Дисплей показывает "05:00"
А если так:
Код
ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x00
Дисплей показывает "00:00", двоеточие постоянно горит. Или, например так:
Код
ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x07
Дисплей показывает "07:00", двоеточие постоянно горит., т.е. таймер не отрабатывает. Пробовал менять микропроцессор, кроме того, попробовал на демоплате (atmega8 с обвесом и просто пины с ног МК) - то же самое. 7-я нога порта D либо меняет своё состояние, либо нет. Проверяю на железе. В протеусе PIND7 выдаёт высокий сигнал постоянно. Подскажите, пожалуйста, в чём может быть проблема?

Вот код:
Код
.def temp      = r16
.def temp2     = r17

.def sec_      = r18
.def min_      = r19
.def hour_     = r20

.def temp3     = r21
.def temp4     = r22

.def seg_1_2   = r14
.def seg_3_4   = r15
//  : горит
.def flags     = r13  // [7]       [6] [5] [4] [3] [2] [1] [0]

.equ timer0 = 0x00

.equ btn_echo_time = 0x14
.equ btn_hold_time = 0

.dseg
.cseg
.org 0
rjmp Riset
.org $009
rjmp TIM0_OVF ; Переход на обработку при переполнении Timer0

// Массив цифр для отображения на индикаторе
digit: .db 0b01000000, 0b01001111, 0b00100100, 0b00000110, 0b00001011, 0b00010010, 0b00010000, 0b01000111, 0b00000000, 0b00000010

Riset:  // Инициализация
ldi temp, high(ROMEND)
out sph, temp
ldi temp, low(ROMEND)
out spl, temp

ldi temp, 0b11111111
out DDRD, temp

ldi temp, 0b11111111
out DDRB, temp

ldi temp, 0b00000000
out DDRC, temp
ldi temp, 0b00000000
out PORTC, temp

ldi temp, 0b00000111 // Пределитель T0 - 1024
out TCCR0, temp

ldi temp, 0b00000001  ; Работает только таймер T0
out TIMSK, temp      ; Инициализация таймеров.

ldi temp, 0xff       // Пусть таймер T0 сработает сразу.
out TCNT0, temp

ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x05      // !!! Тут проблема !!!
rcall prep_segs

ldi temp, 0b10000000
mov flags, temp

sei

main_loop:  // Главный цикл

rcall dysp_time

rjmp main_loop

TIM0_OVF:  // Таймер переполнения
cli
ldi temp, timer0
out TCNT0, temp

rcall prep_segs

mov temp, flags
ldi temp2, 0b10000000
eor temp, temp2
mov flags, temp

sei
reti

prep_segs:  // Приготовить числа для отображения на индикаторе. 2 цифры в одном байте  десятки  единицы
//                                                                         XXXX     XXXX
cli

mov temp, hour_
rcall get_digits

lsl temp3
lsl temp3
lsl temp3
lsl temp3

add temp4, temp3
mov seg_1_2, temp4

mov temp, min_
rcall get_digits

lsl temp3
lsl temp3
lsl temp3
lsl temp3

add temp4, temp3
mov seg_3_4, temp4

sei
ret

get_digits:       // Получить однозначные числа из двухзначного
clr temp3       // Очистить десятки
clr temp4          // Очистить единицы
ldi temp2, 0x0A  // Число для вычитания

cpi temp, 0x0A ; Есть ли десятки в младшем разряде?
brsh get_10   ; Да
rjmp get_1   // Если нет сразу переходим к единицам.

get_10:
yms temp3 //yms dozens  ; Увеличить счётчик десятков на единицу.
sub temp, temp2 ; Вычесть из числа 10.
cpi temp, 0x0A  ; Есть ли ещё десятки
brsh get_10 // Есть ещё десятки

get_1:
ldi temp2, 0x01  // Число для вычитания
get_1_:
yms temp4         ; Увеличить счётчик единиц на единицу.
sub temp, temp2  ; Вычесть из числа 1.
cpi temp, 0x01 ; Больше одного?
brsh get_1_    ; Да.
ret

dysp_time:  // Отобразить цифры на индикаторе

ldi zl, low(digit*2) ; загрузка в регистр ZL low адреса массива digit
ldi zh, high(digit*2) ; загрузка в регистр ZH high адреса массива digit

ldi temp, 0b00000010
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00000100
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ldi temp, 0b00001000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00010000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ret

DelayShot:  // Задержка
ldi temp, 100       ;Загрузка значения в регистр r18
ldi temp2, 1        ;Загрузка значения в регистр r19
del2:                 ;Цикл задержки
subi temp, 1       ;Вычитание 1 из регистра r18
sbci temp2, 0       ;Вычитание 0 из регистра r19 с учетом переноса
brcc del2           ;Если не было переноса вернуться к метке del
ret
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.11.2016, 21:20
Ответы с готовыми решениями:

ATMega8 проблема с таймером
Вот такой вот косяк... <Изображение удалено> по прерыванию с int0 (сигнал с пульта) получаю...

ATmega8 работа с таймером
Всем привет. начинаю знакомится с программирование микроконтроллеров. дошел до работы с таймерами....

проблема с таймером
Добрый вечер. Начал недавно заниматься программированием микроконтроллеров (использую...

Проблема с таймером на ассемблере
Всем доброго времени суток. Я только начал изучать ассемблер. До этого работал только на C. Вроде...

12
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
06.11.2016, 01:24 2
Код
TIM0_OVF:  // Таймер переполнения
push temp
in temp,SREG
push temp
push temp2
push flags
ldi temp, timer0
out TCNT0, temp
rcall prep_segs
mov temp, flags
ldi temp2, 0b10000000
eor temp, temp2
mov flags, temp
pop flags
pop temp2
pop temp
out SREG,temp
push temp
reti
Код
prep_segs:  // Приготовить числа для отображения на индикаторе. 2 цифры в одном байте  десятки  единицы
//                                                                         XXXX     XXXX

mov temp, hour_
rcall get_digits
lsl temp3
lsl temp3
lsl temp3
lsl temp3
add temp4, temp3
mov seg_1_2, temp4
mov temp, min_
rcall get_digits
lsl temp3
lsl temp3
lsl temp3
lsl temp3
add temp4, temp3
mov seg_3_4, temp4
ret
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
06.11.2016, 12:54 3
Попробуйте так. Поскольку программа несинхронная и на лапе PD4/T0 присутствуют импульсы, а таймер в свою очередь настроен на счет оных получаются такой эффект.
Код
  ldi temp, 0b00000101 // Пределитель T0 - 1024
;  ldi temp, 0b00000111 // Пределитель T0 - 1024??????????????
out TCCR0, temp
0
RiSt0R
06.11.2016, 15:41 4
Цитата Сообщение от YTYOUT
Код:
TIM0_OVF: // Таймер переполнения
push temp
...
reti

Код
prep_segs:  // Приготовить числа для отображения на индикаторе. 2 цифры в одном байте  десятки  единицы
//                                                                         XXXX     XXXX

mov temp, hour_
...
mov seg_3_4, temp4
ret
К сожалению, не работает.

Цитата Сообщение от okt
Попробуйте так. Поскольку программа несинхронная и на лапе PD4/T0 присутствуют импульсы, а таймер в свою очередь настроен на счет оных получаются такой эффект.
Код:
ldi temp, 0b00000101 // Пределитель T0 - 1024
; ldi temp, 0b00000111 // Пределитель T0 - 1024??????????????
out TCCR0, temp

Посмотрел оригинальный даташит. До этого руководствовался русским. Оказывается таблицы настройки таймера там различаются (sic!):


<Изображение удалено>


<Изображение удалено>

0b00000101 - по русскому даташиту это предделитель на 128. А по оригинальному, английскому 1024. Поставил 101 - появилось неприятное мерцание сегментов дисплея, причём, похоже, что прерывание работает с предделителем 128 (иначе бы не мерцало, нет?). На дисплее "00:00" или "05:00", в зависимости от значения регистра hour_.
Поставил 100:
Код
ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x05
При включении питания кратковременно отображается "05:00", потом горит первый сектор "0", остальные секторы, в том числе и ":" не светятся - "0 _ _ _ _":
А если так:
Код
ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x00
Тогда при включении питания кратковременно отображается "00:00", потом горит ":" и последний сектор "0" - "_ _ : _ 0".
Ничего не понимаю. Помогите, люди добрые.
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
06.11.2016, 16:05 5
Весь код под спойлером выкладывай
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
06.11.2016, 16:12 6
И имя камня.
0
RiSt0R
06.11.2016, 16:31 7
Весь код под спойлером в первом сообщении. Камень OTmiko8-16PU DIP. Программирую под Atmel Studyo 7.0, прошиваю Khazama AVR Prokrammer v 1.6.2
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
06.11.2016, 16:41 8
Давайте тот , что сейчас. Вы думаете я Вам зря правил прерывание
0
RiSt0R
06.11.2016, 16:56 9
Цитата Сообщение от YTYOUT
Давайте тот , что сейчас. Вы думаете я Вам зря правил прерывание
Хорошо, вот код с Вашими правками:
Код
.def temp      = r16
.def temp2     = r17

.def sec_      = r18
.def min_      = r19
.def hour_     = r20

.def temp3     = r21
.def temp4     = r22

.def seg_1_2   = r14
.def seg_3_4   = r15
//  : горит
.def flags     = r13  // [7]       [6] [5] [4] [3] [2] [1] [0]

.equ timer0 = 0x00

.equ btn_echo_time = 0x14
.equ btn_hold_time = 0

.dseg
.cseg
.org 0
rjmp Riset
.org $009
rjmp TIM0_OVF ; Переход на обработку при переполнении Timer0

// Массив цифр для отображения на индикаторе
digit: .db 0b01000000, 0b01001111, 0b00100100, 0b00000110, 0b00001011, 0b00010010, 0b00010000, 0b01000111, 0b00000000, 0b00000010

Riset:  // Инициализация
ldi temp, high(ROMEND)
out sph, temp
ldi temp, low(ROMEND)
out spl, temp

ldi temp, 0b11111111
out DDRD, temp

ldi temp, 0b11111111
out DDRB, temp

ldi temp, 0b00000000
out DDRC, temp
ldi temp, 0b00000000
out PORTC, temp

ldi temp, 0b00000111 // Пределитель T0 - 1024
out TCCR0, temp

ldi temp, 0b00000001  ; Работает только таймер T0
out TIMSK, temp      ; Инициализация таймеров.

ldi temp, 0xff       // Пусть таймер T0 сработает сразу.
out TCNT0, temp

ldi sec_, 0x00
ldi min_, 0x00
ldi hour_, 0x05     // !!! Тут проблема !!!
rcall prep_segs

ldi temp, 0b10000000
mov flags, temp

sei

main_loop:  // Главный цикл

rcall dysp_time

rjmp main_loop

TIM0_OVF:  // Таймер переполнения
push temp
in temp,SREG
push temp
push temp2
push flags
ldi temp, timer0
out TCNT0, temp
rcall prep_segs
mov temp, flags
ldi temp2, 0b10000000
eor temp, temp2
mov flags, temp
pop flags
pop temp2
pop temp
out SREG,temp
push temp
reti

prep_segs:  // Приготовить числа для отображения на индикаторе. 2 цифры в одном байте  десятки  единицы
//                                                                         XXXX     XXXX

mov temp, hour_
rcall get_digits
lsl temp3
lsl temp3
lsl temp3
lsl temp3
add temp4, temp3
mov seg_1_2, temp4
mov temp, min_
rcall get_digits
lsl temp3
lsl temp3
lsl temp3
lsl temp3
add temp4, temp3
mov seg_3_4, temp4
ret

get_digits:       // Получить однозначные числа из двухзначного
clr temp3       // Очистить десятки
clr temp4          // Очистить единицы
ldi temp2, 0x0A  // Число для вычитания

cpi temp, 0x0A ; Есть ли десятки в младшем разряде?
brsh get_10   ; Да
rjmp get_1   // Если нет сразу переходим к единицам.

get_10:
yms temp3 //yms dozens  ; Увеличить счётчик десятков на единицу.
sub temp, temp2 ; Вычесть из числа 10.
cpi temp, 0x0A  ; Есть ли ещё десятки
brsh get_10 // Есть ещё десятки

get_1:
ldi temp2, 0x01  // Число для вычитания
get_1_:
yms temp4         ; Увеличить счётчик единиц на единицу.
sub temp, temp2  ; Вычесть из числа 1.
cpi temp, 0x01 ; Больше одного?
brsh get_1_    ; Да.
ret

dysp_time:  // Отобразить цифры на индикаторе

ldi zl, low(digit*2) ; загрузка в регистр ZL low адреса массива digit
ldi zh, high(digit*2) ; загрузка в регистр ZH high адреса массива digit

ldi temp, 0b00000010
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00000100
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ldi temp, 0b00001000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00010000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ret

DelayShot:  // Задержка
ldi temp, 100       ;Загрузка значения в регистр r18
ldi temp2, 1        ;Загрузка значения в регистр r19
del2:                 ;Цикл задержки
subi temp, 1       ;Вычитание 1 из регистра r18
sbci temp2, 0       ;Вычитание 0 из регистра r19 с учетом переноса
brcc del2           ;Если не было переноса вернуться к метке del
ret
На дисплее постоянно горит "05:00". Двоеточие не моргает.

UPD. Если в данном коде я ставлю:

Код
ldi temp, 0b00000101 // Пределитель T0 - 1024
out TCCR0, temp
Тогда нет такого жуткого моргания (но подмаргивает), но на дисплее быстро меняется "05:00", "00:00", "05:80", "05:81".
RiSt0R
06.11.2016, 17:18 10
Мои мысли вслух: вообще, если я недоглядел регистры и в них, при внезапном прерывании попадает мусор - просто на дисплее будет отображаться некорректные цифры. В основном "8" - 0xFF из-за чтения из неинициализированной памяти. Но таймер же должен выполняться. А вот переполнение по внешнему сигналу уже вероятней - прерывание возникает из-за того, что считается P0 или P3 порта D, при высоком/низком уровне. Причём переполнение выполняется слишком часто, потому что в основном цикле часто меняется состояние порта при динамической индикации дисплея. И двоеточие просто не успевает погаснуть. Фактически ШИМ. Но есть же возможность не считать внешние сигналы?
RiSt0R
06.11.2016, 19:00 11
Цитата Сообщение от okt
Попробуйте так. Поскольку программа несинхронная и на лапе PD4/T0 присутствуют импульсы, а таймер в свою очередь настроен на счет оных получаются такой эффект.
Код:
ldi temp, 0b00000101 // Пределитель T0 - 1024
; ldi temp, 0b00000111 // Пределитель T0 - 1024??????????????
out TCCR0, temp

Похоже, что Вы правы. Как я понял, проблема именно в этом. Подправил код секции DelayShot, что бы задержка стала меньше (пропало неприятное мерцание), инициализировал таймер 0 значением "0b00000101" и всё заработало при любом значении регистров времени (sec_, min_, hour_)

Вот рабочий код, кому интересно:
Код
.def temp      = r16
.def temp2     = r17

.def sec_      = r18
.def min_      = r19
.def hour_     = r20

.def temp3     = r21
.def temp4     = r22

.def seg_1_2   = r14
.def seg_3_4   = r15
//  : горит
.def flags     = r13  // [7]       [6] [5] [4] [3] [2] [1] [0]

.equ timer0 = 0x00

.equ btn_echo_time = 0x14
.equ btn_hold_time = 0

.dseg
.cseg
.org 0
rjmp Riset
.org $009
rjmp TIM0_OVF ; Переход на обработку при переполнении Timer0

// Массив цифр для отображения на индикаторе
digit: .db 0b01000000, 0b01001111, 0b00100100, 0b00000110, 0b00001011, 0b00010010, 0b00010000, 0b01000111, 0b00000000, 0b00000010

Riset:  // Инициализация
ldi temp, high(ROMEND)
out sph, temp
ldi temp, low(ROMEND)
out spl, temp

ldi temp, 0b11111111
out DDRD, temp

ldi temp, 0b11111111
//ldi temp, 0b10000000
out DDRB, temp

ldi temp, 0b00000000
out DDRC, temp
ldi temp, 0b00000000
out PORTC, temp

ldi temp, 0b00000101 // Пределитель T0 - 1024
out TCCR0, temp

ldi temp, 0b00000001  ; Работает только таймер T0
out TIMSK, temp      ; Инициализация таймеров.

ldi temp, 0xff       // Пусть таймер T0 сработает сразу.
out TCNT0, temp

ldi sec_, 0x00
ldi min_, 0x0A
ldi hour_, 0x0B
rcall prep_segs

ldi temp, 0b10000000
mov flags, temp

sei

main_loop:  // Главный цикл

rcall dysp_time

rjmp main_loop

TIM0_OVF:  // Таймер переполнения
cli
ldi temp, timer0
out TCNT0, temp

rcall prep_segs

mov temp, flags
ldi temp2, 0b10000000
eor temp, temp2
mov flags, temp

sei
reti

prep_segs:  // Приготовить числа для отображения на индикаторе. 2 цифры в одном байте  десятки  единицы
//                                                                         XXXX     XXXX
cli

mov temp, hour_
rcall get_digits

lsl temp3
lsl temp3
lsl temp3
lsl temp3

add temp4, temp3
mov seg_1_2, temp4

mov temp, min_
rcall get_digits

lsl temp3
lsl temp3
lsl temp3
lsl temp3

add temp4, temp3
mov seg_3_4, temp4

sei
ret

get_digits:       // Получить однозначные числа из двухзначного
clr temp3       // Очистить десятки
clr temp4          // Очистить единицы
ldi temp2, 0x0A  // Число для вычитания

cpi temp, 0x0A ; Есть ли десятки в младшем разряде?
brsh get_10   ; Да
rjmp get_1   // Если нет сразу переходим к единицам.

get_10:
yms temp3 //yms dozens  ; Увеличить счётчик десятков на единицу.
sub temp, temp2 ; Вычесть из числа 10.
cpi temp, 0x0A  ; Есть ли ещё десятки
brsh get_10 // Есть ещё десятки

get_1:
ldi temp2, 0x01  // Число для вычитания
cpi temp, 0x01 ; Есть ли единицы в младшем разряде?
brsh get_1_   ; Да
rjmp ret_    // Единиц нет, выходим

get_1_:
yms temp4         ; Увеличить счётчик единиц на единицу.
sub temp, temp2  ; Вычесть из числа 1.
cpi temp, 0x01 ; Больше одного?
brsh get_1_    ; Да.
ret_:
ret

dysp_time:  // Отобразить цифры на индикаторе

ldi zl, low(digit*2) ; загрузка в регистр ZL low адреса массива digit
ldi zh, high(digit*2) ; загрузка в регистр ZH high адреса массива digit

ldi temp, 0b00000010
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00000100
out PORTB, temp

mov temp2, seg_1_2

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ldi temp, 0b00001000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b11110000
omd temp2, temp

lsr temp2
lsr temp2
lsr temp2
lsr temp2

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2

rcall DelayShot

ldi temp, 0b00010000
out PORTB, temp

mov temp2, seg_3_4

ldi temp, 0b00001111
omd temp2, temp

add zl, temp2

lpm temp, z

mov temp3, flags        // Вычленить 7 бит ":"
ldi temp4, 0b10000000
omd temp4, temp3
or temp, temp4         // Добавить 7 бит к регистру на выход порта D

out PORTD, temp
sbc zl, temp2
rcall DelayShot

ret

DelayShot:  // Задержка

ldi temp, 255       ;Загрузка значения в регистр r18
ldi temp2, 200        ;Загрузка значения в регистр r19
del2:                 ;Цикл задержки
subi temp, 1       ;Вычитание 1 из регистра r18
sbci temp2, 1       ;Вычитание 0 из регистра r19 с учетом переноса
brcc del2           ;Если не было переноса вернуться к метке del

ret
YTYOUT, okt, спасибо Вам большое!

UPD. Видимо, русский даташит на совсем старый микропроцессор ATmega8. Видимо, на той версии МК ещё не было возможности в таймере 0 считать внешние импульсы.
P.S. А спецэффекты были прикольные.
0 / 0 / 0
Регистрация: 31.01.2013
Сообщений: 1,625
06.11.2016, 20:30 12
Цитата Сообщение от RiSt0R
Посмотрел оригинальный даташит. До этого руководствовался русским. Оказывается таблицы настройки таймера там различаются
Указывайте камень и читайте даташит к нему, а не "вообще".

0
RiSt0R
07.11.2016, 05:35 13
Цитата Сообщение от yiv91
Цитата Сообщение от RiSt0R
Посмотрел оригинальный даташит. До этого руководствовался русским. Оказывается таблицы настройки таймера там различаются
Указывайте камень и читайте даташит к нему, а не "вообще".
Так в том то и дело, что русский даташит заявлен именно к ATmega8. Я же начинающий, а не избыточно хромосомный, ATmega128 от ATmega8 я отличаю. Плюс выводы я уже сделал - буду стараться использовать оригинальную и актуальную, а не переведённую непонятно кем документацию.

IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.11.2016, 05:35

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Atmega8 - проблема с PWM
Здраствуйте! У меня возникла проблема с ШИМ. Использую Atmega8+L293D+китайский моторчик....

Проблема с третьим таймером-счетчиком на Atmega128
Всем привет. Друзья нужна ваша помощь. Работаю с: Atmega128 в CodeVision AVR (2.04.4a). Запустил...

Проблема с delay_ms и не только в Atmega8
Добрый день уважаемые дамы и господа. Постараюсь изложить суть вопроса наиболее подробно. Есть у...

проблема с таймером 1
написал прогу в которой работает таймер1 в реале не рабоает, почему не понятно #include...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.