К1921ВК01Т (арм Cortex-M4F)

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

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

serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

Лашкевич писал(а): 19 апр 2021, 15:21 Вот моя инициализация АЦП для программного запуска, оцифровка всех каналов, 12 разрядов.

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

	/* Запрет всех секвенсоров */
	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;
	NT_ADC->IM_bit.MASK0 = 1;
	NT_ADC->EMUX_bit.EM0 = 0; // программный запуск установкой бита GSYNC в регистре PSSI
	NT_ADC->PSSI_bit.SS0 = 1;
	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;


	//усреднитель выключен 
	//(но для большинства задач полезно включить!)
	NT_ADC->SAC_bit.AVG0=0;
	NT_ADC->SAC_bit.AVG1=0;
	NT_ADC->SAC_bit.AVG2=0;
	NT_ADC->SAC_bit.AVG3=0;
	NT_ADC->SAC_bit.AVG4=0;
	NT_ADC->SAC_bit.AVG5=0;
	NT_ADC->SAC_bit.AVG6=0;
	NT_ADC->SAC_bit.AVG7=0;
	NT_ADC->RICNT_bit.AVG8=0;
	NT_ADC->RICNT_bit.AVG9=0;
	NT_ADC->RICNT_bit.AVG10=0;
	NT_ADC->RICNT_bit.AVG11=0;


	//настраиваем компараторы каждый на свой канал АЦП -
	//из компараторов будем забирать оцифрованные данные, как из ADC result
	NT_ADC->DCCTL_bit[0].CHNL = 0;
	NT_ADC->DCCTL_bit[1].CHNL = 1;
	NT_ADC->DCCTL_bit[2].CHNL = 2;
	NT_ADC->DCCTL_bit[3].CHNL = 3;
	NT_ADC->DCCTL_bit[4].CHNL = 4;
	NT_ADC->DCCTL_bit[5].CHNL = 5;
	NT_ADC->DCCTL_bit[6].CHNL = 6;
	NT_ADC->DCCTL_bit[7].CHNL = 7;
	NT_ADC->DCCTL_bit[8].CHNL = 8;
	NT_ADC->DCCTL_bit[9].CHNL = 9;
	NT_ADC->DCCTL_bit[10].CHNL = 10;
	NT_ADC->DCCTL_bit[11].CHNL = 11;
	NT_ADC->DCCTL_bit[12].CHNL = 12;
	NT_ADC->DCCTL_bit[13].CHNL = 13;
	NT_ADC->DCCTL_bit[14].CHNL = 14;
	NT_ADC->DCCTL_bit[15].CHNL = 15;
	NT_ADC->DCCTL_bit[16].CHNL = 16;
	NT_ADC->DCCTL_bit[17].CHNL = 17;
	NT_ADC->DCCTL_bit[18].CHNL = 18;
	NT_ADC->DCCTL_bit[19].CHNL = 19;
	NT_ADC->DCCTL_bit[20].CHNL = 20;
	NT_ADC->DCCTL_bit[21].CHNL = 21;
	NT_ADC->DCCTL_bit[22].CHNL = 22;
	NT_ADC->DCCTL_bit[23].CHNL = 23;

	//Показываем, с каких каналов нужно собирать данные
	NT_ADC->SEQ[0].DCP = 0x007FFFFF;	// Каналы в компараторы, чтобы с них брать аналоговые результаты без фифо

Для забора результатов:

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

Uint16 channel4 = NT_ADC->DCVAL_bit[4].VAL;

Для запуска программного, в прерывании:

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

	// Программно запускаем АЦП
	NT_ADC->PSSI_bit.GSYNC = 1;
А вопрос: в какое прерывание должен заходить код по завершении преобразования?
ADC_CompInt_IRQn = 89, /*!< ADC Comparator interrupt */ В это?
Да и вообще где в коде разрешения прерываний? И нельзя ли обойтись без компараторов (просто через секвенсор)?
dav
Сообщения: 209
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение dav »

serg_vega писал(а): 19 апр 2021, 18:31 Вообще я не понял как должен работать код в котором Энвик_EnableIRQ(ADC_SEQ0_IRQn); закомментирована! Просто запрещены прерывания от нулевого секвенсора.
Забирать результаты из FIFO секвенсора можно либо из прерывания секвенсора либо опрашивая регистр флагов прерывания RIS без вызова прерывания.

Во вложении пример проекта в IDE Keil
Keil_k1921vk01t_ADC_Timer.zip
Пример проекта в IDE Keil программного запуска АЦП из прерывания по таймеру для микроконтроллера К1921ВК01T
(168.37 КБ) 30 скачиваний
В примере реализован программный запуск АЦП из прерывания по таймеру.
serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

Сейчас посмотрю пример из ЗИПа. Тем временем я рассмотрел пример uflash_write_read. "Из коробки" не работает... Добавьте утерянные функции (implicit declared):
void USERFLASH_OperationStatusClear()
{
NT_USERFLASH->FCIC=0x00000003;
}

uint32_t USERFLASH_OperationStatus()
{
uint32_t temp_flags;
temp_flags=NT_USERFLASH->FCIS;
return temp_flags;

}
dav
Сообщения: 209
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение dav »

serg_vega писал(а): 20 апр 2021, 10:37 Сейчас посмотрю пример из ЗИПа. Тем временем я рассмотрел пример uflash_write_read. "Из коробки" не работает... Добавьте утерянные функции (implicit declared):
void USERFLASH_OperationStatusClear()
{
NT_USERFLASH->FCIC=0x00000003;
}

uint32_t USERFLASH_OperationStatus()
{
uint32_t temp_flags;
temp_flags=NT_USERFLASH->FCIS;
return temp_flags;

}
В проектах репозитория SDK "projects\niietcm4_pd\userflash\uflash_write_read" и "projects\niietcm4_pd\bootflash\write_read" были обнаружены ошибки, в ближайшее время планируется обновление репозитория.
Так, в примере "uflash_write_read" функции USERFLASH_OperationStatusClear(), USERFLASH_OperationStatus изначально были интегрированы в функции чтения, записи и стирания (USERFLASH_Read, USERFLASH_Write, USERFLASH_PageErase), но остались в файле main.c
Поэтому их достаточно удалить или закомментировать в файле main.c
По проекту "projects\niietcm4_pd\bootflash":
В микроконтроллере К1921ВК01Т процедуры записи/стирании загрузочной Флеш необходимо осуществлять из области ОЗУ. (см. п.4 "Операции с внутренней flash" Errata )

В примере projects\niietcm4_pd\bootflash для Keil данная возможность не реализована, поэтому могут происходить сбои.

Для того, чтобы данный пример выполнялся корректно, необходимо функции модуля niietcm4_bootflash перенести в область ОЗУ, для этого в настройках проекта, на вкладке "Linker" добавить Scatter File следующего содержания:

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

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00000000 0x000FFFFF  {    ; load region size_region
  ER_IROM1 0x00000000 0x000FFFFF  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00003000  {  ; RW data
   .ANY (+RW +ZI)
   niietcm4_bootflash.o (+RO)
  }
}
добавление Scatter File к проекту
добавление Scatter File к проекту
Keil_Linker_ScatterFile.JPG (53.98 КБ) 796 просмотров
ram_write_read.zip
Scatter File
(375 байт) 26 скачиваний
Аватара пользователя
Лашкевич
Сообщения: 373
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение Лашкевич »

serg_vega писал(а): 19 апр 2021, 14:53 А как конкретно, в граммах запустить секвенсор АЦП, допустим №0, на однократное преобразование. Так называемый программный запуск.
В изначальном вопросе не было озвучено необходимости прерываний. Поэтому приведенный код прерываний и не включает. Типичное использование АЦП при программном запуске - в отдельном пользовательском прерывании таймера (скажем, ШИМ) забираются текущие измерения, рассчитывается система управления и программно питается АЦП для измерения ещё раз, так, чтобы к следующему заходу в прерывание таймера уже давно лежал готовый результат (в фифо или регистрах компаратора). Прерывание именно по АЦП нужно только если есть необходимость минимизировать время между измерением АЦП и реакцией на его измерения, что нужно для очень специфических задач.
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

dav писал(а): 20 апр 2021, 10:31
Забирать результаты из FIFO секвенсора можно либо из прерывания секвенсора либо опрашивая регистр флагов прерывания RIS без вызова прерывания.

Во вложении пример проекта в IDE Keil Keil_k1921vk01t_ADC_Timer.zip
В примере реализован программный запуск АЦП из прерывания по таймеру.
На первый взгляд пример как-то работает))). Почему как-то? Ну у меня нет переходника для вывода в консоль, поэтому retarget и все printf я комментирую и смотрю в отладчике. И вот что я заметил... Программа гораздо чаще заходит в TIM0_IRQHandler(), чем в ADC_SEQ0_IRQHandler()... Для демонстрационных целей - ну да, подходит, для рабочих после обеда буду допиливать... Задача получить максимально быстрое прерывание по 2 ну или 4 каналам, остальные мне без особой надобности.... Ну и замерить осциллографом период его выполнения.
serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

Лашкевич писал(а): 20 апр 2021, 11:17
serg_vega писал(а): 19 апр 2021, 14:53 А как конкретно, в граммах запустить секвенсор АЦП, допустим №0, на однократное преобразование. Так называемый программный запуск.
В изначальном вопросе не было озвучено необходимости прерываний. Поэтому приведенный код прерываний и не включает. Типичное использование АЦП при программном запуске - в отдельном пользовательском прерывании таймера (скажем, ШИМ) забираются текущие измерения, рассчитывается система управления и программно питается АЦП для измерения ещё раз, так, чтобы к следующему заходу в прерывание таймера уже давно лежал готовый результат (в фифо или регистрах компаратора). Прерывание именно по АЦП нужно только если есть необходимость минимизировать время между измерением АЦП и реакцией на его измерения, что нужно для очень специфических задач.
Ну да, у нас очень специфическая задача))). Защита от чрезмерного пик-фактора радиосигнала. Я бы вполне обошелся и циклическим запуском, но у меня получается что время реакции (или преобразования) пока непонятно, что именно, плавает. Хотя, возможно будет достаточно воспользоваться прерыванием по компаратору.
serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

dav писал(а): 20 апр 2021, 10:31
serg_vega писал(а): 19 апр 2021, 18:31 Вообще я не понял как должен работать код в котором Энвик_EnableIRQ(ADC_SEQ0_IRQn); закомментирована! Просто запрещены прерывания от нулевого секвенсора.
Забирать результаты из FIFO секвенсора можно либо из прерывания секвенсора либо опрашивая регистр флагов прерывания RIS без вызова прерывания.

Во вложении пример проекта в IDE Keil Keil_k1921vk01t_ADC_Timer.zip
В примере реализован программный запуск АЦП из прерывания по таймеру.
Идем далее. Вот я запустил Ваш пример... Я правильно понимаю, что
for(i=0;i<12;i++) {
NT_ADC->PP_bit.OM = ((0 << 6) | // одниночный режим для канала B
(0 << 4) | // одниночный режим для канала A
(1 << 3) | // 1 - 10 бит, 0 - 12 бит
(3 << 0)); // включаем модуль
NT_ADC->PP_bit.ENA = 1; // Разрешаем работу модуля АЦП
}
это инициализация всех 23 одиночных каналов? (24 может работать только в дифференциальном режиме) Однако в отладке я вижу только первые 8! Остальные ровно "нули". Почему?!
Сразу вопрос, в РП на странице 280 есть подраздел: "Расчет времени одного измерения" имеется инфа, что можно включить только канал А, тогда время преобразования сокращается. И как это сделать? Смотрим поле ОМ... Режим по каждому каналу либо однополярный, либо дифференциальный. Как выбрать режим, когда мне нужен только канал А. В ADC->SEQ.MUX ?
serg_vega
Сообщения: 96
Зарегистрирован: 20 июл 2020, 15:50
Предприятие: АО "ВНИИ "Вега"

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение serg_vega »

Изображение
О научился вставлять изображения. Окно отладки.... Видно, что начиная с 8-го канала - нули.
Вложения
Keil_screen.jpg
Keil_screen.jpg (486.42 КБ) 774 просмотра
dav
Сообщения: 209
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение dav »

serg_vega писал(а): 20 апр 2021, 16:33 Как выбрать режим, когда мне нужен только канал А. В ADC->SEQ.MUX ?

Да, в регистре ADC->SEQ.MUX выбираем каналы, по которым секвенсор должен запускать АЦП.
Так, если необходимо получать результаты только по каналам А:
NT_ADC->SEQ[0].MUX = 0x00555555; // ch 0,2,4,6,8,10,12,14,16,18,20,22
//Тогда и при чтении FIFO секвенсора будут результаты по каналам АЦП: 0,2,4,6,8,10,12,14,16,18,20,22

Для получения результатов по всем 23-м каналам:
NT_ADC->SEQ[0].MUX = 0x007FFFFF; // ch 0 - 22
Ответить

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