Во-вторых, зачем два прерывания? Например, можно оставить прерывание только ЦАП, а АЦП настроить на автоматическую работу со скоростью заведомо выше скорости ЦАП. АЦП тогда будет автоматически, сам, по кругу оцифровывать нужные каналы, а ты в прерывании ЦАП будешь просто брать текущее значение, обрабатывать его и записывать в ЦАП. Можно сделать наоборот и оставить прерывание АЦП, всё зависит от требований и особенностей задачи.
В-третьих, если все же оставлять обработку в фоне, то опять не обязательно использовать два прерывания. Можно оставить только одно из них, например у АЦП, оно будет устанавливать флаг готовности, который ты будешь проверять в фоне. Когда АЦП будет готов читай из него данные, обрабатывай и пиши в ЦАП. Можно, опять же, сделать наоборот, всё зависит особенностей задачи.
В-четвертых, если ты решил оставить обработку в фоне, то использовать глобальные переменные нехорошо (чаще всего). Например, тебе нужно в фоне дожидаться готовности значения АЦП и потом забирать его. Сделай для АЦП отдельный модуль (файл) вот с такой реализацией:
Код: Выделить всё
// adc.h
// Инициализирует драйвер АЦП и запускает преобразование.
void adc_init(void);
// Возвращает истинное значение, если АЦП готов.
bool adc_is_ready(void);
// Возвращает последнее оцифрованное значение, сбрасывает флаг готовности.
u16_t adc_get_value(void);
// adc.c
static u16_t adc_value;
static bool_t adc_ready;
// Обрабатывает прерывания АЦП.
static void adc_isr(void)
{
// TODO: Копируем значение в adc_value.
adc_ready = true;
}
void adc_init(void)
{
// TODO: Инициализация периферии.
// TODO: Запускаем АЦП.
adc_value = 0;
adc_ready = false;
}
bool adc_is_ready(void)
{
return adc_ready;
}
u16_t adc_get_value(void)
{
adc_ready = false;
return adc_value;
}
Код: Выделить всё
// dac.h
// Инициализирует драйвер ЦАП.
void dac_init(void);
// Возвращает истинное значение, если ЦАП готов к записи.
bool dac_is_ready(void);
// Устанавливает значение ЦАП.
void dac_set_value(u16_t value);
// dac.c
static bool_t dac_ready;
// Обрабатывает прерывания ЦАП.
static void dac_isr(void)
{
// Преобразование ЦАП завершено, ЦАП готов принять следующее значение.
dac_ready = true;
}
void dac_init(void)
{
// TODO: Инициализация периферии.
dac_ready = true;
}
bool dac_is_ready(void)
{
return dac_ready;
}
void dac_set_value(u16_t value)
{
// TODO: Запретить прерывания ЦАП.
dac_ready = false;
// TODO: Записываем значение value в ЦАП и ждем окончание преобразования.
// TODO: Разрешить прерывания ЦАП.
}
Код: Выделить всё
void main(void)
{
while(1)
{
while(!adc_is_ready());
value = adc_read();
// TODO: Обработка value.
while(!dac_is_ready());
dac_set_value(value);
}
}


