1921ВК028 /АЦП /секвенсор /циклически

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

Artem_Zxc
Сообщения: 8
Зарегистрирован: 12 сен 2025, 11:31
Предприятие: RIF

1921ВК028 /АЦП /секвенсор /циклически

Сообщение Artem_Zxc »

Программа запускается на демо-борде (плата макетно-отладочная ИС 1921ВК028).
Настроен циклический опрос 2х каналов АЦП, с чтением данных в прерывании секвенсора (SEQ0).
После запуска, программа работает. Данные считываются в массив raw_value, но через какое-то время прерывание ADC_SEQ0_IRQHandler перестает срабатывать. Может сработать ~500 прерываний, а может ~10000, но по итогу прерывание перестает срабатывать.
Пробовал:
- различные варианты настроек секвенсора;
- другие АЦП;
- менял время SRTMR;
- убирал все другое из программы.
Результат такой же.

Подскажите, что я делаю не правильно?

Код:
void periph_init()
{
SystemCoreClockUpdate();
}
//------------------------------------------------------------------------------

//--- Main ----------------------------------------------------------------------
int main()
{
periph_init();
SysTick_Config(200000); // Частота процессора в KHz (200MHz)

//Настройка ADC
PMU->ADCPC_bit.LDOEN0 = 1;
while(!(PMU->ADCPC_bit.LDORDY0));

RCU->ADCCFG_bit.CLKSEL = 1; // SYSCLK=200МГц
RCU->ADCCFG_bit.DIVN = 2; // Выбираем делитель 6 (DIVN=2 & DIVEN=1), 200МГц/6=33,3Мгц
RCU->ADCCFG_bit.DIVEN = 1;
RCU->ADCCFG_bit.CLKEN = 1; // Включаем тактирование
RCU->ADCCFG_bit.RSTDIS = 1; // Снимаем бит сброса

ADC->ACTL[0].ACTL_bit.SELRES = ADC_ACTL_ACTL_SELRES_12bit;
ADC->ACTL[0].ACTL_bit.CALEN = 1; // калибровка
ADC->ACTL[0].ACTL_bit.ADCEN = 1; // разрешение работы АЦП

ADC->EMUX_bit.EM0 = ADC_EMUX_EM0_Cycle; // Циклически
ADC->SEQ[0].SCCTL_bit.ICNT = 3; //количество записей в FIFO для прерывания +1
ADC->SEQ[0].SCCTL_bit.RCNT = 0; //количество перезапусков
ADC->SEQ[0].SRTMR = 33332; // время задержки перезапуска секвенсора 0
ADC->SEQ[0].SRQCTL_bit.RQMAX = 1; // измерения по N+1 каналу
ADC->SEQ[0].SRQSEL0_bit.RQ0 = 0; // канал опроса
ADC->SEQ[0].SRQSEL0_bit.RQ1 = 1;

ADC->SEQ[0].SRQCTL_bit.QAVGVAL = 0;
ADC->SEQ[0].SRQCTL_bit.QAVGEN = 0;

ADC->IM_bit.SEQIM0 = 1;
ADC->SEQEN_bit.SEQEN0 = 1;//разрешение работы секвенсора

Энвик_EnableIRQ(ADC_SEQ0_IRQn);
// Запуск
while(!ADC->ACTL[0].ACTL_bit.ADCRDY);
ADC->SEQSYNC_bit.SYNC0 = 1;
ADC->SEQSYNC_bit.GSYNC = 1;

while (1)
{
if (BSP_Btn_GetState() == BSP_Btn_State_SB3) {
;
}
}
}

volatile uint32_t raw_value[16];
uint32_t Tmp_i1;

void ADC_SEQ0_IRQHandler(void)
{
int i=0;

if (ADC->RIS_bit.SEQRIS0)
{
ADC->IC_bit.SEQIC0 = 1; // Сбрасываем прерывание
Tmp_i1++;
for ( i = 0; i < 4; i++)
{
raw_value = ADC->SEQ[0].SFIFO; // Читаем очередное значение
}
}
}
RabidRabbit
Сообщения: 136
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение RabidRabbit »

Код: Выделить всё

raw_value = ADC->SEQ[0].SFIFO; 
- это называется "чтение в массив"?
Artem_Zxc
Сообщения: 8
Зарегистрирован: 12 сен 2025, 11:31
Предприятие: RIF

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение Artem_Zxc »

Виноват. Там конечно же "кв. скобка i кв. скобка". Форум убирает, что в квадратных скобках, без обозначения code

Код: Выделить всё

raw_value[i] = ADC->SEQ[0].SFIFO; // Читаем очередное значение
Последний раз редактировалось Artem_Zxc 16 сен 2025, 09:47, всего редактировалось 2 раза.
RabidRabbit
Сообщения: 136
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение RabidRabbit »

А зачем нужна вот эта

Код: Выделить всё

if (ADC->RIS_bit.SEQRIS0)
проверка в начале обработчика прерываний?
Artem_Zxc
Сообщения: 8
Зарегистрирован: 12 сен 2025, 11:31
Предприятие: RIF

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение Artem_Zxc »

Наверно не нужна...
RabidRabbit
Сообщения: 136
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение RabidRabbit »

Я это к тому, что не может ли дёрнуться прерывание от другого флага, который Вы не проверяете. При этом зацикливание в обработчике прерывания обеспечено.
Artem_Zxc
Сообщения: 8
Зарегистрирован: 12 сен 2025, 11:31
Предприятие: RIF

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение Artem_Zxc »

Я ставил счетчик внутри:

Код: Выделить всё

if (ADC->RIS_bit.SEQRIS0)
и снаружи - количество одинаково.
Так же запускал программу без этого if.
Результат такой же: "сколько-то" прерываний приходит, потом перестают приходить.
RabidRabbit
Сообщения: 136
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение RabidRabbit »

А если включать прерывания после запуска АЦП? Т.е. вот так

Код: Выделить всё

// Запуск
while(!ADC->ACTL[0].ACTL_bit.ADCRDY);
ADC->SEQSYNC_bit.SYNC0 = 1;
ADC->SEQSYNC_bit.GSYNC = 1;
// Включить обработчик
Энвик_EnableIRQ(ADC_SEQ0_IRQn);
Artem_Zxc
Сообщения: 8
Зарегистрирован: 12 сен 2025, 11:31
Предприятие: RIF

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение Artem_Zxc »

Попробовал, результат такой же ((
RabidRabbit
Сообщения: 136
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: 1921ВК028 /АЦП /секвенсор /циклически

Сообщение RabidRabbit »

Попробую проверить на К1921ВГ015, там АЦП примерно такой же.
Ответить

Вернуться в «32-разрядные микроконтроллеры»