Программа 29

Программа 29.2. Пример программы на языке Си

/* CIRCBUF.C */
/* Это программа генерации эха, написанная на Си для ADSP-21061 EZ-KIT Lite */
/* Эта программа использует базовую программу прямой передачи входных данных */
/* (talkthrough) на выход и дополнительно использует схему циклической буферизации */
/* Циклический буфер инициализируется функциями CIRCULAR_BUFFER, BASE и LENGTH */
/* Эхо формируется добавлением к текущему входному отсчёту самого старого */
/* записанного в циклический буфер входного отсчёта */
/* Задержка эха может регулироваться значением параметра BUFF_LENGTH */
/* */
#include <21020.h> /* для команды idle() */
#include <signal.h> /* для команды interrupt */
#include <macros.h> /* для функций CIRCULAR_BUFFER() и segment() */
#define BUFF_LENGTH 4000
CIRCULAR_BUFFER (float,1,echo) /* инициализирует переменную echo,
/* как указатель на */
/* циклический буфер в памяти данных. Значение указателя хранится в регистре i1 */
/* генератора адреса данных DAG1 */
volatile float in_port segment (hip_reg0); /* объекты hip_reg0 и hip-reg2 */
volatile float out_port segment (hip_reg2); /* используются в файле архитектуры */

void process_input (int);
void main (void)
{/* Длину циклического буфера можно менять. Если остановить выполнение программы в */
/* теле функции main и в окне отображения памяти dm изменить параметр _BUFF_LENGTH */
/* то задержка эха изменится. Но не делайте BUFF_LENGTH больше, чем размер стека! */
float data_buff [BUFF_LENGTH];
interrupt (SIG_IRQ3, process_input);
BASE (echo) = data_buff; /* Загружает в b1 и i1 начальный адрес буфера */
LENGTH (echo) = BUFF_LENGTH; /* Загружает в L1 длину буфера */
/* когда циклический буфер полностью заполнен, n-й его элемент содержит самый */
/* новый отсчёт, а (n + 1)-й элемент содержит самый старый отсчёт */

while (1)
{
float oldest, newest; /* Добавление эха означает суммирование самого нового */
idle(); /* и самого старого отсчётов */

/* После обработки прерывания переменная echo указывает на n-й элемент */
/* циклического буфера. Новый отсчёт записывается в переменную 'newest'. */
/* Затем указатель увеличивается на единицу и переходит к элементу n + 1 */

CIRC_READ (echo, 1, newest, dm);

/* Теперь переменная echo указывает на (n + 1)-й элемент. Происходит чтение */
/* переменной 'oldest'. Указатель не изменяется, так как теперь он указывает */
/* на элемент, в который после следующего прерывания будет записан новый отсчёт */
CIR_READ (echo, 0, oldest, dm);

/* Суммируем самый старый и самый новый отсчёты и результат отправляем на выход */
out_port=oldest+newest;
}
}
void process_input (int int_number)
{
/* Новый входной отсчёт записывается в циклический буфер на место самого старого */
/* отсчёта в n-й элемент. Указатель не изменяется */

CIRC_WRITE (echo, 0, in_port, dm);
}