Оптимизация работы АЦП
This commit is contained in:
parent
c7fb6db1d2
commit
7b592829d8
@ -5,7 +5,7 @@
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1428732868423050069" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1548003095956541040" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
@ -16,7 +16,7 @@
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1413074244047209090" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1588485529958774947" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
@ -195,6 +195,7 @@ void SM_Sys_Init(TSM_Sys *p) {
|
||||
//! \memberof TSM_Sys
|
||||
void SM_Sys_Fast_Calc(TSM_Sys *p) {
|
||||
sm_net.fast_calc(&sm_net);//ðàñ÷åò êîììóíèêàöèîííûõ äðàéâåðîâ
|
||||
adc.fast_calc(&adc);//расчет АЦП
|
||||
if (drv_params.sens_type == POS_SENSOR_TYPE_ENCODER) // òèïå äàò÷èêà âûáðàí ýíêîäåð
|
||||
posspeedEqep.calc(&posspeedEqep); //ÄÏÐ ýíêîäåð
|
||||
if (drv_params.sens_type == POS_SENSOR_TYPE_HALL){ // òèïå äàò÷èêà âûáðàí ÄÏÐ Õîëëà
|
||||
@ -226,6 +227,8 @@ void SM_Sys_Fast_Calc(TSM_Sys *p) {
|
||||
cur_par.calc(&cur_par); //Ðàñ÷åò òåêóùèõ ïîêàçàòåëåé ïðèâîäà
|
||||
drv_params.sens_type = drv_params.sens_type & 7; //Îòñåêàåì âåðõíþþ ÷àñòü ïåðåìåííîé, òàì ìóñîð
|
||||
|
||||
ADC->SEQSYNC_bit.GSYNC = 1; // Запуск АЦП
|
||||
|
||||
#ifdef WATCHDOG_ON
|
||||
WatchDog.calc();//åñëè ñòîðîæåâîé òàéìåð èñïîëüçóåòñÿ, ñáðàñûâàåì åãî çäåñü
|
||||
#endif //WATCHDOG_ON
|
||||
|
136
Vsrc/V_adc.c
136
Vsrc/V_adc.c
@ -35,67 +35,60 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
//!Инициализация.
|
||||
|
||||
//! Настраиваются секвенсоры и тип оцифровки данных. каналы для оцифровки, частота.
|
||||
//! В данном случае оцифровка происходит по событию таймера,частота которого
|
||||
//! равна частоте ШИМ, чтобы измерять ровно посередине периода ШИМ (требуется для шунтовых
|
||||
//! датчиков тока)
|
||||
//Запуск оцифровки производится по таймеру NT_PWM3, который синхронизирован с другими таймерами ШИМ.
|
||||
//Оцифрованные измерения складываются в ФИФО. Каждый канал АЦП настроен на отдельный секвенсор с ФИФО длиной до 16 измерений.
|
||||
//В прерывании с частотой 10 кГц данные забираются из ФИФО и складываются в кольцевые массивы (старые затираются новыми).
|
||||
//В том же прерывании из кольцевого массива берется N последних точек и из них вычисляется среднее арифметическое.
|
||||
//Число выборок для усреднения N зависит от частоты ШИМ и равна Fшим/10кГц. Если частоты ШИМ меньше 10 кГц, то берется одна выборка, если больше 40 кГц - 4 выборки.
|
||||
//К вычисленному среднему значению добавляется калибровочный сдвиг, и оно умножается на коэффициент измерения, в результате получается окончательный результат измерения.
|
||||
|
||||
//! \memberof TAdcDrv
|
||||
//!
|
||||
void AdcDrv_init(TAdcDrv *p) {
|
||||
PWM0->ETSEL_bit.SOCAEN = 1;
|
||||
PWM0->ETSEL_bit.SOCASEL = ET_CTR_ZERO;
|
||||
PWM0->ETPS_bit.SOCAPRD = 0;
|
||||
|
||||
Uint32 AdcClock, AdcDiv, trash;
|
||||
//! Èíèöèàëèçàöèÿ ÀÖÏ ïðè ïðîãðàììíîì çàïóñêå áåç èñïîëüçîâàíèè ïðåðûâàíèé è ôèôî
|
||||
|
||||
// Сколько SYSCLKOUT тактов занимает период ШИМ
|
||||
Uint32 pwmPrd = PWM0->TBPRD * (SystemCoreClock / APB0BusClock);
|
||||
if (PWM0->TBCTL_bit.CTRMODE == TB_COUNT_UPDOWN)
|
||||
pwmPrd = pwmPrd << 1;
|
||||
Uint32 trash;
|
||||
// Çàïðåò âñåõ ñåêâåíñîðîâ
|
||||
ADC->SEQSYNC = 0;
|
||||
|
||||
// Сколько SYSCLKOUT тактов занимает один такт АЦП (AdcDiv)
|
||||
AdcDiv = 2 * (RCU->ADCCFG_bit.DIVN + 1); // Итого деление частоты
|
||||
AdcClock = SystemCoreClock / AdcDiv; // Снимаем сброс
|
||||
// Ñáðîñ Ñ÷åò÷èêîâ ïðåðûâíèé è èçìåðåíèé
|
||||
ADC->SEQ[0].SCVAL = 0;
|
||||
ADC->SEQ[1].SCVAL = 0;
|
||||
ADC->SEQ[2].SCVAL = 0;
|
||||
ADC->SEQ[3].SCVAL = 0;
|
||||
ADC->SEQ[4].SCVAL = 0;
|
||||
ADC->SEQ[5].SCVAL = 0;
|
||||
ADC->SEQ[6].SCVAL = 0;
|
||||
ADC->SEQ[7].SCVAL = 0;
|
||||
|
||||
//Инициализация ADC
|
||||
ADC->ACTL[0].ACTL_bit.ADCEN = 0x1; // Разрешаем работу АЦП
|
||||
//Âêëþ÷àåì ñåêâåíñîð
|
||||
ADC->SEQSYNC_bit.SYNC0 = 1;
|
||||
//Ñòàâèì ìàñêó ïðåðûâàíèÿ
|
||||
ADC->IM_bit.SEQIM0 = 1;
|
||||
//Íàñòðàèâàåì èñòî÷íèê çàïóñêà ïðîãðàììíûé
|
||||
ADC->EMUX_bit.EM0 = ADC_EMUX_EM0_SwReq;
|
||||
// Ðàçðåøèòü ñåêâåíñîðîâ
|
||||
ADC->SEQEN_bit.SEQEN0 = 1;
|
||||
//Íàñòðàèâàåì êîëè÷åñòâî ïåðåçàïóñêîâ ñåêâåíñîðà RCNT + 1
|
||||
ADC->SEQ[0].SCCTL_bit.RCNT = 3;
|
||||
ADC->SEQ[0].SCCTL_bit.RAVGEN = 1; // Ðàçðåøåíî óñðåäíåíèå
|
||||
// Íåò ïðåðûâàíèÿ
|
||||
ADC->SEQ[0].SCCTL_bit.ICNT = 0;
|
||||
ADC->SEQ[0].SRQCTL_bit.RQMAX = 0x6;
|
||||
|
||||
|
||||
ADC->ACTL[0].ACTL_bit.ADCEN = 0x1; // Ðàçðåøàåì ðàáîòó ÀÖÏ
|
||||
ADC->ACTL[0].ACTL_bit.SELRES = ADC_ACTL_ACTL_SELRES_12bit;
|
||||
ADC->ACTL[1].ACTL_bit.ADCEN = 0x1; // Разрешаем работу АЦП
|
||||
ADC->ACTL[1].ACTL_bit.ADCEN = 0x1; // Ðàçðåøàåì ðàáîòó ÀÖÏ
|
||||
ADC->ACTL[1].ACTL_bit.SELRES = ADC_ACTL_ACTL_SELRES_12bit;
|
||||
ADC->ACTL[2].ACTL_bit.ADCEN = 0x1; // Разрешаем работу АЦП
|
||||
ADC->ACTL[2].ACTL_bit.ADCEN = 0x1; // Ðàçðåøàåì ðàáîòó ÀÖÏ
|
||||
ADC->ACTL[2].ACTL_bit.SELRES = ADC_ACTL_ACTL_SELRES_12bit;
|
||||
ADC->ACTL[3].ACTL_bit.ADCEN = 0x1; // Разрешаем работу АЦП
|
||||
ADC->ACTL[3].ACTL_bit.ADCEN = 0x1; // Ðàçðåøàåì ðàáîòó ÀÖÏ
|
||||
ADC->ACTL[3].ACTL_bit.SELRES = ADC_ACTL_ACTL_SELRES_12bit;
|
||||
|
||||
//Настройка секвенсора 0
|
||||
// CH0, CH1, CH2, CH3.
|
||||
ADC->EMUX_bit.EM0 = ADC_EMUX_EM0_PWM012A; // Запуск от таймера
|
||||
ADC->SEQSYNC = ADC_SEQSYNC_SYNC0_Msk; // Разрешить секвенсор SEQ0
|
||||
ADC->SEQ[0].SRQCTL_bit.RQMAX = 0x6; // Опрашивать 4 канала за раз = RQMAX + 1
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ0 = 13; // Какой вход АЦП когда опрашивается
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ1 = 19; // --//--
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ2 = 1; // --//--
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ3 = 31; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ4 = 18; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ5 = 27; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ6 = 29; // --//--
|
||||
ADC->SEQ[0].SCCTL_bit.RCNT = 3; // Делать ещё три перезапуска после первого запуска
|
||||
ADC->SEQ[0].SRTMR_bit.VAL = pwmPrd / (ADC->SEQ[0].SCCTL_bit.RCNT + 1) / AdcDiv; // Пауза между пусками АЦП на период ШИМ в тактах ACLK
|
||||
ADC->SEQ[0].SCCTL_bit.RAVGEN = 1; // Разрешить усреднять по 4 точкам
|
||||
ADC->SEQEN_bit.SEQEN0 = 1; // Разрешить секвенсор 0
|
||||
ADC->SEQ[0].SCCTL_bit.ICNT = 6; // Вызов прерывания через каждые (ICNT + 1) записи в fifo
|
||||
|
||||
// Очистка FIFO
|
||||
while (ADC->SEQ[0].SFLOAD)
|
||||
trash = ADC->SEQ[0].SFIFO;
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ0 = 13; // Êàêîé âõîä ÀÖÏ êîãäà îïðàøèâàåòñÿ
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ1 = 19; // --//--
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ2 = 1; // --//--
|
||||
ADC->SEQ[0].SRQSEL0_bit.RQ3 = 20; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ4 = 15; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ5 = 27; // --//--
|
||||
ADC->SEQ[0].SRQSEL1_bit.RQ6 = 29; // --//--
|
||||
|
||||
|
||||
// Æä¸ì, ïîêà ÀÖÏ âûñòàâèò ôëàã "ÃÎÒÎÂ" (ìîæíî âñòàâèòü ýòîò öèêë ïîñëå "ADCEN = 1")
|
||||
while (!ADC->ACTL[0].ACTL_bit.ADCRDY) {};
|
||||
@ -103,10 +96,6 @@ void AdcDrv_init(TAdcDrv *p) {
|
||||
while (!ADC->ACTL[2].ACTL_bit.ADCRDY) {};
|
||||
while (!ADC->ACTL[3].ACTL_bit.ADCRDY) {};
|
||||
|
||||
// Разрешить прерывание от первого секвенсера
|
||||
ADC->IM_bit.SEQIM0 = 1;
|
||||
NVIC_EnableIRQ(ADC_SEQ0_IRQn);
|
||||
NVIC_SetPriority(ADC_SEQ0_IRQn, IRQ_PRIORITY_ADC);
|
||||
}
|
||||
|
||||
|
||||
@ -121,24 +110,28 @@ void AdcDrv_fast_calc(TAdcDrv *p) {
|
||||
Uint32 trash;
|
||||
Uint16 pot, ain1, ain2, temper;
|
||||
|
||||
// Если всё пошло хорошо, то в ФИФЕ будут уже усреднённые результаты - 4 штуки.
|
||||
p->IA_temp = ADC->SEQ[0].SFIFO;
|
||||
p->IC_temp = ADC->SEQ[0].SFIFO;
|
||||
p->Udc_temp = ADC->SEQ[0].SFIFO;
|
||||
pot = ADC->SEQ[0].SFIFO;
|
||||
ain1 = ADC->SEQ[0].SFIFO;
|
||||
ain2 = ADC->SEQ[0].SFIFO;
|
||||
temper = ADC->SEQ[0].SFIFO;
|
||||
p->IA_temp = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
p->IC_temp = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
|
||||
// Очистка FIFO на случай, если почему-то там оказалось больше чем надо значений (бывает после остановки житагом)
|
||||
while (ADC->SEQ[0].SFLOAD)
|
||||
trash = ADC->SEQ[0].SFIFO;
|
||||
p->Udc_temp = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
|
||||
pot = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
ain1 = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
ain2 = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
|
||||
p->T_temp = (int16) ADC->SEQ[0].SFIFO_bit.DATA;
|
||||
|
||||
// Ïðåîáðàçîâàíèå
|
||||
p->Imeas_a = p->IaGainNom * (((p->IA_temp<< 4) + p->Imeas_a_offset));
|
||||
p->Imeas_c = p->IcGainNom * (((p->IC_temp<< 4) + p->Imeas_c_offset));
|
||||
p->Udc_meas = p->UdcGainNom * (p->Udc_temp + p->Udc_meas_offset);
|
||||
p->Imeas_b = -p->Imeas_a - p->Imeas_c;
|
||||
p->T_meas = p->TGainNom*(p->T_temp);
|
||||
|
||||
// Î÷èñòêà ÔÈÔÎ
|
||||
while (ADC->SEQ[0].SFLOAD)
|
||||
trash = ADC->SEQ[0].SFIFO;
|
||||
|
||||
}
|
||||
|
||||
//!Ìåäëåííûé ðàñ÷åò.
|
||||
@ -180,25 +173,12 @@ void AdcDrv_fast_calc(TAdcDrv *p) {
|
||||
|
||||
//! \memberof TAdcDrv
|
||||
void AdcDrv_slow_calc(TAdcDrv *p) {
|
||||
// Пересчёт пауз между перезапусками
|
||||
volatile Uint16 pwmPrd = PWM0->TBPRD * (SystemCoreClock / APB0BusClock);
|
||||
|
||||
// Если считает вверх-вниз, то период на деле в два раза больше
|
||||
if (PWM0->TBCTL_bit.CTRMODE == TB_COUNT_UPDOWN)
|
||||
pwmPrd = pwmPrd << 1;
|
||||
|
||||
// Делитель частоты АЦП
|
||||
Uint16 AdcDiv = 2 * (RCU->ADCCFG_bit.DIVN + 1);
|
||||
if (pwmPrd < 1000) pwmPrd = 1000;
|
||||
|
||||
// Пауза между перезапускмами
|
||||
// VAL = (Период ШИМ в тактах SysClkOut) / (Кол-во перезапусков) / (Делитель частоты АЦП)
|
||||
ADC->SEQ[0].SRTMR_bit.VAL = pwmPrd / (ADC->SEQ[0].SCCTL_bit.RCNT + 1) / AdcDiv;
|
||||
|
||||
p->IaGainNom = _IQ16mpy(p->Imeas_a_gain, drv_params._1_I_nom) << 1;
|
||||
p->IbGainNom = _IQ16mpy(p->Imeas_b_gain, drv_params._1_I_nom) << 1;
|
||||
p->IcGainNom = _IQ16mpy(p->Imeas_c_gain, drv_params._1_I_nom) << 1;
|
||||
p->UdcGainNom = _IQ16mpy(p->Udc_meas_gain, drv_params._1_Udc_nom) << 4;
|
||||
p->TGainNom = _IQ16mpy(p->T_meas_gain, _IQ(0.05)) << 4; //0.05 = 1/20
|
||||
}
|
||||
|
||||
//! Ìèëëèñåêóíäíûé ðàñ÷åò
|
||||
|
@ -322,6 +322,6 @@ void QEP1_IRQHandler(void)
|
||||
|
||||
//Прерывание вызывается один раз на периоде ШИМ и забирает 4 результата за период
|
||||
void ADC_SEQ0_IRQHandler (void) {
|
||||
adc.fast_calc(&adc);
|
||||
ADC->IC_bit.SEQIC0 = 1;
|
||||
// adc.fast_calc(&adc);
|
||||
// ADC->IC_bit.SEQIC0 = 1;
|
||||
}
|
||||
|
2
cood.xml
2
cood.xml
@ -3776,7 +3776,7 @@
|
||||
<description description=""/>
|
||||
</obj_5114h.01h>
|
||||
<obj_5114h.02h DataType="Editable" name="Ðåæèì ðàáîòû" addr="sm_ctrl.run_mode" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
|
||||
<format Type="StandartNum" Size="16" Signed="false"/>
|
||||
<format Type="Bit" Visualization="Text" Length="5" StartBit="0"/>
|
||||
<text text="ÐåæÐàá" textID="411"/>
|
||||
<defaults default="4" min="" max=""/>
|
||||
<description description="Æåëàåìîå ñîñòîÿíèå ðàáîòû ïðèâîäà. 5 - äàò÷èêîâîå, 4 - èñòî÷íèê òîêà, 3 - ñêàëÿðíîå óïðàâëåíèå U(f), 2 - ðåæèì óæåðæàíèÿ ïîä òîêîì."/>
|
||||
|
Loading…
Reference in New Issue
Block a user