Здравствуйте!
Подскажите пожалуйста как решить задачу. Написал программу по устранению дребезга кнопки, в отладчике работает и если ее вставить в основной цикл программы тоже работает, а вот в обработке прерываний не работает. Как сделать так, чтобы программа работала в обработке прерываний от T1 не только в отладчике, но и в реальности? переполнениеи T1 происходит каждые 100 Гц.
rx0 значение которое было в предыдущий раз
rx1 значение сейчас
rx2 значение, которое говорит в основном цикле программы о нажатии кнопки
;================ Инициализация таймера ТС0 ==========
BSET 7 ; Разрешение всех прерываний
ldi Temp4,1
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС0
ldi Temp4 , 0x05
out TCCR0,Temp4 ; установка предделителя
; с этого момента таймер запущен
;================ Инициализация таймера ТС1 ==========
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС1
ldi temp4, 0x01
out TCCR1A,Temp4
; с этого момента таймер запущен
.
.
.
.
.
.
.
.
;------------------------------------- Обработка прерываний от Т1 ------------------------------------------------------
TM1_OVF:
ldi Temp3 , 0xec ; Temp3:=50
out TCNT1H,Temp3 ;
out TCNT1L,Temp3
in rx1,PIND ; запись PIND--> rx1
mov rx,rx1 ;rx1-->rx
com rx1 ;инверсия rx1
andi rx1,0x40 ; маскирование
and rx1,rx0
mov rx2,rx1 ; rx2- управляющий регистр, который в основном теле программы указывает на сброс счетчика на индикаторе.
mov rx0,rx
Благодарю за ответы!
AVR, прерывание таймера ATMEGA32
- Реклама
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: AVR, прерывание таймера ATMEGA32
определитесь как-то.kostyali писал(а): rx2 значение, которое говорит в основном цикле программы о нажатии кнопки
mov rx2,rx1 ; rx2- управляющий регистр, который в основном теле программы указывает на сброс счетчика на индикаторе.
Docendo discimus
Re: AVR, прерывание таймера ATMEGA32
.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m32def.inc"
;=============== Таблица векторов прерываний =================
.cseg
.org 0
rjmp START
.org $12
rjmp TM1_OVF
.org $16
rjmp TM0_OVF
;=============== Инициализация стека
START:
ldi r16,low(RAMEND)
out spl,r16
ldi r16,high(RAMEND)
out sph,r16
;================ Инициализация портов ввода-вывода
.def Temp=R16
.def Temp3=R19
.def Temp4=R20
.def Temp5=R24
.def counter_sec=R21
.def counter_sotn=R13
.def Temp6=R26
.def bufer=R23
.def RX=R17
.def RX0=R18
.def RX1=R22
.def RX2=R25
in temp, SFIOR ; запись содержимого SFIOR в temp
andi temp, 0xFB ; логическое умножение на 11111011
out SFIOR,Temp ; запись содержимого temp в SFIOR
ldi Temp,0xC7 ;
out DDRA,Temp ;ножки 0,1,2 порта А на вывод, 3,4,5 на ввод
ldi Temp,0x38
out PortA,Temp ;включение подтягивающих резисторов PA3,4,5
ldi Temp,255 ;присвоение константы
out DDRB,Temp ;ножки порта B на вывод
out DDRC,Temp ;ножки порта C на вывод
out DDRC,Temp ;ножки порта C на вывод
out DDRC,Temp ;ножки порта C на вывод
ldi Temp,0x00
out DDRD,Temp
ldi Temp,0x40
out PORTD,Temp
;================ Инициализация начальных значений переменных
.equ sotni=100
.equ desyatki=10
.equ edinici=1
ldi rx2,0x00
ldi rx0,0x40
;================ Инициализация таймера ТС0 ==========
BSET 7 ; Разрешение всех прерываний
ldi Temp4,1
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС0
ldi Temp4 , 0x05
out TCCR0,Temp4 ; установка предделителя
; с этого момента таймер запущен
;================ Инициализация таймера ТС1
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС1
ldi temp4, 0x01
out TCCR1A,Temp4 ; установка предделителя
; с этого момента таймер запущен
;========== Программа
MAIN_PROGRAM:
;******************************************** Выполнение двоично-десятичного преобразования
mov bufer,counter_sec ;запись содержания регистра counter_sec в bufer
;========== Счетчик сотен
sotnya:
mov temp, bufer ;запись содержания регистра bufer в temp
cpi temp,sotni ;вычитание сотни из temp
brcs M1 ;if флаг n=1(число отрицательное) then переход на метку М
subi bufer, sotni ;вычитание сотни из bufer
inc counter_sotn ;counter_sotn+1
rjmp sotnya
M1:
ldi Temp,0x3E
out PortA,Temp ;разрешение вывода(0) сотен
out portC,counter_sotn ;вывод сотен в portC
ldi Temp,0
mov counter_sotn,Temp ; отчистка счетчика сотен
;========== Счетчик десятков
desyatok:
mov temp, bufer ;запись содержания регистра bufer в temp
subi temp,desyatki ;вычитание десятка из temp
brmi M2 ;if флаг n=1(число отрицательное) then переход на метку М2
subi bufer, desyatki ;вычитание десятка из bufer
inc counter_sotn ;counter_des+1=counter_sotn+1
rjmp desyatok
M2:
ldi Temp,0x3D
out PortA,Temp ;разрешение вывода(0) десятков
out portC,counter_sotn ;вывод десятков в portC
ldi Temp,0
mov counter_sotn,Temp ;отчистка счетчика десятков
;========== Счетчик единиц
edinica:
mov temp, bufer ;запись содержания регистра bufer в temp
subi temp,edinici ;вычитание единицы из temp
brmi M3 ;if флаг n=1(число отрицательное) then переход на метку М
subi bufer,edinici ;вычитание единицы из bufer
inc counter_sotn ;counter_des+1=counter_sotn+1
rjmp edinica
M3:
ldi Temp,0x3B
out PortA,Temp ;разрешение вывода(0) единиц
out portC,counter_sotn ;вывод единиц в portC
ldi Temp,0
mov counter_sotn,Temp ;отчистка счетчика единиц
;====== Обработка кнопок
in rx1,PIND
mov rx,rx1
com rx1
andi rx1,0x40
;здесь этот кусок работает (когда кнопка не нажата PIND,bit6=1
; когда кнопка нажата PIND,bit6=0
; если случается такое что rx1=1-[состояние PIND,bit6 сейчас]
; а rx0=0-[состояние PIND,bit6 в предыдущий раз], то в rx2,bit6
; записывается 1 )
and rx1,rx0
mov rx2,rx1
mov rx0,rx
sbrs rx2,6 ; если rx2,bit6=1 то счетчик сбрасывается
rjmp exit1
ldi counter_sec, 0x00
ldi temp, 0x00
ldi bufer, 0x00
exit1:
;***********************************************************************************************************
rjmp MAIN_PROGRAM
;================= ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЙ
;--------------------- Обработка прерываний от Т0 ---------------------------------------------------------
TM0_OVF:
inc counter_sec ; counter_sec+1
ldi Temp6, 0x50
out TCNT0,Temp6
reti
;------------------------------------- Обработка прерываний от Т1 ------------------------------------------------------
TM1_OVF:
ldi Temp3 , 0xec
out TCNT1H,Temp3
out TCNT1L,Temp3
in rx1,PIND
mov rx,rx1
com rx1
andi rx1,0x40 ; здесь этот кусок не работает, не могу понять почему
and rx1,rx0
mov rx2,rx1
mov rx0,rx
retii
;=============== Таблица векторов прерываний =================
.cseg
.org 0
rjmp START
.org $12
rjmp TM1_OVF
.org $16
rjmp TM0_OVF
;=============== Инициализация стека
START:
ldi r16,low(RAMEND)
out spl,r16
ldi r16,high(RAMEND)
out sph,r16
;================ Инициализация портов ввода-вывода
.def Temp=R16
.def Temp3=R19
.def Temp4=R20
.def Temp5=R24
.def counter_sec=R21
.def counter_sotn=R13
.def Temp6=R26
.def bufer=R23
.def RX=R17
.def RX0=R18
.def RX1=R22
.def RX2=R25
in temp, SFIOR ; запись содержимого SFIOR в temp
andi temp, 0xFB ; логическое умножение на 11111011
out SFIOR,Temp ; запись содержимого temp в SFIOR
ldi Temp,0xC7 ;
out DDRA,Temp ;ножки 0,1,2 порта А на вывод, 3,4,5 на ввод
ldi Temp,0x38
out PortA,Temp ;включение подтягивающих резисторов PA3,4,5
ldi Temp,255 ;присвоение константы
out DDRB,Temp ;ножки порта B на вывод
out DDRC,Temp ;ножки порта C на вывод
out DDRC,Temp ;ножки порта C на вывод
out DDRC,Temp ;ножки порта C на вывод
ldi Temp,0x00
out DDRD,Temp
ldi Temp,0x40
out PORTD,Temp
;================ Инициализация начальных значений переменных
.equ sotni=100
.equ desyatki=10
.equ edinici=1
ldi rx2,0x00
ldi rx0,0x40
;================ Инициализация таймера ТС0 ==========
BSET 7 ; Разрешение всех прерываний
ldi Temp4,1
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС0
ldi Temp4 , 0x05
out TCCR0,Temp4 ; установка предделителя
; с этого момента таймер запущен
;================ Инициализация таймера ТС1
out TIMSK,Temp4 ; разрешение прерывания от таймера ТС1
ldi temp4, 0x01
out TCCR1A,Temp4 ; установка предделителя
; с этого момента таймер запущен
;========== Программа
MAIN_PROGRAM:
;******************************************** Выполнение двоично-десятичного преобразования
mov bufer,counter_sec ;запись содержания регистра counter_sec в bufer
;========== Счетчик сотен
sotnya:
mov temp, bufer ;запись содержания регистра bufer в temp
cpi temp,sotni ;вычитание сотни из temp
brcs M1 ;if флаг n=1(число отрицательное) then переход на метку М
subi bufer, sotni ;вычитание сотни из bufer
inc counter_sotn ;counter_sotn+1
rjmp sotnya
M1:
ldi Temp,0x3E
out PortA,Temp ;разрешение вывода(0) сотен
out portC,counter_sotn ;вывод сотен в portC
ldi Temp,0
mov counter_sotn,Temp ; отчистка счетчика сотен
;========== Счетчик десятков
desyatok:
mov temp, bufer ;запись содержания регистра bufer в temp
subi temp,desyatki ;вычитание десятка из temp
brmi M2 ;if флаг n=1(число отрицательное) then переход на метку М2
subi bufer, desyatki ;вычитание десятка из bufer
inc counter_sotn ;counter_des+1=counter_sotn+1
rjmp desyatok
M2:
ldi Temp,0x3D
out PortA,Temp ;разрешение вывода(0) десятков
out portC,counter_sotn ;вывод десятков в portC
ldi Temp,0
mov counter_sotn,Temp ;отчистка счетчика десятков
;========== Счетчик единиц
edinica:
mov temp, bufer ;запись содержания регистра bufer в temp
subi temp,edinici ;вычитание единицы из temp
brmi M3 ;if флаг n=1(число отрицательное) then переход на метку М
subi bufer,edinici ;вычитание единицы из bufer
inc counter_sotn ;counter_des+1=counter_sotn+1
rjmp edinica
M3:
ldi Temp,0x3B
out PortA,Temp ;разрешение вывода(0) единиц
out portC,counter_sotn ;вывод единиц в portC
ldi Temp,0
mov counter_sotn,Temp ;отчистка счетчика единиц
;====== Обработка кнопок
in rx1,PIND
mov rx,rx1
com rx1
andi rx1,0x40
;здесь этот кусок работает (когда кнопка не нажата PIND,bit6=1
; когда кнопка нажата PIND,bit6=0
; если случается такое что rx1=1-[состояние PIND,bit6 сейчас]
; а rx0=0-[состояние PIND,bit6 в предыдущий раз], то в rx2,bit6
; записывается 1 )
and rx1,rx0
mov rx2,rx1
mov rx0,rx
sbrs rx2,6 ; если rx2,bit6=1 то счетчик сбрасывается
rjmp exit1
ldi counter_sec, 0x00
ldi temp, 0x00
ldi bufer, 0x00
exit1:
;***********************************************************************************************************
rjmp MAIN_PROGRAM
;================= ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЙ
;--------------------- Обработка прерываний от Т0 ---------------------------------------------------------
TM0_OVF:
inc counter_sec ; counter_sec+1
ldi Temp6, 0x50
out TCNT0,Temp6
reti
;------------------------------------- Обработка прерываний от Т1 ------------------------------------------------------
TM1_OVF:
ldi Temp3 , 0xec
out TCNT1H,Temp3
out TCNT1L,Temp3
in rx1,PIND
mov rx,rx1
com rx1
andi rx1,0x40 ; здесь этот кусок не работает, не могу понять почему
and rx1,rx0
mov rx2,rx1
mov rx0,rx
retii
Re: AVR, прерывание таймера ATMEGA32
Указанные команды "портят" флаги!kostyali писал(а):com rx1
andi rx1,0x40 ; здесь этот кусок не работает, не могу понять почему
and rx1,rx0
Для начала, при входе в прерывание сохраните флаги и все, что может быть подпорчено, при выходе - восстановите.
— Не говорите мне что делать и я не скажу куда Вам идти...
Re: AVR, прерывание таймера ATMEGA32
md5sum писал(а):kostyali писал(а): Для начала, при входе в прерывание сохраните флаги и все, что может быть подпорчено, при выходе - восстановите.
а что может быть подпорчено еще кроме флагов? вот так восстанавливать?[красным цветом] а сохранять в смысле посмотреть и запомнить по отладчику? в обработке прерываний от T0 так же флаги лучше восстанавливать?
;------------------------------------- Обработка прерываний от Т1 ------------------------------------------------------
TM1_OVF:
ldi Temp3 , 0xec
out TCNT1H,Temp3
out TCNT1L,Temp3
in rx1,PIND
mov rx,rx1
com rx1
andi rx1,0x40 ; здесь этот кусок не работает, не могу понять почему
and rx1,rx0
mov rx2,rx1
mov rx0,rx
ses
sen
clz
retii
- Реклама
Re: AVR, прерывание таймера ATMEGA32
В самом начале прерывания:
Перед reti:
Код: Выделить всё
push Temp
in Temp, SREG
push Temp
Код: Выделить всё
pop Temp
out SREG, Temp
pop Temp
— Не говорите мне что делать и я не скажу куда Вам идти...
Re: AVR, прерывание таймера ATMEGA32
TM1_OVF:
push Temp
in Temp,SREG
push Temp
push Temp4
ldi Temp4 , 0xec
out TCNT1H,Temp4
out TCNT1L,Temp4
in rx1,PIND
mov rx,rx1
com rx1
and rx1,rx0
mov rx2,rx1
mov rx0,rx
pop Temp4
pop Temp
out SREG, Temp
pop Temp
reti
благодарю за помощь! но это не помогло, по прежнему в отладчике работает, а в реальности нет.
push Temp
in Temp,SREG
push Temp
push Temp4
ldi Temp4 , 0xec
out TCNT1H,Temp4
out TCNT1L,Temp4
in rx1,PIND
mov rx,rx1
com rx1
and rx1,rx0
mov rx2,rx1
mov rx0,rx
pop Temp4
pop Temp
out SREG, Temp
pop Temp
reti
благодарю за помощь! но это не помогло, по прежнему в отладчике работает, а в реальности нет.


