Частотометр на ассемблере

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 13
Зарегистрирован: Вс янв 20, 2013 12:53:13

Сообщение 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
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

А БПФ не пробовали прикрутить? Есть готовые решения под МК.
Изображение only pure true norwegian blackx Изображение
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

maks_m4a1 писал(а):Хочу зделать цветомузыку и вот пытаюсь разбить частоты, в данном примере на 4 диапазона. Засекаю прерывания int0 по отсутствею напряжения и тогда запускаю таймер
Музыка это обычно сигнал произвольной формы и амплитуды. Как вы на цифровом входе собираетесь выделять частоты? Вам или внешние аналоговые фильтры ставить. Или делать цифровую обработку сигнала. Один, и почти единственный, вариант blackx уже предложил. У Чана есть, например.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Друг Кота
Аватара пользователя
Сообщения: 15749
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

А если в качестве входной подготовки данных использовать LM 3914/15/16 c полосовыми фильтрами на входе и обрабатывать уже псевдоцифровой сигнал на их выходе? :roll:
Реклама
Эиком - электронные компоненты и радиодетали
Грызет канифоль
Сообщения: 298
Зарегистрирован: Ср дек 30, 2009 09:55:39

Сообщение kolobok0 »

maks_m4a1 писал(а):...Начал дебажить, и посмотрев значение регистров, понял что count постоянно висит на 0, то есть не инкрементируется....
не верю...

не верю, что дебажили.
1) с какого перепою таймер должен срабатывать? краевые условия не выполнены - нет инициализации его просто.
2) ну вот отработало у вас прерывание по уровню ножки. окейно. первым делом вы выключаете таймер - ок. и если счётчик ваш меньше 20 то..... то кто включит таймер???

т.е. на лицо проблемы с логикой.
вы даже логически не _обозначили_ код который должен работать. впечатление такое - что надёргали с плохой курсовой...

напишите по русски сначала. что хотите сделать. прямо в листинге кода, ставите коментарии и вперёд. по русски напишите. типа - тут инициализируются все переменные - список переменных. тут железо - список железа. тут основной цикл - пустой, так как.... тут прерывание от таймера... и т.д. и т.п...
потом читая по русски вашу программу мысленно пройдитесь последовательно по всем этапам. как оно будет в железе, на ваш взгляд.

когда всё это сделаете. переписать из русского в любой код - не составит вам труда вообще...

удачи вам
(круглый)
Реклама
Родился
Сообщения: 13
Зарегистрирован: Вс янв 20, 2013 12:53:13

Сообщение maks_m4a1 »

kolobok0 писал(а):
maks_m4a1 писал(а):...Начал дебажить, и посмотрев значение регистров, понял что count постоянно висит на 0, то есть не инкрементируется....
не верю...

не верю, что дебажили.
1) с какого перепою таймер должен срабатывать? краевые условия не выполнены - нет инициализации его просто.
2) ну вот отработало у вас прерывание по уровню ножки. окейно. первым делом вы выключаете таймер - ок. и если счётчик ваш меньше 20 то..... то кто включит таймер???

т.е. на лицо проблемы с логикой.
вы даже логически не _обозначили_ код который должен работать. впечатление такое - что надёргали с плохой курсовой...

напишите по русски сначала. что хотите сделать. прямо в листинге кода, ставите коментарии и вперёд. по русски напишите. типа - тут инициализируются все переменные - список переменных. тут железо - список железа. тут основной цикл - пустой, так как.... тут прерывание от таймера... и т.д. и т.п...
потом читая по русски вашу программу мысленно пройдитесь последовательно по всем этапам. как оно будет в железе, на ваш взгляд.

когда всё это сделаете. переписать из русского в любой код - не составит вам труда вообще...

удачи вам
(круглый)
Очень занимательно, конечно, но, простите, я тоже не пальцами делан и писал проекты далеко не на одну тысячу строк и бывали такие моменты, когда возможности не было посмотреть место ошибки в тот момент, когда программа не работала, и это приходилось исправлять. Да, я не отрицаю: интерпретированный язык программирования высокого уровня далеко не ассемблер, но что то я да таки знаю на практике.
Почему Вы утверждаете, что таймер не запущен? После выполнения условий я постоянно возвращаюсь на метку "импульс", а дальше делаю переинициализацию таймера, заново выставляю быти и опять разрешаю прерывания, пока в очередной раз не произойдет пара повышение-понижение напряжения.
А БПФ не пробовали прикрутить? Есть готовые решения под МК.
Впервые слышу.Гуглю.
Реклама
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение 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
Ответить

Вернуться в «AVR»