bkolbov, добрый день!
bkolbov писал(а): ↑25 июл 2017, 13:00Какие каналы используете?
Используются следующие каналы: ADC6A, ADC6B, ADC7A, ADC7B, ADC8A, ADC9A, ADC10A, ADC10B и ADC11B.
bkolbov писал(а): ↑25 июл 2017, 13:00Как настроили прерывания?
Прерывания настроены только для ШИМ при событиях PRD=CTR и PRD=ZERO.
Запуск секвенсора осуществляется при событии PRD=CTR автоматически. Далее в обработчике прерывания (PRD=CTR) я вычитываю результаты из FIFO.
Вот полная функция вычитки из FIFO:
Код: Выделить всё
uint8_t getAdcData(struct AdcData *adcData)
{
/* Результаты измерений модулей АЦП записываются в буферы секвенсоров в
* порядке возрастания номеров каналов. Сохраненные в буфере данные доступны
* для чтения посредством регистра FIFO */
while (NT_ADC->RIS_bit.INR0 == 0); // Ожидаем окончания измерений
/*
* Если буфер не содержит искомое количество выборок, то его содержимое
* следует считать НЕ действительным и такие данные не интерпретировать.
*/
if(NT_ADC->SEQ[0].FSTAT_bit.FLOAD != 9)
{
adcClearFifo();
NT_ADC->ISC = 0x01;
return 0;
}
adcData->val0= (NT_ADC->SEQ[0].FIFO);
adcData->val1= (NT_ADC->SEQ[0].FIFO);
adcData->val2= (NT_ADC->SEQ[0].FIFO);
adcData->val3= (NT_ADC->SEQ[0].FIFO);
adcData->val4= (NT_ADC->SEQ[0].FIFO);
adcData->val5= (NT_ADC->SEQ[0].FIFO);
adcData->val6= (NT_ADC->SEQ[0].FIFO);
adcData->val7= (NT_ADC->SEQ[0].FIFO);
adcData->val8= (NT_ADC->SEQ[0].FIFO);
NT_ADC->ISC = 0x01;
return 1;
}
До того, как эта функция будет запущена я считаю некоторую математику. Все равно секвенсор еще работает и надо немного подождать.
Затем я проверяю готовность через флаг INR0 и вычитываю FIFO если меня устраивает количество элементов в нем.
bkolbov писал(а): ↑25 июл 2017, 13:00Какая частота ядра?
96 МГц
bkolbov писал(а): ↑25 июл 2017, 13:00Какие предделители ШИМ (какая частота счета ШИМ)? Какое значение периода?
ШИМ 24 КГц.
Счетчик UpDown. Предделителей на ШИМ нет. Период 2000.
Частота работы ШИМ проверенна на осциллографе. Корректность вызова обработчиков прерываний тоже.
Полный код настройки ШИМ:
Код: Выделить всё
void adcSetup(void)
{
/* Частота тактирования
* Для 12-разрядного режима работы АЦП необходимо обеспечить частоту
* тактирования 24 МГц. Применим для этого делитель DIV_ADCn (6 бит).
* Fadc = Fsysclk/(2*(DIV_ADCn + 1)) = 96/(2*(1+1)) = 24 МГц
* После установки частоты включаем тактирование для каждого канала
* с помощью регистра настроек модуля АЦП PPm, где:
* PPm[ENA] = PPm[31] - бит разрешения работы модуля (1 - разрешено / 0 - запрещено)
* PPm[OM] = PPm[19] - разрядность (0 - 12 бит / 1 - 10 бит)
* PPm[OM] = PPm[18-16] - режим (000 - выключен / 001 - StandBy / 011 - включен)
*/
NT_COMMON_REG->ADC_CTRL1_bit.DIV_ADC6 = 1; // DIV_ADC0
NT_COMMON_REG->ADC_CTRL1_bit.DIVEN_ADC6 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL1_bit.CLKEN_ADC6 = 1; // Включаем тактовый сигнал
NT_COMMON_REG->ADC_CTRL1_bit.DIV_ADC7 = 1; // DIV_ADC1
NT_COMMON_REG->ADC_CTRL1_bit.DIVEN_ADC7 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL1_bit.CLKEN_ADC7 = 1; // Включаем тактовый сигнал
NT_COMMON_REG->ADC_CTRL2_bit.DIV_ADC8 = 1; // DIV_ADC2
NT_COMMON_REG->ADC_CTRL2_bit.DIVEN_ADC8 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL2_bit.CLKEN_ADC8 = 1; // Включаем тактовый сигнал
NT_COMMON_REG->ADC_CTRL2_bit.DIV_ADC9 = 1; // DIV_ADC3
NT_COMMON_REG->ADC_CTRL2_bit.DIVEN_ADC9 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL2_bit.CLKEN_ADC9 = 1; // Включаем тактовый сигнал
NT_COMMON_REG->ADC_CTRL2_bit.DIV_ADC10 = 1; // DIV_ADC6
NT_COMMON_REG->ADC_CTRL2_bit.DIVEN_ADC10 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL2_bit.CLKEN_ADC10 = 1; // Включаем тактовый сигнал
NT_COMMON_REG->ADC_CTRL2_bit.DIV_ADC11 = 1; // DIV_ADC7
NT_COMMON_REG->ADC_CTRL2_bit.DIVEN_ADC11 = 1; // Выбираем тактовый сигнал после делителя
NT_COMMON_REG->ADC_CTRL2_bit.CLKEN_ADC11 = 1; // Включаем тактовый сигнал
/* Деинициализация
* Отключаем все компараторы (регистр DCCTLn)
* Для этого в поле CHNL регистра DCCTLn может быть записан номер канала,
* который выбран в регистре MUX или любое значение из диапазона
* от 18h до 1Fh. Запишем везде 18h.
*/
for(i=0;i<24;i++)
{
NT_ADC->DCCTL[i] = (0x18 << 16);
}
// Запрет всех секвенсоров
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->EMUX_bit.EM0 = 6; // Сигнал от ШИМ0
// Разрешение работы секвенсора
NT_ADC->PSSI_bit.SS0 = 1;
//Перезапуск секвенсора не требуется
NT_ADC->SEQ[0].CTL_bit.RCNT = 0;
// Режим функционирования - однополярный.
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[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->SEQ[0].MUX_bit.CH12 = 1; /* ADC6A */
NT_ADC->SEQ[0].MUX_bit.CH13 = 1; /* ADC6B */
NT_ADC->SEQ[0].MUX_bit.CH14 = 1; /* ADC7A */
NT_ADC->SEQ[0].MUX_bit.CH15 = 1; /* ADC7B */
NT_ADC->SEQ[0].MUX_bit.CH16 = 1; /* ADC8A */
NT_ADC->SEQ[0].MUX_bit.CH18 = 1; /* ADC9A */
NT_ADC->SEQ[0].MUX_bit.CH20 = 1; /* ADC10A */
NT_ADC->SEQ[0].MUX_bit.CH21 = 1; /* ADC10B */
NT_ADC->SEQ[0].MUX_bit.CH23 = 1; /* ADC11B */
// Отключаем усреднители на секвенсоре
NT_ADC->SAC_bit.AVG0 = 0; // Секвенсор 0
}