Программа 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);
}