Юрий Ревич - Занимательная микроэлектроника
- Название:Занимательная микроэлектроника
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2007
- Город:Санкт-Петербург
- ISBN:978-5-9775-0080-7
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Юрий Ревич - Занимательная микроэлектроника краткое содержание
Для широкого круга радиолюбителей
Занимательная микроэлектроника - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Программа для данного случая содержится в листинге 19.1.
Листинг 19.1
/==== программа вывода цифрового звука ====
;процессор mеgа8515 в режиме 8515, частота 16 МГц
.include "853 5def.inc"
.equ T_Sample = 193 ;предварительное значение для Timer 0 при 4 кГц
.equ bSample = 0 ;бит готовности к чтению
;регистры temp и DATA определены в "I2С.рrg" (Приложение 5)
.def FLAGS = r19
; прерывания
rjmp RESET ;начальный загрузчик
reti
reti
reti
reti
reti
reti
rjmp TIMO ;обработчик прерывания переполнения Timer 0
reti
reti
reti
reti
.include "I2C.prg"
RESET:
ldi temp,0b00100000
out DDRD,temp ;ОС1А — на выход
ldi temp,(1<< ;инициализация PWM
out TCCR1A,temp
ldi temp,1< ;включаем Timer1, 1/1
out TCCR1B,temp
ldi temp,(1<< ;включаем Timer0, 1/64
out TCCR0,temp
out TCNT0,T_Sample ;T_Sample=6, заряжаем таймер 0 на 4 кГц
ldi temp,(1< ;разрешаем прерывание Timer0
out TIMSK,temp
clr temp ;очищаем все регистры
out OCR1AH,temp
out OCR1AL,temp
out OCR1BH,temp
out OCR1BL,temp
ldi XH,high(Nbytes)
ldi XL,low(Nbytes) ;зарядка счетчика выводимых байт
;вместо Nbytes подставить объем записи в байтах, не более 64К
ldi YH,high(ADrWord)
ldi YL,low(ADrWord)
;вместо ADrWord можно подставить начальный адрес
;во flash-памяти, он может быть отличен от 0:0
sei ;разрешаем прерывания
loop_voice: ;читаем байт для последующего вывода
rcall read_i2c ;чтение памяти, YL,YH — адрес, в DATA — полученных байтов
sleep ;Idle-mode, проснется по прерыванию Timer0
sbrs FLAGS,bSample ;бит встает в 1 в обработчике прер. TIM0
rjmp loop_voice ;если еще не установлен, то на начало цикла
adiw YL,1;иначе увеличиваем адрес на 1
cbr FLAGS,1< ;сбрасываем бит готовности к чтению
sleep ;Idle-mode, проснется по прерыванию Timer0
in temp,TCCR0 ;проверяем, не остановлен ли таймер
tst temp
brne loop_voice ;если не остановлен, то следующий цикл
;иначе вывод звука закончен — делаем что-то еще
…
;===== обработчик прерывания от Timer 0 =====
TIM0:
out TCNT0,T_Sample ;перезаряжаем Timer0
clr temp
out OCR1AH,temp
out ОСR1AL,DATA ;занесение байта в PWM
sbr FLAGS,1< ;бит готовности к чтению — в 1
sbiw XL,1 ; уменьшаем счетчик прочитанных байтов
brne rt_pwm_ ;если он равен 0
out TCCR0,XL ;то выключаем таймер 0
out TCCR1B,XL ;и Timer 1 также
rt_pwm_:
reti ;возврат из обработчика Timer0
В начале программы мы устанавливаем Timer 1 в PWM-режим и задаем ему переключающий режим по выходу ОС1А такой, чтобы там устанавливался низкий уровень, а также запускаем его с входной частотой, равной тактовой. Прерываний от Timer 1 никаких не требуется, он будет работать непрерывно, пока мы его не выключим. Управление битрейтом мы будем осуществлять по прерыванию переполнения Timer0. Если каждый раз в него записывать некоторое число, то можно регулировать частоту таких прерываний. Включим его с частотой на входе, равной 1/64 тактовой (последняя должна быть равна 16 МГц), тогда минимальная частота на выходе будет равна 976 Гц (976,5625 Гц = 16 МГц/64/256). Мы же здесь хотим частоту как можно ближе к 4 кГц (не следует окончательно портить звук еще и изменением битрейта), поэтому мы будем записывать каждый раз в таймер число 193, и он будет считать от 193 до 255, т. е. отсчитывать 62 такта, тогда прерывание будет происходить с частотой почти ровно 4 кГц. Меняя эти параметры (указанное число и частоту на входе Timer 0), можно устанавливать другой битрейт, ограниченный в данном случае скоростью чтения из памяти по интерфейсу I 2С (при максимальной частоте шины 400 кГц эта скорость составит около 9 кбайт/с). При более скоростной памяти битрейт будет ограничен в принципе лишь скоростью работы таймера в PWM-режиме (32 кГц), но при воспроизведении такого звука могут возникнуть сложности из-за искажений. Более глубоко в этот вопрос влезать здесь нет смысла.
В процедуре прерывания мы загружаем очередной байт в Timer 1 и будем устанавливать некий флаг ( bsampieв регистре флагов), а в основной программе заведем непрерывный цикл, в котором, если этот флаг установлен, производится чтение из памяти следующего байта.
В этой программе число воспроизводимых байтов ограничено 65 536 (64 кбайт), т. к. для упрощения мы считаем их в 16-разрядном регистре х, но при необходимости несложно добавить еще один регистр счетчика адреса и задействовать большую емкость памяти (правда, для длинных клипов придется переходить на другие типы интерфейса, см. главу 16 ). В листинге 19.1 указаны теоретические начальный адрес ( ADrWord) и объем записи ( Nbytes), которые нужно для вашей задачи заменить на конкретные числа. Кроме того, по окончании звукового фрагмента программа просто остановится. Несложно сделать так, например, чтобы она «закольцевалась»: для этого вместо выключения таймера просто заново занесите значение Nbytesв регистры XHи XL. В общем, приспосабливайте программу для ваших нужд, как можете.
И еще несколько слов о том, откуда берутся исходные звуковые сэмплы. Для этого нужно записать в компьютере звук (моно!) в формате WAV, и обработать его в любом звуковом редакторе, который позволяет регулировать битрейт и глубину оцифровки (например, Sound Forge). Исходным материалом может быть как ваш собственный голос, записанный через микрофон, так и готовый звуковой клип. Формат WAV — чистый оцифрованный звук, и его можно напрямую перекачивать в нашу память. Проще всего для этого воспользоваться каким-нибудь универсальным программатором, но несложно модифицировать данную программу так, чтобы МК сам мог записывать клипы из компьютера через UART. Все необходимые сведения для создания такой программы в этой книге есть.
Аналоговая индикация может быть во многих случаях более естественным методом для создания человеко-машинных интерфейсов, чем цифровая. Как я уже указывал в главе 10 , большинство показывающих приборов на пультах управления сложными системами имеют стрелочные или шкальные индикаторы, т. к. точное значение некоего параметра человека интересует не так уж часто. Это касается даже часов: модели со стрелками не есть просто дань стилю «ретро», в некоторых ситуациях (например, когда вы кого-то ждете), они удобнее, чем с цифровым индикатором. Все определяется задачей: от медицинского термометра мы ждем точного значения температуры, от датчика температуры двигателя — лишь оценки относительно некоего порога. Вот когда нужна такая оценка, аналоговый индикатор окажется лучше цифрового.
Читать дальшеИнтервал:
Закладка: