32-разрядные микроконтроллеры разработки АО "НИИЭТ"
Модераторы: dav, bkolbov, Alis, pip, _sva_, dav, bkolbov, Alis, pip, _sva_, dav, bkolbov, Alis, pip, _sva_
-
Василий
- Сообщения: 11
- Зарегистрирован: 15 ноя 2017, 15:30
- Предприятие: ООО "НПФ Вектор"
Сообщение
Василий » 15 дек 2020, 18:24
Дополню некоторыми подробностями. Параметр AVG меняется в прерывании с частотой 1 кГц по таймеру NT_TIMER1. При этом АЦП остается включенным. Запуск преобразования АЦП происходит программно в конце процедуры обработки прерывания по таймеру ШИМ NT_PWM3. Приоритет у прерывания NT_TIMER1 ниже, чем у NT_PWM3.
Код: Выделить всё
// Программно запускаем АЦП
NT_ADC->PSSI_bit.GSYNC = 1;
Результаты преобразования берутся с компараторов подобным образом:
Код: Выделить всё
ui16 = (Uint16) (NT_ADC->DCVAL_bit[14].VAL);
Процедура инициализации АЦП:
- | Показать
Код: Выделить всё
/* Запрет всех секвенсоров */
NT_ADC->ACTSS = 0;
/* Сброс счётчиков прерываний и измерений*/
NT_ADC->SEQ[0].OP = 0;
NT_ADC->SEQ[1].OP = 0;
NT_ADC->SEQ[2].OP = 0;
NT_ADC->SEQ[3].OP = 0;
NT_ADC->SEQ[4].OP = 0;
NT_ADC->SEQ[5].OP = 0;
NT_ADC->SEQ[6].OP = 0;
NT_ADC->SEQ[7].OP = 0;
NT_ADC->ACTSS_bit.ASEN0 = 1; //Разрешение работы секвенсора 0 (1 - разрешено)
NT_ADC->IM_bit.MASK0 = 1; //Маска прерывания секвенсора 0 (1 - прерывание разрешено)
NT_ADC->EMUX_bit.EM0 = 0; //Поле выбора события для запуска секвенсора 0 - программный запуск установкой бита GSYNC в регистре PSSI
NT_ADC->PSSI_bit.SS0 = 1; //Бит разрешения запуска секвенсора 0
NT_ADC->SEQ[0].CTL_bit.RCNT = 0; //Перезапуск не требуется
NT_ADC->SEQ[0].CTL_bit.ICNT = 0; //Прерывания после каждого запуска
NT_ADC->PP_bit[0].OM = 0x3; //OM2-OM0 = ’011’ All blocks active (ADC plus internal buffers plus internal bandgap).
NT_ADC->PP_bit[1].OM = 0x3;
NT_ADC->PP_bit[2].OM = 0x3;
NT_ADC->PP_bit[3].OM = 0x3;
NT_ADC->PP_bit[4].OM = 0x3;
NT_ADC->PP_bit[5].OM = 0x3;
NT_ADC->PP_bit[6].OM = 0x3;
NT_ADC->PP_bit[7].OM = 0x3;
NT_ADC->PP_bit[8].OM = 0x3;
NT_ADC->PP_bit[9].OM = 0x3;
NT_ADC->PP_bit[10].OM = 0x3;
NT_ADC->PP_bit[11].OM = 0x3;
//Включаем необходимые модули АЦП
NT_ADC->PP_bit[0].ENA = 1;
NT_ADC->PP_bit[1].ENA = 1;
NT_ADC->PP_bit[2].ENA = 1;
NT_ADC->PP_bit[3].ENA = 1;
NT_ADC->PP_bit[4].ENA = 1;
NT_ADC->PP_bit[5].ENA = 1;
NT_ADC->PP_bit[6].ENA = 1;
NT_ADC->PP_bit[7].ENA = 1;
NT_ADC->PP_bit[8].ENA = 1;
NT_ADC->PP_bit[9].ENA = 1;
NT_ADC->PP_bit[10].ENA = 1;
NT_ADC->PP_bit[11].ENA = 1;
//усреднители в секвенсоре, сколько раз подряд измерить и усреднить
//задаёт степень двойки
#define AVG_NUM 2
NT_ADC->SAC_bit.AVG0=AVG_NUM;
NT_ADC->SAC_bit.AVG1=AVG_NUM;
NT_ADC->SAC_bit.AVG2=6; //Задаем длину выборки для аппаратного усреднения тока дросселя (Idc).
//На том же АЦП (ADC2) сидит еще температура радиатора (каналы 5 и 4), так что это усреднение действует и для нее.
NT_ADC->SAC_bit.AVG3=AVG_NUM;
NT_ADC->SAC_bit.AVG4=AVG_NUM;
NT_ADC->SAC_bit.AVG5=AVG_NUM;
NT_ADC->SAC_bit.AVG6=AVG_NUM;
NT_ADC->SAC_bit.AVG7=AVG_NUM;
NT_ADC->RICNT_bit.AVG8=AVG_NUM;
NT_ADC->RICNT_bit.AVG9=AVG_NUM;
NT_ADC->RICNT_bit.AVG10=AVG_NUM;
NT_ADC->RICNT_bit.AVG11=AVG_NUM;
//настраиваем компараторы каждый на свой канал АЦП -
//из компараторов будем забирать оцифрованные данные, как из ADC result
//после 8го все переставлено, так как номера на МК не соответствуют номерам на контроллере.
//при такой настройке номера каналов в проге будут совпадать с номерами на разъёме АЦП МК
NT_ADC->DCCTL_bit[0].CHNL = 1;
NT_ADC->DCCTL_bit[1].CHNL = 22;
NT_ADC->DCCTL_bit[2].CHNL = 2;
NT_ADC->DCCTL_bit[3].CHNL = 20;
NT_ADC->DCCTL_bit[4].CHNL = 3;
NT_ADC->DCCTL_bit[5].CHNL = 21;
NT_ADC->DCCTL_bit[6].CHNL = 18;
NT_ADC->DCCTL_bit[7].CHNL = 19;
NT_ADC->DCCTL_bit[8].CHNL = 16;
NT_ADC->DCCTL_bit[9].CHNL = 17;
NT_ADC->DCCTL_bit[10].CHNL = 14;
NT_ADC->DCCTL_bit[11].CHNL = 5;
NT_ADC->DCCTL_bit[12].CHNL = 12;
NT_ADC->DCCTL_bit[13].CHNL = 13;
NT_ADC->DCCTL_bit[14].CHNL = 4;
NT_ADC->DCCTL_bit[15].CHNL = 6;
NT_ADC->DCCTL_bit[16].CHNL = 0;
NT_ADC->DCCTL_bit[17].CHNL = 7;
NT_ADC->DCCTL_bit[18].CHNL = 8;
NT_ADC->DCCTL_bit[19].CHNL = 9;
NT_ADC->DCCTL_bit[20].CHNL = 10;
NT_ADC->DCCTL_bit[21].CHNL = 11;
NT_ADC->DCCTL_bit[22].CHNL = 15;
//Показываем, с каких каналов нужно собирать данные
NT_ADC->SEQ[0].DCP = 0x007FFFFF; // Каналы в компараторы, чтобы с них брать аналоговые результаты без фифо
-
bkolbov
- Сообщения: 248
- Зарегистрирован: 14 дек 2015, 11:37
- Предприятие: АО НИИЭТ
- Откуда: Воронеж
Сообщение
bkolbov » 16 дек 2020, 09:23
Василий писал(а): ↑14 дек 2020, 19:31
Столкнулся с проблемой при настройке усреднителя АЦП. Сделал параметр AVG настраиваемым. При изменении параметра на несколько единиц вниз стабильно зависает весь АЦП: перестают выполняться измерения, не формируются прерывания. Например, если задать AVG=4, а потом сбросить на AVG=0. Или сбросить AVG с 6 до 3.
Код: Выделить всё
if (p->Idc_AVG_setting < 0)
p->Idc_AVG_setting = 0;
if (p->Idc_AVG_setting > 6)
p->Idc_AVG_setting = 6;
NT_ADC->SAC_bit.AVG2=p->Idc_AVG_setting;
В документации не нашел запретов редактирования параметра AVG в каких-либо режимах работы микроконтроллера.
Василий писал(а): ↑15 дек 2020, 18:24
Дополню некоторыми подробностями. Параметр AVG меняется в прерывании с частотой 1 кГц по таймеру NT_TIMER1. При этом АЦП остается включенным. Запуск преобразования АЦП происходит программно в конце процедуры обработки прерывания по таймеру ШИМ NT_PWM3. Приоритет у прерывания NT_TIMER1 ниже, чем у NT_PWM3.
Код: Выделить всё
// Программно запускаем АЦП
NT_ADC->PSSI_bit.GSYNC = 1;
Результаты преобразования берутся с компараторов подобным образом:
Код: Выделить всё
ui16 = (Uint16) (NT_ADC->DCVAL_bit[14].VAL);
Процедура инициализации АЦП:
- | Показать
Код: Выделить всё
/* Запрет всех секвенсоров */
NT_ADC->ACTSS = 0;
/* Сброс счётчиков прерываний и измерений*/
NT_ADC->SEQ[0].OP = 0;
NT_ADC->SEQ[1].OP = 0;
NT_ADC->SEQ[2].OP = 0;
NT_ADC->SEQ[3].OP = 0;
NT_ADC->SEQ[4].OP = 0;
NT_ADC->SEQ[5].OP = 0;
NT_ADC->SEQ[6].OP = 0;
NT_ADC->SEQ[7].OP = 0;
NT_ADC->ACTSS_bit.ASEN0 = 1; //Разрешение работы секвенсора 0 (1 - разрешено)
NT_ADC->IM_bit.MASK0 = 1; //Маска прерывания секвенсора 0 (1 - прерывание разрешено)
NT_ADC->EMUX_bit.EM0 = 0; //Поле выбора события для запуска секвенсора 0 - программный запуск установкой бита GSYNC в регистре PSSI
NT_ADC->PSSI_bit.SS0 = 1; //Бит разрешения запуска секвенсора 0
NT_ADC->SEQ[0].CTL_bit.RCNT = 0; //Перезапуск не требуется
NT_ADC->SEQ[0].CTL_bit.ICNT = 0; //Прерывания после каждого запуска
NT_ADC->PP_bit[0].OM = 0x3; //OM2-OM0 = ’011’ All blocks active (ADC plus internal buffers plus internal bandgap).
NT_ADC->PP_bit[1].OM = 0x3;
NT_ADC->PP_bit[2].OM = 0x3;
NT_ADC->PP_bit[3].OM = 0x3;
NT_ADC->PP_bit[4].OM = 0x3;
NT_ADC->PP_bit[5].OM = 0x3;
NT_ADC->PP_bit[6].OM = 0x3;
NT_ADC->PP_bit[7].OM = 0x3;
NT_ADC->PP_bit[8].OM = 0x3;
NT_ADC->PP_bit[9].OM = 0x3;
NT_ADC->PP_bit[10].OM = 0x3;
NT_ADC->PP_bit[11].OM = 0x3;
//Включаем необходимые модули АЦП
NT_ADC->PP_bit[0].ENA = 1;
NT_ADC->PP_bit[1].ENA = 1;
NT_ADC->PP_bit[2].ENA = 1;
NT_ADC->PP_bit[3].ENA = 1;
NT_ADC->PP_bit[4].ENA = 1;
NT_ADC->PP_bit[5].ENA = 1;
NT_ADC->PP_bit[6].ENA = 1;
NT_ADC->PP_bit[7].ENA = 1;
NT_ADC->PP_bit[8].ENA = 1;
NT_ADC->PP_bit[9].ENA = 1;
NT_ADC->PP_bit[10].ENA = 1;
NT_ADC->PP_bit[11].ENA = 1;
//усреднители в секвенсоре, сколько раз подряд измерить и усреднить
//задаёт степень двойки
#define AVG_NUM 2
NT_ADC->SAC_bit.AVG0=AVG_NUM;
NT_ADC->SAC_bit.AVG1=AVG_NUM;
NT_ADC->SAC_bit.AVG2=6; //Задаем длину выборки для аппаратного усреднения тока дросселя (Idc).
//На том же АЦП (ADC2) сидит еще температура радиатора (каналы 5 и 4), так что это усреднение действует и для нее.
NT_ADC->SAC_bit.AVG3=AVG_NUM;
NT_ADC->SAC_bit.AVG4=AVG_NUM;
NT_ADC->SAC_bit.AVG5=AVG_NUM;
NT_ADC->SAC_bit.AVG6=AVG_NUM;
NT_ADC->SAC_bit.AVG7=AVG_NUM;
NT_ADC->RICNT_bit.AVG8=AVG_NUM;
NT_ADC->RICNT_bit.AVG9=AVG_NUM;
NT_ADC->RICNT_bit.AVG10=AVG_NUM;
NT_ADC->RICNT_bit.AVG11=AVG_NUM;
//настраиваем компараторы каждый на свой канал АЦП -
//из компараторов будем забирать оцифрованные данные, как из ADC result
//после 8го все переставлено, так как номера на МК не соответствуют номерам на контроллере.
//при такой настройке номера каналов в проге будут совпадать с номерами на разъёме АЦП МК
NT_ADC->DCCTL_bit[0].CHNL = 1;
NT_ADC->DCCTL_bit[1].CHNL = 22;
NT_ADC->DCCTL_bit[2].CHNL = 2;
NT_ADC->DCCTL_bit[3].CHNL = 20;
NT_ADC->DCCTL_bit[4].CHNL = 3;
NT_ADC->DCCTL_bit[5].CHNL = 21;
NT_ADC->DCCTL_bit[6].CHNL = 18;
NT_ADC->DCCTL_bit[7].CHNL = 19;
NT_ADC->DCCTL_bit[8].CHNL = 16;
NT_ADC->DCCTL_bit[9].CHNL = 17;
NT_ADC->DCCTL_bit[10].CHNL = 14;
NT_ADC->DCCTL_bit[11].CHNL = 5;
NT_ADC->DCCTL_bit[12].CHNL = 12;
NT_ADC->DCCTL_bit[13].CHNL = 13;
NT_ADC->DCCTL_bit[14].CHNL = 4;
NT_ADC->DCCTL_bit[15].CHNL = 6;
NT_ADC->DCCTL_bit[16].CHNL = 0;
NT_ADC->DCCTL_bit[17].CHNL = 7;
NT_ADC->DCCTL_bit[18].CHNL = 8;
NT_ADC->DCCTL_bit[19].CHNL = 9;
NT_ADC->DCCTL_bit[20].CHNL = 10;
NT_ADC->DCCTL_bit[21].CHNL = 11;
NT_ADC->DCCTL_bit[22].CHNL = 15;
//Показываем, с каких каналов нужно собирать данные
NT_ADC->SEQ[0].DCP = 0x007FFFFF; // Каналы в компараторы, чтобы с них брать аналоговые результаты без фифо
Добрый день!
Мне нужно уточнить детали взаимодействия механизмов запусков АЦП и усреднения, но могу сделать первое предположение о том, что усреднение изменяется в процессе измерения "на горячую", а не между измерениями. Таймер и ШИМ не синхронизированы, а значит потенциально может быть ситуация, когда ШИМ запустил АЦП, а следом, во время активного измерения, приходит прерывание от таймера и изменяется значения усреднения. Или нет? И такая ситуация исключена каким-либо образом? Если гарантировано изменять усреднение между измерениями, то будет ли ситуация повторяться?
-
Василий
- Сообщения: 11
- Зарегистрирован: 15 ноя 2017, 15:30
- Предприятие: ООО "НПФ Вектор"
Сообщение
Василий » 16 дек 2020, 11:42
bkolbov писал(а): ↑16 дек 2020, 09:23
Добрый день!
Мне нужно уточнить детали взаимодействия механизмов запусков АЦП и усреднения, но могу сделать первое предположение о том, что усреднение изменяется в процессе измерения "на горячую", а не между измерениями. Таймер и ШИМ не синхронизированы, а значит потенциально может быть ситуация, когда ШИМ запустил АЦП, а следом, во время активного измерения, приходит прерывание от таймера и изменяется значения усреднения. Или нет? И такая ситуация исключена каким-либо образом? Если гарантировано изменять усреднение между измерениями, то будет ли ситуация повторяться?
День добрый!
Да, действительно, прерывание ШИМ, в котором запускается измерение, и прерывание по таймеру, в котором изменяется настройка усреднения, не синхронизированы. Ситуация, когда AVG меняется во время активного измерения, вполне вероятна. Никакой "страховки" от этого не предусмотрено.
Сейчас провел тест: сделал изменение AVG непосредственно перед запуском АЦП. В таком случае, проблемы зависания АЦП не возникает.
-
bkolbov
- Сообщения: 248
- Зарегистрирован: 14 дек 2015, 11:37
- Предприятие: АО НИИЭТ
- Откуда: Воронеж
Сообщение
bkolbov » 16 дек 2020, 11:59
Да, посмотрел - значение AVG никак не защищено от изменения во время измерения, а значит, при изменении на горячую вполне может сломаться внутренняя логика работы. Т.е. безопасно изменять значение усреднения следует только когда измерение неактивно.
-
Василий
- Сообщения: 11
- Зарегистрирован: 15 ноя 2017, 15:30
- Предприятие: ООО "НПФ Вектор"
Сообщение
Василий » 16 дек 2020, 12:07
bkolbov писал(а): ↑16 дек 2020, 11:59
Да, посмотрел - значение AVG никак не защищено от изменения во время измерения, а значит, при изменении на горячую вполне может сломаться внутренняя логика работы. Т.е. безопасно изменять значение усреднения следует только когда измерение неактивно.
Думаю, это стоит отразить в документации.
-
bkolbov
- Сообщения: 248
- Зарегистрирован: 14 дек 2015, 11:37
- Предприятие: АО НИИЭТ
- Откуда: Воронеж
Сообщение
bkolbov » 16 дек 2020, 12:28
Василий писал(а): ↑16 дек 2020, 12:07
Думаю, это стоит отразить в документации.
Верно.
-
petrovitch
- Сообщения: 77
- Зарегистрирован: 15 фев 2017, 19:07
Сообщение
petrovitch » 12 фев 2021, 12:11
Из документации мне не совсем понятно как можно пользоваться цифровым компаратором. Так на стр. 209 РП (рис. 21.) сказано, что далее сигнал поступает на некий ADCDC_triggern. Найти дальнейшие следы этого ADCDC...не удалось.
Мне необходимо подавать на ножку контроллера единицу пока превышен некий порог напряжения на АЦП и возвращать ножку в ноль при снижении уровня ниже порога.
Как мне это сделать?
Можно ли при этом использовать не ножку выхода ШИМ, а какую-либо другую?
-
Лашкевич
- Сообщения: 211
- Зарегистрирован: 13 май 2015, 13:10
- Предприятие: ООО "НПФ Вектор"
- Откуда: Москва
-
Contact:
Сообщение
Лашкевич » 06 мар 2021, 09:38
Регистр GPIOQPAD в таблице Таблица А.2.5 называется GPIOPAD, без буквы Q. Нужно поправить, иначе поиском не найти
-
Лашкевич
- Сообщения: 211
- Зарегистрирован: 13 май 2015, 13:10
- Предприятие: ООО "НПФ Вектор"
- Откуда: Москва
-
Contact:
Сообщение
Лашкевич » 06 мар 2021, 09:41
petrovitch писал(а): ↑12 фев 2021, 12:11
Из документации мне не совсем понятно как можно пользоваться цифровым компаратором. Так на стр. 209 РП (рис. 21.) сказано, что далее сигнал поступает на некий ADCDC_triggern. Найти дальнейшие следы этого ADCDC...не удалось.
Мне необходимо подавать на ножку контроллера единицу пока превышен некий порог напряжения на АЦП и возвращать ножку в ноль при снижении уровня ниже порога.
Как мне это сделать?
Можно ли при этом использовать не ножку выхода ШИМ, а какую-либо другую?
Мы пробовали пользоваться цифровым компаратором, он работает, как вы описали (с ножкой ШИМ), но, к сожалению, после каждого срабатывания его приходится программно сбрасывать для разрешения нового срабатывания. А поэтому всю идею с автоматической цифровой релейкой это сводит на нет, можно с тем же успехом делать в программе if'ом. Это поведение пофикшено в новых изделиях, 1921ВК028. Тут вот тема есть
viewtopic.php?f=37&t=2399
Пользователи онлайн
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя