Правильно настроены ножки под UART для ModBus. Обновлен модуль дискретных входов/выходов.

This commit is contained in:
dimidxxx 2019-09-30 19:41:07 +03:00
parent 2dd8e3d58c
commit 5812e0c8c9
9 changed files with 193 additions and 153 deletions

View File

@ -41,9 +41,9 @@ extern "C"
#if defined (HW_MCB3)
//Для управления контроллером мы используем внешние дискретные входы с использованием фильтрации (см. V_DIO)
#define STARTBUTTON (BIT_IS_SET(input_vect, 0) ? 1 : 0) //Проверка на уставку бита в векторе дискретных входов
#define STOPBUTTON (BIT_IS_SET(input_vect, 1) ? 1 : 0) //Проверка на уставку бита в векторе дискретных входов
#define RESETBUTTON (BIT_IS_SET(input_vect, 2) ? 1 : 0) //Проверка на уставку бита в векторе дискретных входов
#define STARTBUTTON (dio.in_bit.n0) //Проверка на уставку бита в векторе дискретных входов
#define STOPBUTTON (dio.in_bit.n1) //Проверка на уставку бита в векторе дискретных входов
#define RESETBUTTON (dio.in_bit.n2) //Проверка на уставку бита в векторе дискретных входов
#elif defined (HW_MCB3_SIMULATOR)
#define STARTBUTTON 0
#define STOPBUTTON 0

View File

@ -47,7 +47,7 @@ extern "C"
#define DRV_FAULT3 (GPIOD->DATA & (1 << 4)) //Àâàðèÿ êëþ÷à A2
#define DRV_FAULT4 (GPIOD->DATA & (1 << 5)) //Àâàðèÿ êëþ÷à B0 èëè B1 èëè B2
//Äëÿ ñáðîñà àïïàðàòíîé àâàðèè â äàííîì êîíòðîëëåðå èñïîëüçóååòñÿ âíåøíèé äèñêðåòíûé ïîðò ââîäà
#define RESET_FAULT_BUTTON (BIT_IS_SET(input_vect, 2) ? 1 : 0) //Åñëè óñòàíîâëåí 3-é áèò â âåêòîðå äèñêðåòíûõ âõîäîâ
#define RESET_FAULT_BUTTON (dio.in_bit.n2) //Äèñêðåòíûé âõîä äëÿ êíîïêè ñáðîñà àâàðèè
#elif defined (HW_MCB3_SIMULATOR)
#define DRV_FAULT 0
#define DRV_FAULT1 0

View File

@ -16,7 +16,7 @@
\file V_DIO.h
\brief Ěîäóëü äčńęđĺňíűő âőîäîâ/âűőîäîâ
\author ÎÎÎ "ÍĎÔ Âĺęňîđ". http://motorcontrol.ru
\version v 1.0 25/08/2017
\version v 2.0 25/09/2019
\addtogroup
@{*/
@ -30,84 +30,115 @@ extern "C" {
#endif
// Ìàêðîñ óñòàíîâêè â '1' çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) óñòàíàâëèâàåìîãî áèòà
#define SET_BIT(var, index) var |= (1 << index);
// Ìàêðîñ ñáðîñà â '0' çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) î÷èùàåìîãî áèòà
#define CLEAR_BIT(var, index) var &= (~(1 << index));
// Ìàêðîñ ïðîâåðêè íåíóëåâîãî ñîñòîßíèÿ çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) ïðîâåðßåìîãî áèòà
#define BIT_IS_SET(var, index) ((var & (1 << index)) != 0)
// Ìàêðîñ ïðîâåðêè íóëåâîãî ñîñòîßíèÿ çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) ïðîâåðßåìîãî áèòà
#define BIT_IS_CLEAR(var, index) ((var & (1 << index)) == 0)
// Äåôàéíèì äèñêðåòíûå âõîäû
#ifdef HW_MCB3
//TODO ïåðåäåëàòü
#define D_IN1 ((GPIOM->DATA & (1 << 13)) == 0) //M13 Ñòàðò
#define D_IN2 ((GPIOM->DATA & (1 << 11)) == 0) //M11 Ñòîï
#define D_IN3 ((GPIOM->DATA & (1 << 10)) == 0) //M10 Ñáðîñ àâàðèé
#else
#define D_IN1 0
#define D_IN2 0
#define D_IN3 0
#endif
typedef struct SDIO {
// Äåôàéíèì äèñêðåòíûå âûõîäû
#ifdef HW_MCB3
#define D_OUT1_ON GPIOD->DATAOUTSET = GPIO_PIN_1
#define D_OUT1_OFF GPIOD->DATAOUTCLR = GPIO_PIN_1
#define D_OUT2_ON GPIOD->DATAOUTSET = GPIO_PIN_2
#define D_OUT2_OFF GPIOD->DATAOUTCLR = GPIO_PIN_2
#define D_OUT3_ON GPIOM->DATAOUTSET = GPIO_PIN_14
#define D_OUT3_OFF GPIOM->DATAOUTCLR = GPIO_PIN_14
#else
#define D_OUT1_ON
#define D_OUT1_OFF
#define D_OUT2_ON
#define D_OUT2_OFF
#define D_OUT3_ON
#define D_OUT3_OFF
#endif
union { //!<Âåêòîð óïðàâëåíèÿ äèñêðåòíûìè âûõîäàìè
Uint16 out;
struct {
Uint16 n0:1;
Uint16 n1:1;
Uint16 n2:1;
Uint16 n3:1;
Uint16 n4:1;
Uint16 n5:1;
Uint16 n6:1;
Uint16 n7:1;
Uint16 n8:1;
Uint16 n9:1;
Uint16 n10:1;
Uint16 n11:1;
Uint16 n12:1;
Uint16 n13:1;
Uint16 n14:1;
Uint16 n15:1;
}out_bit;
};
union { //!<Âåêòîð ñîñòîÿíèÿ äèñêðåòíûõ âõîäîâ ñ ó÷åòîì èíâåðñèè ìàñêè
Uint16 in;
struct {
Uint16 n0:1;
Uint16 n1:1;
Uint16 n2:1;
Uint16 n3:1;
Uint16 n4:1;
Uint16 n5:1;
Uint16 n6:1;
Uint16 n7:1;
Uint16 n8:1;
Uint16 n9:1;
Uint16 n10:1;
Uint16 n11:1;
Uint16 n12:1;
Uint16 n13:1;
Uint16 n14:1;
Uint16 n15:1;
}in_bit;
};
_iq inputKf; //!<Êîýôôèöèåíò ôèëüòðàöèè äèñêðåòíûõ âõîäîâ Kf = 0.001/Tô (Tô - ïîñòîßííàß âðåìåíè ôèëüòðà, ñåê)
_iq inputOff; //!<Ïîðîã ïåðåõîäà äèñêðåòíîãî âõîäà â ñîñòîßíèå OFF (0)
_iq inputOn; //!<Ïîðîã ïåðåõîäà äèñêðåòíîãî âõîäà â ñîñòîßíèå ON (1)
// Ôèëüòðû äèñêðåòíûõ âõîäîâ
TFilter fIn0;
TFilter fIn1;
TFilter fIn2;
TFilter fIn3;
TFilter fIn4;
TFilter fIn5;
TFilter fIn6;
TFilter fIn7;
TFilter fIn8;
TFilter fIn9;
TFilter fIn10;
TFilter fIn11;
TFilter fIn12;
TFilter fIn13;
TFilter fIn14;
TFilter fIn15;
void (*init)(struct SDIO*);
void (*slow_calc)(struct SDIO*);
void (*ms_calc)(struct SDIO*);
}TDIO;
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âûõîäîâ
extern volatile Uint16 output_vect;
// Ìàñêà èíâåðòèðîâàíèß âåêòîðà ñîñòîßíèß äèñêðåòíûõ âûõîäîâ
extern volatile Uint16 output_mask;
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âõîäîâ
extern volatile Uint16 input_vect;
// Ìàñêà èíâåðòèðîâàíèß âåêòîðà ñîñòîßíèß äèñêðåòíûõ âõîäîâ
extern volatile Uint16 input_mask;
// Êîýôôèöèåíò ôèëüòðàöèè äèñêðåòíûõ âõîäîâ Kf = 0.0001/Tô
// (Tô - ïîñòîßííàß âðåìåíè ôèëüòðà, ñåê)
extern volatile _iq inputKf;
#define in_Kf inputKf // ïñåâäîíèì äëß óæå èìåþùåéñÿ ïåðåìåííîé â ñëîâàðå CANopen
// Ïîðîã ïåðåõîäà äèñêðåòíîãî âõîäà â ñîñòîßíèå OFF (0)
extern volatile _iq inputOff;
// Ïîðîã ïåðåõîäà äèñêðåòíîãî âõîäà â ñîñòîßíèå ON (1)
extern volatile _iq inputOn;
//!Èíèöèàëèçàòîð ïî-óìîë÷àíèþ.
#define DIO_DEFAULTS { .out = 0, .in = 0, \
.inputKf = 0, .inputOff = 0, .inputOn = 0, \
.fIn0 = FILTER_DEFAULTS, \
.fIn1 = FILTER_DEFAULTS, \
.fIn2 = FILTER_DEFAULTS, \
.fIn3 = FILTER_DEFAULTS, \
.fIn4 = FILTER_DEFAULTS, \
.fIn5 = FILTER_DEFAULTS, \
.fIn6 = FILTER_DEFAULTS, \
.fIn7 = FILTER_DEFAULTS, \
.fIn8 = FILTER_DEFAULTS, \
.fIn9 = FILTER_DEFAULTS, \
.fIn10 = FILTER_DEFAULTS, \
.fIn11 = FILTER_DEFAULTS, \
.fIn12 = FILTER_DEFAULTS, \
.fIn13 = FILTER_DEFAULTS, \
.fIn14 = FILTER_DEFAULTS, \
.fIn15 = FILTER_DEFAULTS, \
.init = DIO_init, \
.slow_calc = DIO_slow_calc, \
.ms_calc = DIO_ms_calc, \
}
void DIO_Init();
void DIO_slow_calc(); // âûçûâàòü â ôîíîâîé ïðîãðàììå
void DIO_fast_calc(); // âûçûâàòü ñ ÷àñòîòîé 1êÃö èëè 10 êÃö
//! \memberof TDIO
void DIO_init(TDIO* p);
//! \memberof TDIO
void DIO_slow_calc(TDIO* p);
//! \memberof TDIO
void DIO_ms_calc(TDIO* p);
#ifdef __cplusplus

View File

@ -134,6 +134,7 @@ extern Texcitation pwm_ex;
extern TDrvInterface drv_interface;
extern TLogger FaultLog;
extern TGlobalTime global_time;
extern TDIO dio;
extern TUdControl udControl;
extern TFanControl FanControl;
extern TTMU tmu;

View File

@ -54,10 +54,10 @@ void SM_Sys_Init(TSM_Sys *p) {
cur_par.init(&cur_par); //Ðàñ÷åò òåêóùèõ ïîêàçàòåëåé ïðèâîäà
leds.init(&leds);//ñâåòîäèîäû
udControl.init(&udControl); //ïëàâíàÿ çàðÿäêà ÇÏÒ ÷åðåç òåðìèñòîðû
DIO_Init(); //הטסךנועם<D7A2>ו גץמה<D79E><>ץמה<D79E>
FanControl.init(&FanControl); //âåíòèëÿòîð
//ãëîáàëüíîå âðåìß (âíåøíèå èëè âíóòð. ÷àñû)
global_time.init(&global_time);
dio.init(&dio); //äèñêðåòíûå âõîäû/âûõîäû
if (drv_params.sens_type == POS_SENSOR_TYPE_HALL){ // òèïå äàò÷èêà âûáðàí ÄÏÐ íà ýëåìåíòàõ Õîëëà
DPReCAP.Init(&DPReCAP); //ÄÏÐ èíèö.
}
@ -251,8 +251,7 @@ void SM_Sys_ms_Calc(TSM_Sys* p) {
DPReCAP.ms_calc(&DPReCAP);
}
global_time.ms_calc(&global_time);
DIO_fast_calc(); //הטסךנועם<D7A2>ו גץמה<D79E><>ץמה<D79E>
dio.ms_calc(&dio); //äèñêðåòíûå âõîäû/âûõîäû
}
//!Ìåäëåííûé ðàñ÷åò (ôîíîâûé).
@ -275,7 +274,7 @@ void SM_Sys_Slow_Calc(TSM_Sys *p) {
AutoOffset.slow_calc(&AutoOffset);
posspeedEqep.slow_calc(&posspeedEqep);//èíèöèàëèçàöèÿ ìîäóëÿ ýíêîäåðà
RotorObserver.slow_calc(&RotorObserver);//íàáëþäàòåëü ïîòîêà ðîòîðà ÀÄ
DIO_slow_calc(); //הטסךנועם<D7A2>ו גץמה<D79E><>ץמה<D79E>
dio.slow_calc(&dio); //äèñêðåòíûå âõîäû/âûõîäû
FanControl.slow_calc(&FanControl);//âåíòèëÿòîð

View File

@ -16,7 +16,7 @@
\file V_DIO.c
\brief Модуль дискретных входов/выходов
\author ООО "НПФ Вектор". http://motorcontrol.ru
\version v 1.0 25/08/2017
\version v 2.0 25/09/2019
\addtogroup
@{*/
@ -27,90 +27,98 @@
#include "filter.h"
// Äåôàéíèì äèñêðåòíûå âõîäû
#ifdef HW_MCB3
#define D_IN0 ((GPIOM->DATA & (1 << 13)) == 0) //M13 Ñòàðò
#define D_IN1 ((GPIOM->DATA & (1 << 11)) == 0) //M11 Ñòîï
#define D_IN2 ((GPIOM->DATA & (1 << 10)) == 0) //M10 Ñáðîñ àâàðèé
#else
#define D_IN0 0
#define D_IN1 0
#define D_IN2 0
#endif
// Вектор состоЯниЯ дискретных выходов
volatile Uint16 output_vect = 0;
// Маска инвертированиЯ вектора состоЯниЯ дискретных выходов
volatile Uint16 output_mask = 0;
// Вектор состоЯниЯ дискретных входов
volatile Uint16 input_vect = 0;
// Маска инвертированиЯ вектора состоЯниЯ дискретных входов
volatile Uint16 input_mask = 0;
// Коэффициент фильтрации дискретных входов Kf = 0.001/Tф
// (Tф - постоЯннаЯ времени фильтра, сек)
volatile _iq inputKf = _IQ(0.03); //Время срабатывания составляется 60мс при inputKf=_IQ(0.03) и inputOn = _IQ(0.8) в 1кГц прерывании;
// Порог перехода дискретного входа в состоЯние OFF (0)
volatile _iq inputOff = _IQ(0.3);
// Порог перехода дискретного входа в состоЯние ON (1)
volatile _iq inputOn = _IQ(0.8);
// Промежуточный вектор состоЯниЯ дискретных входов (без учёта маски инвертированиЯ)
Uint16 input = 0;
// Фильтры дискретных входов
TFilter fIn1 = FILTER_DEFAULTS;
TFilter fIn2 = FILTER_DEFAULTS;
TFilter fIn3 = FILTER_DEFAULTS;
// Äåôàéíèì äèñêðåòíûå âûõîäû
#ifdef HW_MCB3
#define D_OUT0_ON GPIOD->DATAOUTSET = GPIO_PIN_1
#define D_OUT0_OFF GPIOD->DATAOUTCLR = GPIO_PIN_1
#define D_OUT1_ON GPIOD->DATAOUTSET = GPIO_PIN_2
#define D_OUT1_OFF GPIOD->DATAOUTCLR = GPIO_PIN_2
#define D_OUT2_ON GPIOM->DATAOUTSET = GPIO_PIN_14
#define D_OUT2_OFF GPIOM->DATAOUTCLR = GPIO_PIN_14
#else
#define D_OUT0_ON
#define D_OUT0_OFF
#define D_OUT1_ON
#define D_OUT1_OFF
#define D_OUT2_ON
#define D_OUT2_OFF
#endif
void DIO_Init()
void DIO_init(TDIO* p)
{
//Íàñòðîéêà êîýôôèöèåíòîâ ôèëüòðàöèè è ïîðîãîâ ñðàáàòûâàíèÿ äëÿ äèñêðåòíûõ âõîäîâ
p->inputKf = _IQ(0.03);
p->inputOff = _IQ(0.2);
p->inputOn = _IQ(0.8);
//Âðåìÿ âêëþ÷åíèÿ/îòêëþ÷åíèÿ ïðè êîýôôèöèåíòàõ inputKf=_IQ(0.2), inputOn = _IQ(0.8), inputKf = _IQ(0.03) áóäåò ñîñòàâëÿòü ïðèìåðíî 60 ìñ (ôèëüòðû ñ÷èòàþòñÿ â 1êÃö ïðåðûâàíèè)
}
void DIO_slow_calc()
void DIO_slow_calc(TDIO* p)
{
// Получаем вектор состоЯниЯ дискретных выходов с учётом маски инвертированиЯ
Uint16 output = output_vect ^ output_mask;
// Выводим управлЯющее воздействие по Выходу 1
if (BIT_IS_SET(output, 0))
D_OUT1_OFF;
else
D_OUT1_ON;
// Выводим управлЯющее воздействие по Выходу 2
if (BIT_IS_SET(output, 1))
D_OUT2_OFF;
else
D_OUT2_ON;
// Выводим управлЯющее воздействие по Выходу 3
if (BIT_IS_SET(output, 2))
D_OUT3_OFF;
else
D_OUT3_ON;
// ОбновлЯем коэффициенты фильтрации дискретных входов
fIn1.T = inputKf;
fIn2.T = inputKf;
fIn3.T = inputKf;
// Получаем состоЯние Входа 1 с учётом фильтрации
if (fIn1.output > inputOn) SET_BIT(input, 0);
if (fIn1.output < inputOff) CLEAR_BIT(input, 0);
// Получаем состоЯние Входа 2 с учётом фильтрации
if (fIn2.output > inputOn) SET_BIT(input, 1);
if (fIn2.output < inputOff) CLEAR_BIT(input, 1);
// Получаем состоЯние Входа 3 с учётом фильтрации
if (fIn3.output > inputOn) SET_BIT(input, 2);
if (fIn3.output < inputOff) CLEAR_BIT(input, 2);
input_vect = input ^ input_mask;
p->fIn0.T = p->inputKf;
p->fIn1.T = p->inputKf;
p->fIn2.T = p->inputKf;
}
void DIO_fast_calc()
void DIO_ms_calc(TDIO* p)
{
//------------------------Îáðàáîòêà âõîäîâ------------------------------//
// Èíåðöèîííûé ôèëüòð äèñêðåòíîãî Âõîäà 0
p->fIn0.input = (D_IN0 == 1) ? _IQ(1.0) : 0;
p->fIn0.calc(&(p->fIn0));
// Инерционный фильтр дискретного Входа 1
fIn1.input = (D_IN1 == 1) ? _IQ(1.0) : 0;
fIn1.calc(&fIn1);
p->fIn1.input = (D_IN1 == 1) ? _IQ(1.0) : 0;
p->fIn1.calc(&(p->fIn1));
// Инерционный фильтр дискретного Входа 2
fIn2.input = (D_IN2 == 1) ? _IQ(1.0) : 0;
fIn2.calc(&fIn2);
// Инерционный фильтр дискретного Входа 3
fIn3.input = (D_IN3 == 1) ? _IQ(1.0) : 0;
fIn3.calc(&fIn3);
p->fIn2.input = (D_IN2 == 1) ? _IQ(1.0) : 0;
p->fIn2.calc(&(p->fIn2));
// Ïîëó÷àåì ñîñòîßíèå Âõîäà 0 ñ ó÷¸òîì ôèëüòðàöèè
if (p->fIn0.output > p->inputOn) p->in_bit.n0 = 1;
if (p->fIn0.output < p->inputOff) p->in_bit.n0 = 0;
// Ïîëó÷àåì ñîñòîßíèå Âõîäà 1 ñ ó÷¸òîì ôèëüòðàöèè
if (p->fIn1.output > p->inputOn) p->in_bit.n1 = 1;
if (p->fIn1.output < p->inputOff) p->in_bit.n1 = 0;
// Ïîëó÷àåì ñîñòîßíèå Âõîäà 2 ñ ó÷¸òîì ôèëüòðàöèè
if (p->fIn2.output > p->inputOn) p->in_bit.n2 = 1;
if (p->fIn2.output < p->inputOff) p->in_bit.n2 = 0;
//------------------------Îáðàáîòêà âûõîäîâ------------------------------//
// Âûâîäèì óïðàâëßþùåå âîçäåéñòâèå ïî Âûõîäó 0
if (p->out_bit.n0 == 1)
D_OUT0_ON;
else
D_OUT0_OFF;
// Âûâîäèì óïðàâëßþùåå âîçäåéñòâèå ïî Âûõîäó 1
if (p->out_bit.n1 == 1)
D_OUT1_ON;
else
D_OUT1_OFF;
// Âûâîäèì óïðàâëßþùåå âîçäåéñòâèå ïî Âûõîäó 2
if (p->out_bit.n2 == 1)
D_OUT2_ON;
else
D_OUT2_OFF;
}
/*@}*/

View File

@ -69,7 +69,7 @@
void ModBus_RS_Init(TModBus *p) {
p->MBInternals.NT_UART = UART2; //Используемый в драйвере номер UART (1,2,3)
p->MBInternals.NT_UART = UART3; //Используемый в драйвере номер UART (1,2,3)
p->MBInternals.NT_UART->CR_bit.UARTEN = 1; // Разрешить работу UART
//Текущая реализация драйвера не использует FIFO, обрабатывает данные по одному байту

View File

@ -74,6 +74,7 @@ TMBVarsConv MBVarsConv = MBVARSCONV_DEFAULTS;//!<
TDrvInterface drv_interface = DRV_INTERFACE_DEFAULTS; //!<Èíòåðôåéñ äëß ðàáîòû ñ áàíêàìè àâàðèé, ñîáûòèé è ò.ï.
TLogger FaultLog = LOGGER_DEFAULTS; //!<Ïðîòîêîëèðîâàíèå àâàðèé
TGlobalTime global_time = GLOBAL_TIME_DEFAULTS; //!<Ðàáîòà ñ ÷àñàìè
TDIO dio = DIO_DEFAULTS; //!<Ìîäóëü ðàáîòû ñ äèñêðåòíûìè âõîäàìè/âûõîäàìè
TUdControl udControl = UD_CONTROL_DEFAULTS; //!<Ïëàâíàÿ çàðÿäêà ÇÏÒ ÷åðåç òåðìèñòîðû
TFanControl FanControl = FAN_CONTROL_DEFAULTS; //!<Âåíòèëÿòîð
TTMU tmu = TMU_DEFAULTS; //!<Áëîê òðèãîíîìåòè÷åñêèõ ïðåîáðàçîâàíèé

View File

@ -92,10 +92,10 @@ void gpioPeripheralInit (void) {
#endif
#ifdef MODBUS_ENA
// UART2: K10 / K11 + M2 (modbus tx/rx)
GPIOK->ALTFUNCNUM1_bit.PIN10 = 4; // UART2_RX
GPIOK->ALTFUNCNUM1_bit.PIN11 = 4; // UART2_TX
GPIOK->ALTFUNCSET = GPIO_PIN_10 | GPIO_PIN_11;
// UART3: E8 / E9 + M2 (modbus rx/tx)
GPIOE->ALTFUNCNUM1_bit.PIN8 = 4; // UART3_RX
GPIOE->ALTFUNCNUM1_bit.PIN9 = 4; // UART3_TX
GPIOE->ALTFUNCSET = GPIO_PIN_8 | GPIO_PIN_9;
GPIOM->ALTFUNCCLR = GPIO_PIN_2;
GPIOM->OUTENSET = GPIO_PIN_2;