Страница 1 из 1
Частотометр на ассемблере
Добавлено: Вт фев 19, 2013 02:33:11
maks_m4a1
Хочу зделать цветомузыку и вот пытаюсь разбить частоты, в данном примере на 4 диапазона. Засекаю прерывания int0 по отсутствею напряжения и тогда запускаю таймер, когда прошел импульс и напряжение опять пропало, таймер останавливаю и сверяюсь с полученым значением count. В Протеусе собрал схему с МК и пару диодов, только моргает постоянно один. Начал дебажить, и посмотрев значение регистров, понял что count постоянно висит на 0, то есть не инкрементируется. МК: тини13
Код: Выделить всё
.cseg
.def count = r20
.def line0 = r21
.def line1 = r22
.def line2 = r23
.def line3 = r24
.org 0
rjmp init
.org 1
rjmp impulse
.org 3 ;Задание адреса прерывания по переполнению таймера 0
rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
init:
ldi line0, (1<<0)
ldi line1, (1<<2)
ldi line2, (1<<3)
ldi line3, (1<<4)
ser r16 ; all bits into 1
out DDRB, r16
clr r16
out PORTB, r16
ldi r16, RAMEND;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPL, r16 ;Копирование значения из r16 в регистр указателя стека SPL
ldi r16, (1<<INT0) ; toggle interupt int0
out GIMSK, r16
clr r30
sei
main: ;Основной цикл программы
rjmp main ;Вернуться к метке main
impulse:
cli
out TIMSK0,r30 ; timer's stopped
out PORTB, r30
cpi count, $14
brlo khz5; if count < 20
cpi count, $3C
brsh more15; if count > 60
cpi count, $14 ;if >20
brsh more5
cpi count, $28; if >40
brsh more10
clr count
ldi r16, (1<<CS00);
out TCCR0B,r16 ;Копирование значения из регистра r16 в регистр TCCR0B
ldi r16, (1<<TOIE0) ;Загрузка в регистр r16 "1", смещенной на TOIE0 (переполнение таймера 0)
out TIMSK0,r16 ;Копирование значения из регистра r16 в регистр TIMSK0
ldi r16, RAMEND;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPL, r16 ;Копирование значения из r16 в регистр указателя стека SPL
sei
reti
timer0_ovf:
inc count
reti
more5:
cpi count, $28
brlo khz10
reti
more10:
cpi count, $3C
brlo khz15
reti
khz5:
out PORTB, line0
reti
khz10:
out PORTB, line1
reti
khz15:
out PORTB, line2
reti
more15:
out PORTB, line3
reti
Re: Частотометр на ассемблере
Добавлено: Вт фев 19, 2013 06:36:52
blackx
А БПФ не пробовали прикрутить? Есть готовые решения под МК.
Re: Частотометр на ассемблере
Добавлено: Вт фев 19, 2013 07:22:58
Kavka
maks_m4a1 писал(а):Хочу зделать цветомузыку и вот пытаюсь разбить частоты, в данном примере на 4 диапазона. Засекаю прерывания int0 по отсутствею напряжения и тогда запускаю таймер
Музыка это обычно сигнал произвольной формы и амплитуды. Как вы на цифровом входе собираетесь выделять частоты? Вам или внешние аналоговые фильтры ставить. Или делать цифровую обработку сигнала. Один, и почти единственный, вариант blackx уже предложил. У
Чана есть, например.
Re: Частотометр на ассемблере
Добавлено: Вт фев 19, 2013 10:09:46
BOB51
А если в качестве входной подготовки данных использовать LM 3914/15/16 c полосовыми фильтрами на входе и обрабатывать уже псевдоцифровой сигнал на их выходе?

Re: Частотометр на ассемблере
Добавлено: Вт фев 19, 2013 16:06:43
kolobok0
maks_m4a1 писал(а):...Начал дебажить, и посмотрев значение регистров, понял что count постоянно висит на 0, то есть не инкрементируется....
не верю...
не верю, что дебажили.
1) с какого перепою таймер должен срабатывать? краевые условия не выполнены - нет инициализации его просто.
2) ну вот отработало у вас прерывание по уровню ножки. окейно. первым делом вы выключаете таймер - ок. и если счётчик ваш меньше 20 то..... то кто включит таймер???
т.е. на лицо проблемы с логикой.
вы даже логически не _обозначили_ код который должен работать. впечатление такое - что надёргали с плохой курсовой...
напишите по русски сначала. что хотите сделать. прямо в листинге кода, ставите коментарии и вперёд. по русски напишите. типа - тут инициализируются все переменные - список переменных. тут железо - список железа. тут основной цикл - пустой, так как.... тут прерывание от таймера... и т.д. и т.п...
потом читая по русски вашу программу мысленно пройдитесь последовательно по всем этапам. как оно будет в железе, на ваш взгляд.
когда всё это сделаете. переписать из русского в любой код - не составит вам труда вообще...
удачи вам
(круглый)
Re: Частотометр на ассемблере
Добавлено: Ср фев 20, 2013 00:22:25
maks_m4a1
kolobok0 писал(а):maks_m4a1 писал(а):...Начал дебажить, и посмотрев значение регистров, понял что count постоянно висит на 0, то есть не инкрементируется....
не верю...
не верю, что дебажили.
1) с какого перепою таймер должен срабатывать? краевые условия не выполнены - нет инициализации его просто.
2) ну вот отработало у вас прерывание по уровню ножки. окейно. первым делом вы выключаете таймер - ок. и если счётчик ваш меньше 20 то..... то кто включит таймер???
т.е. на лицо проблемы с логикой.
вы даже логически не _обозначили_ код который должен работать. впечатление такое - что надёргали с плохой курсовой...
напишите по русски сначала. что хотите сделать. прямо в листинге кода, ставите коментарии и вперёд. по русски напишите. типа - тут инициализируются все переменные - список переменных. тут железо - список железа. тут основной цикл - пустой, так как.... тут прерывание от таймера... и т.д. и т.п...
потом читая по русски вашу программу мысленно пройдитесь последовательно по всем этапам. как оно будет в железе, на ваш взгляд.
когда всё это сделаете. переписать из русского в любой код - не составит вам труда вообще...
удачи вам
(круглый)
Очень занимательно, конечно, но, простите, я тоже не пальцами делан и писал проекты далеко не на одну тысячу строк и бывали такие моменты, когда возможности не было посмотреть место ошибки в тот момент, когда программа не работала, и это приходилось исправлять. Да, я не отрицаю: интерпретированный язык программирования высокого уровня далеко не ассемблер, но что то я да таки знаю на практике.
Почему Вы утверждаете, что таймер не запущен? После выполнения условий я постоянно возвращаюсь на метку "импульс", а дальше делаю переинициализацию таймера, заново выставляю быти и опять разрешаю прерывания, пока в очередной раз не произойдет пара повышение-понижение напряжения.
А БПФ не пробовали прикрутить? Есть готовые решения под МК.
Впервые слышу.Гуглю.
Re: Частотометр на ассемблере
Добавлено: Ср фев 20, 2013 07:21:24
akl
Поддержу
kolobok0 (круглого). Вы не прогоняли код с симуляторе. Вот хоть как-то, в моем понимании, работающее начало. Но, без запуска таймера не работает. С запуском тоже не работает, т.к. счетчик не наращивается при останавливаемом в обработчике таймере.
Спойлер
Код: Выделить всё
.INCLUDE "tn13def.inc"
.cseg
.def count = r20
.def line0 = r21
.def line1 = r22
.def line2 = r23
.def line3 = r24
.org 0
rjmp init
.org 1
rjmp impulse
.org 3 ;Задание адреса прерывания по переполнению таймера 0
timer0_ovf:
inc count
reti
;rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
init:
ldi line0, (1<<0)
ldi line1, (1<<2)
ldi line2, (1<<3)
ldi line3, (1<<4)
ser r16 ; all bits into 1
out DDRB, r16
;*************************************************
OUT PORTB,R16
LDI R16,$3D
OUT DDRB,R16
;*************************************************
clr r16
out PORTB, r16
;*************************************************
; ненужные для этого камня команды
;ldi r16, RAMEND;Загрузка в регистр r16 адреса верхней границы ОЗУ
;out SPL, r16 ;Копирование значения из r16 в регистр указателя стека SPL
;*************************************************
ldi r16, (1<<INT0) ; toggle interupt int0 ???????????? разрешить прерывание INT0
out GIMSK, r16
LDI R19,0b00000010 ; обработка прерывания каждого спада falling
OUT MCUCR,R19
;*************************************************
clr r30
;*************************************************
SER R16
OUT GIFR,R16
OUT TIFR0,R16
; ldi r16, (1<<CS00);
; out TCCR0B,r16 ;Копирование значения из регистра r16 в регистр TCCR0B
;*************************************************
sei
main: ;Основной цикл программы
rjmp main ;Вернуться к метке main
impulse:
out TIMSK0,r30 ; timer's stopped
out PORTB, r30
cpi count, $14
brlo khz5; if count < 20
cpi count, $3C
brsh more15; if count > 60
cpi count, $14 ;if >20
brsh more5
cpi count, $28; if >40
brsh more10
clr count
ldi r16, (1<<CS00);
out TCCR0B,r16 ;Копирование значения из регистра r16 в регистр TCCR0B
ldi r16, (1<<TOIE0) ;Загрузка в регистр r16 "1", смещенной на TOIE0 (переполнение таймера 0)
out TIMSK0,r16 ;Копирование значения из регистра r16 в регистр TIMSK0
reti
more5:
cpi count, $28
brlo khz10
reti
more10:
cpi count, $3C
brlo khz15
reti
khz5:
out PORTB, line0
reti
khz10:
out PORTB, line1
reti
khz15:
out PORTB, line2
reti
more15:
out PORTB, line3
reti