Студентам > Курсовые > Устройство цифровой записи речи (цифровой диктофон)
Устройство цифровой записи речи (цифровой диктофон)Страница: 6/8
Пример программы на языке 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 1PORTB = 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 |= 0x02; // установка флага, показывающего, что следующим этапом должна быть запись данных // прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4SPCR = 0x5C; while (block_counter < 512){PORTB &= ~DF_CHIP_SELECT; // включение DataFlashSPDR = BLOCK_ERASE;while (!(SPSR & temp)); // ожидание завершения передачиSPDR = (char)(block_counter>>3);while (!(SPSR & temp)); // ожидание завершения передачиSPDR = (char)(block_counter<<5);while (!(SPSR & temp)); // ожидание завершения передачиSPDR = 0x00; // не важноwhile (!(SPSR & temp)); // ожидание завершения передачиPORTB |= DF_CHIP_SELECT; // выключение DataFlash block_counter++;while(!(PINB & 0x02)); // ожидание очистки блока}SPCR = 0x00; //отключение SPI} void recording(void){// прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4 SPCR = 0x5C;ADMUX = 0x00; // номер входного вывода АЦП = 0ADCSR = 0xDD; // одиночное АЦ преобразование, fCK/32, старт преобразованияwhile (!(PIND & 8)); // цикл продолжается пока нажата кнопка записи (кнопка 3) ADCSR = 0x00; // выключение АЦПSPCR = 0x00; // выключение SPI} void interrupt[ADC_vect] sample_ready(void){unsigned char count = 0; while (count < 6) count++; // ожидание в течение нескольких цикловADCSR |= 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; // запись данных в регистр данных SPIwhile (!(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)); // ожидание завершения передачиSPDR = 0x00; // не важноwhile (!(SPSR & temp)); // ожидание завершения передачи PORTB |= DF_CHIP_SELECT; // выключение DataFlash page_counter++;}else{PORTB |= 0x08; // погасить LED while (!(PIND & 8)); // ждать пока кнопка записи не отпущена (кнопка 3)}}} void playback(void){unsigned int page_counter = 0;unsigned int buffer_counter = 0;unsigned char active_buffer = 1; // активный буфер = буфер 1unsigned char temp = 0x80; TCCR1A = 0x21; // 8 бит ШИМ, используется COM1BTCNT1 = 0x00; // обнуление счётчика 1TIFR = 0x04; // сброс флага превышения счётчика 1 TIMSK = 0x04; // разрешение прерывания переполнения счётчика 1 TCCR1B = 0x01; // коэф. Пересчёта счётчика 1 = 1OCR1B = 0x00; // обнуление выходного регистра сравнения B // прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4 SPCR = 0x5C; next_page_to_next_buffer (active_buffer, page_counter); // чтение страницы 0 в буфер 1 while (!(PINB & 0x02)); // ожидание завершения передачи данных из страницы 0 в буфер 1while ((page_counter < 4095)&(!(PIND & 2))) // пока кнопка воспроизведения (кнопка 1) нажата{page_counter++; // теперь берём следующую страницу next_page_to_next_buffer (active_buffer, page_counter);active_buffer_to_speaker (active_buffer); if (active_buffer == 1) // если буфер 1 является активным буфером{active_buffer++; // то устанавливаем буфер 2 в качестве активного}else // иначе{active_buffer--; // устанавливаем буфер 1 в качестве активного}}TIMSK = 0x00; // запрещаем все прерыванияTCCR1B = 0x00; // останавливаем счётчик 1SPCR = 0x00; // отключаем SPI} void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter){unsigned char temp = 0x80;while(!(PINB & 0x02)); // ждём, пока флэш не освободится PORTB &= ~DF_CHIP_SELECT; // включаем DataFlash if (active_buffer == 1) // если буфер 1 активный{SPDR = MM_PAGE_TO_B2_XFER; // то передаём следующую страницу в буфер 2}else // иначе{SPDR = MM_PAGE_TO_B1_XFER; // передаём следующую страницу в буфер 1 }while (!(SPSR & temp)); // ожидаем завершения передачиSPDR = (char)(page_counter >> 6);while (!(SPSR & temp)); // ожидаем завершения передачиSPDR = (char)(page_counter << 2);while (!(SPSR & temp)); // ожидаем завершения передачиSPDR = 0x00; // записываем не имеющий значения байтwhile (!(SPSR & temp)); // ожидаем завершения передачиPORTB |= DF_CHIP_SELECT; // выключаем DataFlash и начинаем передачу} void interrupt[TIMER1_OVF1_vect] out_now(void){wait = 0; // возникновение прерывания} void active_buffer_to_speaker (unsigned char active_buffer){// пока активный буфер не очистится воспроизводим его содержимое на динамикеunsigned int buffer_counter = 0;unsigned char temp = 0x80; PORTB &= ~DF_CHIP_SELECT; // включение DataFlash if (active_buffer == 1) // если буфер 1 активный буфер{SPDR = BUFFER_1_READ; // то читаем из буфера 1}else // иначе{SPDR = BUFFER_2_READ; // читаем из буфера 2} while (!(SPSR & temp)); // ожидаем завершения передачи SPDR = 0x00; // запись не имеющего значения байтаwhile (!(SPSR & temp)); // ожидаем завершения передачиSPDR = 0x00; // запись не имеющего значения байтаwhile (!(SPSR & temp)); // ожидаем завершения передачиSPDR = 0x00; // начать с адреса 0 буфераwhile (!(SPSR & temp)); // ожидаем завершения передачиSPDR = 0x00; // запись не имеющего значения байтаwhile (!(SPSR & temp)); // ожидаем завершения передачи while (buffer_counter < 528){SPDR = 0xFF; // записываем фиктивное значение в начало сдвигового регистраwhile (!(SPSR & temp)); // ожидаем завершения передачиwhile(wait); // ожидаем прерывание переполнения таймера 1OCR1B = SPDR; // воспроизводим данные из сдвигового регистраwait = 1; // сброс флага сигнала buffer_counter++;} PORTB |= DF_CHIP_SELECT; // выключение DataFlash} void main(void){setup(); for(;;){if (!(PIND & 8)) // если кнопка записи нажата (кнопка 3){PORTB &= 0xF7; // зажигаем LEDrecording();}if (!(PIND & 4)) // если нажата кнопка очистки (кнопка 2){PORTB &= 0xF7; // зажигаем LEDerasing();while (!(PIND & 4)); // ждём пока кнопка очистки не отпущена (кнопка 2)}if (!(PIND & 2)) //если нажата кнопка воспроизведения(кнопка 1){PORTB &= 0xF7; // зажигаем LEDplayback();while (!(PIND & 2)); // ждём пока кнопка воспроизведения не отпущена (кнопка 1) }PORTB |= 0x08; // гасим LED во время «холостой» работы}} DataFlash.h // изменён 19.04.1999// для использования 8535 #include “ina90.h”#pragma language=extended // DataFlash вывод сброса порта (PB 0)#define DF_RESET 0x01 // DataFlash вывод состояния порта готов/занят (PB 1)#define DF_RDY_BUSY 0x02 // DataFlash защита от записи загрузочного сектора (PB 2)#define DF_WRITE_PROTECT 0x04 // DataFlash вывод порта выбора микросхемы (PB 4)#define DF_CHIP_SELECT 0x10 // буфер 1#define BUFFER_1 0x00 // буфер 2#define BUFFER_2 0x01 // определение всех кодов операций // запись буфера 1#define BUFFER_1_WRITE 0x84 // запись буфера 2#define BUFFER_2_WRITE 0x87 // чтение буфера 1#define BUFFER_1_READ 0x54 // чтение буфера 2#define BUFFER_2_READ 0x56 // Буфер 1 в основную страницу памяти программы с встроенным стиранием#define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83 // Буфер 2 в основную страницу памяти программы с встроенным стиранием#define B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86 // Буфер 1 в основную страницу памяти программы без встроенного стирания#define B1_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x88 // Буфер 2 в основную страницу памяти программы без встроенного стирания#define B2_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x89 // Основная страница памяти программы сквозь буфер 1#define MM_PAGE_PROG_THROUGH_B1 0x82 // Основная страница памяти программы сквозь буфер 2#define MM_PAGE_PROG_THROUGH_B2 0x85 // автоматическая перезапись страницы через буфер 1#define AUTO_PAGE_REWRITE_THROUGH_B1 0x58 // автоматическая перезапись страницы через буфер 2#define AUTO_PAGE_REWRITE_THROUGH_B2 0x59 // сравнение основной страницы памяти с буфером 1#define MM_PAGE_TO_B1_COMP 0x60 // сравнение основной страницы памяти с буфером 2#define MM_PAGE_TO_B2_COMP 0x61 // передача основной страницы памяти в буфер 1#define MM_PAGE_TO_B1_XFER 0x53 // передача основной страницы памяти в буфер 2#define MM_PAGE_TO_B2_XFER 0x55 // регистр состояния DataFlash для чтения плотности, сравнения состояний,// и состояния готов/занят#define STATUS_REGISTER 0x57 // чтение основной страницы памяти#define MAIN_MEMORY_PAGE_READ 0x52 // очистка 528 байт страницы#define PAGE_ERASE 0x81 // очистка 512 страниц#define BLOCK_ERASE 0x50 #define TRUE 0xff#define FALSE 0x00
|