Устройство цифровой записи речи (цифровой диктофон)

Когда преобразование закончено, возникает прерывание. Процедура прерывания выполняет цикл для заполнения пустых 62 циклов (510–448), перед началом нового преобразования.

Результатом 10-разрядного преобразования является величина на входе АЦП, которая появляется через 2 цикла после начала преобразования. Эти 10 бит перекрывают диапазон от AGND до AREF (в данном примере от 0 до 5В). Выходной сигнал цепи микрофона ограничен диапазоном 2.3В…3.5В. Поэтому из результата 10-разрядного преобразования вычитается минимальное входное напряжение. Это 0x1D5 для 2.3В. Часть данных, представляющих сигнал величиной выше 3.5В, убирается путём удаления двух MSB. Это делается автоматически, когда результат преобразования передаётся в подпрограмму «запись во флэш», так как эти переменные «flash_data» определяются типом «char» (8-бит). Последние 8-бит данных должны быть записаны в DataFlash перед следующим прерыванием преобразования.


Рисунок 13. Запись

Запись данных в DataFlash


Рисунок 14. Запись в DataFlash

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

В подпрограмме «write_to_flash» переменная «j» соответствует номеру байта в буфере, а переменная «k» номеру страницы, в которую будет записываться содержимое буфера. Если флаг новых данных показывает, что DataFlash пуста, то оба счётчика устанавливаются в нуль.

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

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

Для записи данных в буфер, линия #CS переводится в низкое состояние и в DataFlash загружается операционный код 0x84. Это следует за 14 не имеющими смысла битами и 10-битовым адресом положения внутри буфера. Затем вводятся 8-бит данных.

Эта последовательность передаётся «ведомому» побайтно. После каждого байта проверяется регистр состояния SPI (SPSR), пока флаг прерывания SPI не покажет, что последовательная передача завершена. После записи всей последовательности линия #CS переводится в высокое состояние.

Если буфер заполнен и остались пустые страницы, то буфер копируется на следующую страницу DataFlash. Так как память была очищена раньше, то данные могут быть записаны без дополнительного стирания.

Если память заполнена, то цикл выполняется, пока нажата кнопка «запись». Любые данные, записанные в то время, когда память уже заполнена, будут потеряны.

Воспроизведение

В процедуре «воспроизведения», содержимое DataFlash считывается и модулируется как 8-разрядная ШИМ на частоте 15.686 Гц. Для достижения большей скорости, данные не читаются напрямую из основной памяти, а передаются в один из двух буферов и затем читаются из буфера. В это время копируется следующая страница памяти в другой буфер. Для ШИМ, 16-разрядный Таймер/Счётчик 1 используется с выходом ШИМ на OC1B. Это описывается в регистре управления Таймера/Счётчика A и B (TCCRA/TCCRB). Для запуска ШИМ с возможной наибольшей частотой, делитель тактовой частоты ШИМ устанавливается в 1.

Когда установка завершена, первая страница копируется в буфер 1, посредством перевода линии #CS в низкое состояние и передачей соответствующих команд в DataFlash. Передача страницы в буфер начинается, когда линия #CS переводится снова в высокое состояние. Когда состояние на выводе Ready/Busy меняется памятью DataFlash на высокое, то это означает, что буфер 1 содержит действительные данные. Затем начинается передача следующей страницы в буфер 2. Так как оба буфера независимы друг от друга, то данные могут всегда читаться из буфера 1, пока DataFlash остаётся занятой копированием данных из второй страницы в буфер 2.

Для чтения байта из буфера, в DataFlash должна быть записана фиктивная величина. Операция записи «ведущего» в SPI «ведомого» приводит к тому, что содержимое его регистра данных SPI (SPDR) будет изменено. После записи фиктивного байта в DataFlash, регистр SPDR микроконтроллера AVR содержит выходные данные из DataFlash.


Рисунок 15. Воспроизведение

Когда значения ШИМ счётчика равно «0», Таймер 1 вызывает прерывание переполнения. Это прерывание используется для синхронизации выходных данных из DataFlash частотой ШИМ. Когда значение из буфера сдвигается в микроконтроллер AVR, цикл выполняется до тех пор, пока Таймер 1 не вызовет прерывание переполнения. Затем данные записываются в выходной регистр сравнения Таймера/Счётчика 1 B (OCR1B), автоматически защёлкивая выход ШИМ, когда счётчик ШИМ достигнет максимального значения (255 для 8-разрядной ШИМ).

После того как считается последнее значение из буфера, активный буфер переключится.

Если воспроизведена вся память, то все прерывания отключены и Таймер/Счётчик 1 остановлен.


Рисунок 16. Следующая страница в следующий буфер


Рисунок 17. Активный буфер в динамик

Изменение и оптимизация

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

Данные, записанные в DataFlash, полностью соответствуют данным, считанным с АЦП. В случае записи в течение большого промежутка времени или записи стерео сигнала может потребоваться упаковка этих данных.

В этом примере приведены два способа применения флага состояния.

Первый способ – использование глобальной переменной (т.е. переменная «wait» используется в подпрограмме «playback»). Второй способ – использование незадействованного бита в регистре. В подпрограмме «стирания», используется бит ACIS1 (регистра управления и состояния аналогового компаратора (ACSR))для отображения того, что следующими этапом должно быть сохранение новых данных.

Частота выборки равная 15.686 Гц (приблизительно 510 циклов), генерируется с помощью прерывания АЦП и цикла задержки. Она может быть заменена независимым таймером (Таймер/Счётчик 0 или Таймер/Счётчик 2), если он не используется для других целей.


Пример программы на языке C

/* Очистка всех страниц в случае необходимости. Запись данных в буфер 1. Если буфер заполнен,

то его содержимое записывается в страницу памяти. Чтение DataFlash через буфер 1 и буфер 2 в

регистр данных.

*/

#include “io8535.h”

#include

#include “stdlib.h”

#include “dataflash.h”

// прототипы

void setup (void);

void erasing (void);

void recording (void);

void interrupt[ADC_vect] sample_ready (void);

void write_to_flash (unsigned char ad_data);

void playback (void);

void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter);

void interrupt[TIMER1_OVF1_vect] out_now(void);

void active_buffer_to_speaker (unsigned char active_buffer);

// глобальные переменные

volatile unsigned char wait = 0;

void setup(void)

{

DDRB = 0xBD;             // Инициализация порта SPI

// SCK, MISO, MOSI, CS, LED, WP , RDYBSY, RST

// PB7, PB6, PB5, PB4, PB3, PB2 , PB1, PB0

//  O    I    O    O    O    O     I    O

//  1    0    1    1    1    1     0    1

PORTB = 0xFF;           // все выходы в высоком состоянии, на входах

   нагрузочные резисторы (LED погашен)

DDRA = 0x00;              // Port A определяется как вход

PORTA = 0x00;

DDRD = 0x10;              // Port D определяется как вход (D4: выход)

_SEI();                          // прерывания разрешены

}

void erasing(void)

unsigned int block_counter = 0;

unsigned char temp = 0x80;

ACSR

void recording(void)

{

// прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4

SPCR = 0x5C;

ADMUX = 0x00; // номер входного вывода АЦП = 0

ADCSR = 0xDD; // одиночное АЦ преобразование, fCK/32, старт

    преобразования

while (!(PIND & 8)); // цикл продолжается пока нажата кнопка записи

    (кнопка 3)

ADCSR = 0x00; // выключение АЦП

SPCR = 0x00;  // выключение SPI

}

void interrupt[ADC_vect] sample_ready(void)

= 0x40;                       // старт нового АЦ преобразования

write_to_flash(ADC-0x1D5); // чтение данных, преобразование 8 бит и

   сохранение во флэш

void write_to_flash(unsigned char flash_data)

{

static unsigned int buffer_counter;

static unsigned int page_counter;

unsigned char temp = 0x80;

if((ACSR & 0x02)) // если флаг установлен, то новые данные должны быть

 установлены

{

buffer_counter = 0;

page_counter = 0;   // сброс счётчика если должны быть записаны

   новые данные

ACSR &= 0xFD;          // очистка флага сигнала

}

while(!(PINB & 0x02)); // проверка занятости флэша

PORTB &= ~DF_CHIP_SELECT;       // включение DataFlash

SPDR = BUFFER_1_WRITE;

while (!(SPSR & temp));            // ожидание завершения передачи

SPDR = 0x00;                           // не важно

while (!(SPSR & temp));            // ожидание завершения передачи

SPDR = (char)(buffer_counter>>8); // не важно + первые два бита буфера

    адреса

while (!(SPSR & temp));                         // ожидание завершения передачи

SPDR = (char)buffer_counter;    // буфер адреса (макс. 2^8 = 256

    страниц)

while (!(SPSR & temp));                         // ожидание завершения передачи

SPDR = flash_data;                   // запись данных в регистр данных SPI

while (!(SPSR & temp));            // ожидание завершения передачи

PORTB |= DF_CHIP_SELECT;            // выключение DataFlash

buffer_counter++;

if (buffer_counter > 528)            // если буфер заполнен, то его

  содержимое записывается в страницу памяти

{

buffer_counter = 0;

if (page_counter < 4096) // если память не заполнена

PORTB &= ~DF_CHIP_SELECT;       // включить DataFlash

SPDR = B1_TO_MM_PAGE_PROG_WITHOUT_ERASE; // записать

данные из буфера 1 в страницу

while (!(SPSR & temp));            // ожидание завершения

   передачи

SPDR = (char)(page_counter>>6);

while (!(SPSR & temp));            // ожидание завершения

   передачи

SPDR = (char)(page_counter<<2);

while (!(SPSR & temp));            // ожидание завершения

Страницы: 1, 2, 3, 4, 5



Реклама
В соцсетях
рефераты скачать рефераты скачать рефераты скачать рефераты скачать рефераты скачать рефераты скачать рефераты скачать