📄 signalling.c
字号:
#include "Signalling.h"
//void OUTPUT_RELAY_CONTACT(void)
//{
// GPIO_SetBits(SIG_OUT_SW_PORT, SIG_OUT_SW_PIN);
//}
//void OUTPUT_RELAY_RELEASE(void)
//{
// GPIO_ResetBits(SIG_OUT_SW_PORT, SIG_OUT_SW_PIN);
//}
//
//void OPEN_LOW_MOSFET_A(void)
//{
// GPIO_ResetBits(SIG_GEN_PULSE_A_PORT, SIG_GEN_PULSE_A_PIN);
//}
//
//void OPEN_LOW_MOSFET_B(void)
//{
// GPIO_ResetBits(SIG_GEN_PULSE_B_PORT, SIG_GEN_PULSE_B_PIN);
//}
//void ENABLE_SIG_EXTI(void)
//{
// sta_EXTI_InitStructure.EXTI_LineCmd = ENABLE;
// EXTI_Init(&sta_EXTI_InitStructure);
//}
//void DISABLE_SIG_EXTI(void)
//{
// sta_EXTI_InitStructure.EXTI_LineCmd = DISABLE;
// EXTI_Init(&sta_EXTI_InitStructure);
//}
void SIG_Configuration(void)
{
/* TIM1 is at APB2 clock domain, so it's 72M clock counter
TIM1 frequency = TIM1 counter clock / (TIM1_PERIOD + 1) = 200 KHz
and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50%
The channel 1 and channel 1N duty cycle is set to 50%
The Timer pulse is calculated as follows:
- ChannelxPulse = DutyCycle * (TIM1_PERIOD - 1) / 100
*/
/* TIM1 is at APB2 clock domain, so it's 72M clock counter
TIM1 frequency = TIM1 counter clock / (TIM1_PERIOD + 1) = 40 KHz
and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50%
The channel 1 and channel 1N duty cycle is set to 50%
The Timer pulse is calculated as follows:
- ChannelxPulse = DutyCycle * (TIM1_PERIOD - 1) / 100
*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = SIG_GEN_TIMER_PERIOD_200K;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = SIG_PULSE_NUM;
TIM_TimeBaseInit(SIG_GEN_TIMER, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = SIG_200K_PULSE_DUTY;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(SIG_GEN_TIMER, &TIM_OCInitStructure);
/* Automatic Output enable, Break, dead time and lock configuration*/
// TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
// TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
// TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
// TIM_BDTRInitStructure.TIM_DeadTime = 11;
// TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
// TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
// TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
//
// TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_ITConfig(SIG_GEN_TIMER, TIM_IT_Update, ENABLE);
// TIM_SelectOnePulseMode(SIG_GEN_TIMER, TIM_OPMode_Single);
/* TIM1 Main Output Enable */
//TIM_CtrlPWMOutputs(SIG_GEN_TIMER, ENABLE);
/* TIM1 counter enable */
//TIM_Cmd(SIG_GEN_TIMER, ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = SIG_DETECT_TIMER_PRESCAL;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = SIG_DETECT_TIMER_PERIOD;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(SIG_DETECT_TIMER, &TIM_TimeBaseStructure);
TIM_ITConfig(SIG_DETECT_TIMER, TIM_IT_Update, ENABLE);
// SIG in configuratuion
EXTI_DeInit();
/* Connect EXTI0 Line to PB.00 pin */
GPIO_EXTILineConfig(SIG_RECV_EXTI_PORT_SOURCE, SIG_RECV_EXTI_PIN_SOURCE);
/* Configure EXTI0 line */
gEXTI_InitStructure.EXTI_Line = SIG_RECV_EXTI_LINE;
gEXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
gEXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
gEXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&gEXTI_InitStructure);
}
uint16_t getMaxUint16NUM(uint16_t *pInputRawData, uint8_t inputArrayLength)
{
uint16_t sortResult;
uint8_t arrayIndex;
sortResult = *pInputRawData;
for (arrayIndex = 1; arrayIndex < inputArrayLength; arrayIndex++)
{
if (sortResult < *(pInputRawData + arrayIndex))
{
sortResult = *(pInputRawData + arrayIndex);
}
}
return sortResult;
}
uint16_t getMinUint16NUM(uint16_t *pInputRawData, uint8_t inputArrayLength)
{
uint16_t sortResult;
uint8_t arrayIndex;
sortResult = *pInputRawData;
for (arrayIndex = 1; arrayIndex < inputArrayLength; arrayIndex++)
{
if (*(pInputRawData + arrayIndex) < sortResult)
{
sortResult = *(pInputRawData + arrayIndex);
}
}
return sortResult;
}
uint8_t *autorangeUint16NUMtoUint8(uint16_t *pInputRawData, uint8_t inputArrayLength,
uint16_t minInputRawData, uint16_t maxInputRawData, uint8_t *pOutputProcessedData)
{
// Also sequency the stream from pReceivedRawData
uint8_t tempIndex;
uint16_t tempRange;
if (maxInputRawData - minInputRawData < HMI_HEIGHT_PIX)
{
for (tempIndex = 0; tempIndex < inputArrayLength; tempIndex++)
{
*(pOutputProcessedData + tempIndex) = (uint8_t)(*pInputRawData - minInputRawData);
if ((receivedRawData + HMI_WIDTH_PIX - 1) == pInputRawData)
{
pInputRawData = receivedRawData;
}
else
{
pInputRawData++;
}
}
}
else
{
tempRange = maxInputRawData - minInputRawData;
for (tempIndex = 0; tempIndex < inputArrayLength; tempIndex++)
{
*(pOutputProcessedData + tempIndex) = (uint8_t)(((*pInputRawData - minInputRawData) * (HMI_HEIGHT_PIX - 1)) / tempRange);
if ((receivedRawData + HMI_WIDTH_PIX - 1) == pInputRawData)
{
pInputRawData = receivedRawData;
}
else
{
pInputRawData++;
}
}
}
return pOutputProcessedData;
}
Boolean fishDetector(uint16_t newRawData)
{
// If detect falling edge whithin MAX_NEW_DATA_NUM_AFTER_RISING times new data acquired after detect rising edge
static uint16_t staLastRawData = 0;
static uint8_t staAfterRisingCNT = 0;
if (RESET == FLAG_SIG_FISH_DETECT_RISING)
{
staAfterRisingCNT = 0;
if (newRawData < staLastRawData)
{
if ((staLastRawData - newRawData) > DEPTH_DIFF_FISH_DETECT_THR)
{
FLAG_SIG_FISH_DETECT_RISING = SET;
}
}
}
else
{
// ----====!!!! ATTENTION !!!!====----
// ----====!!!! THis may be fish !!!!====----
if (abs(staLastRawData - newRawData) < VIB_THR_AFTER_RISING)
{
staAfterRisingCNT++;
if (staAfterRisingCNT > MAX_NEW_DATA_NUM_AFTER_RISING)
{ // unfortunately, the "fish" is too wide...
// Alarm eliminate,
FLAG_SIG_FISH_DETECT_RISING = RESET;
}
}
else
{
if (newRawData < staLastRawData)
{
// Continuely rising, what happend?
// Alarm eliminate
FLAG_SIG_FISH_DETECT_RISING = RESET;
}
else
{
// ----====!!!! NICE !!!!====----
// ----====!!!! Depth Increase !!!!====----
// ----====!!!! FISH !!!!====----
staLastRawData = newRawData;
FLAG_SIG_FISH_DETECT_RISING = RESET;
return TRUE;
}
}
}
staLastRawData = newRawData;
return FALSE;
}
void sigDataHandler(uint16_t *pInputRawDataBufStart, uint16_t *pInputRawDataBufPos, uint8_t inputArrayLength, uint8_t *pOutputProcessedData)
{
if (SET == FLAG_SIG_NEW_DATA_INCOME)
{
FLAG_SIG_NEW_DATA_INCOME = RESET;
gMaxSigRawData = getMaxUint16NUM(pInputRawDataBufStart, inputArrayLength);
gMinSigRawData = getMinUint16NUM(pInputRawDataBufStart, inputArrayLength);
if (fishDetector(*pReceivedRawData))
{
FLAG_SIG_FISH_DETECTED = SET;
}
gMaxDepthInCM = GET_SEA_WATER_DEPTH_IN_CM_US(gMaxSigRawData);
gMinDepthInCM = GET_SEA_WATER_DEPTH_IN_CM_US(gMinSigRawData);
autorangeUint16NUMtoUint8(pInputRawDataBufPos, inputArrayLength, gMinSigRawData, gMaxSigRawData, pOutputProcessedData);
FLAG_HMI_DEPTH_CURVE_REDRAW = SET;
}
}
void SIG_Manager(void)
{
static uint32_t sta_LastTXTimeRecord;
static uint16_t sta_OutputRelayStartContactTimeRecord;
static uint16_t sta_StartVDampTimeRecord;
// static uint16_t staTestCurveVar = 0;
switch (sta_SIG_StateMachine)
{
case SIG_STATE_IDLE:
if (SET == FLAG_SIG_START_TX)
{
FLAG_SIG_START_TX = RESET;
sta_SIG_StateMachine = SIG_STATE_CONFIG;
}
break;
case SIG_STATE_CONFIG:
/* Signalling configuration ------------------------------------------------------*/
SIG_Configuration();
pReceivedRawData = receivedRawData;
pReceivedProcessedData = receivedProcessedData;
FLAG_SIG_NEW_DATA_INCOME = RESET;
//sta_LastTXTimeRecord = gSystem_1ms_CNT;
sta_SIG_StateMachine = SIG_STATE_WAITING_NEXT_TX;
break;
case SIG_STATE_PREPARE_TX:
sta_LastTXTimeRecord = gSystem_1ms_CNT; // Used to judge when to start next TX
sta_OutputRelayStartContactTimeRecord = GET_GLOBAL_FREERUN_US;
MOSFET_DRIVER_ON;
OUTPUT_RELAY_CONTACT;
RECV_RELAY_RELEASE; // Just make sure input is totally cut off to prevent blow up OP
// #ifdef TESTPIN_ENABLE
// if (SIG_Out_Relay_CNT < SIG_OUT_RELAY_SW_THRE)
// {
// SIG_Out_Relay_CNT++;
// TEST_PIN_2_HIGH;
// }
// else if (SIG_Out_Relay_CNT < SIG_OUT_RELAY_SW_THRE + SIG_OUT_RELAY_SW_THRE)
// {
// SIG_Out_Relay_CNT++;
// TEST_PIN_2_LOW;
// }
// else
// {
// SIG_Out_Relay_CNT = 0;
// }
// #endif
// Clear works
FLAG_SIG_START_TX = RESET;
FLAG_SIG_TX_FINISHED = RESET;
FLAG_SIG_CONTACT_RELAY = RESET;
FLAG_SIG_RELAY_CONTACTED = RESET;
FLAG_SIG_RECV_TIME_REACH = RESET;
FLAG_SIG_SUCC_RECVEIVED = RESET;
DISABLE_SIG_EXTI;
TIM_Cmd(SIG_GEN_TIMER, DISABLE);
TIM_Cmd(SIG_DETECT_TIMER, DISABLE);
TIM_SetCounter(SIG_GEN_TIMER, 0);
TIM_SetCounter(SIG_DETECT_TIMER, 0);
sta_SIG_StateMachine = SIG_STATE_START_TX;
break;
case SIG_STATE_START_TX:
if ((uint16_t)(GET_GLOBAL_FREERUN_US - sta_OutputRelayStartContactTimeRecord) > OUTPUT_RELAY_CONTACT_TIME_IN_US)
{
/* PWM TIM Main Output Enable */
TIM_CtrlPWMOutputs(SIG_GEN_TIMER, ENABLE);
/* PWM TIM counter enable */
TIM_Cmd(SIG_GEN_TIMER, ENABLE);
/* SIG IN Detect TIM counter enable */
TIM_Cmd(SIG_DETECT_TIMER, ENABLE);
#ifndef DEBUG
#ifdef TRIGGER_TEST
RESET_UART2_RX_PIN;
#endif
#endif
sta_SIG_StateMachine = SIG_STATE_TXING;
}
break;
case SIG_STATE_TXING:
// Do nothing except check if TX is finished
// Close the relay acting is handled in the interrupt to make sure high voltage is cut off and save time
// Also in the interrupt CNT has been gotten from SIG_DETECT_TIMER which will be used to judge if relay has fully contact without bounce
if (SET == FLAG_SIG_TX_FINISHED)
{
FLAG_SIG_TX_FINISHED = RESET;
sta_StartVDampTimeRecord = GET_GLOBAL_FREERUN_US;
sta_SIG_StateMachine = SIG_STATE_V_DAMP;
}
break;
case SIG_STATE_V_DAMP:
// The input relay is already set to contact in the interrupt after high voltage is cut off
// Open low side MOSFET to release the high voltage stored in transducer's capacitor
OPEN_LOW_MOSFET_A;
OPEN_LOW_MOSFET_B;
sta_SIG_StateMachine = SIG_STATE_START_RX;
break;
case SIG_STATE_START_RX:
if ((uint16_t)(GET_GLOBAL_FREERUN_US - sta_StartVDampTimeRecord) > V_DAMP_TIME_IN_US)
{
// Isolate receive circle from high voltage
MOSFET_DRIVER_OFF; // Pull down IR2104's SD to disable MOSFET
OUTPUT_RELAY_RELEASE; // To isolate the out put capasitor and inductor
sta_SIG_StateMachine = SIG_STATE_RECV_RELAY_CLOSING;
}
break;
case SIG_STATE_RECV_RELAY_CLOSING:
// Check if relay has fully contact without bounce by time (CNT in SIG_DETECT_TIMER)
if ((uint16_t)(TIM_GetCounter(SIG_DETECT_TIMER) - gRelayStartCloseCNT) > RECV_RELAY_CONTACT_TIME_IN_US)
{
// Enable SIG input interrupt
gReceivedHop = 0;
ENABLE_SIG_EXTI;
#ifndef DEBUG
#ifdef TRIGGER_TEST
SET_UART2_RX_PIN;
#endif
#endif
// #ifdef TESTPIN_ENABLE
// TEST_PIN_2_LOW;
// TEST_PIN_1_HIGH;
// #endif
sta_SIG_StateMachine = SIG_STATE_RXING;
}
break;
case SIG_STATE_RXING:
if (SET == FLAG_SIG_SUCC_RECVEIVED) // This was done in EXTI handler
{
// Success fully received SIG,
// ------======!!!!!! CONGRATULATION !!!!!!======------
FLAG_SIG_SUCC_RECVEIVED = RESET;
TIM_Cmd(SIG_DETECT_TIMER, DISABLE);
// Disable SIG input interrupt
DISABLE_SIG_EXTI;
// Release the relay
RECV_RELAY_RELEASE;
*pReceivedRawData = gSIGDetectRawCNT;
// Pointer pReceivedRawData will be increased after handling the data
// Because we still need to know where the newest data is during process data
// So, make sure the routine will NOT reach here untill finished processing data
sta_SIG_StateMachine = SIG_STATE_WAITING_NEXT_TX;
}
else if (SET == FLAG_SIG_RECV_TIME_REACH)
{
// Bad news, receive something
FLAG_SIG_RECV_TIME_REACH = RESET;
RECV_RELAY_RELEASE;
// if (staTestCurveVar < 48970)
// {
// staTestCurveVar += 1000;
// }
// else
// {
// staTestCurveVar = 384;
// }
*pReceivedRawData = 0; //staTestCurveVar; //0;
// Poinyer pReceivedRawData will be increased after handling the data
// Because we still need to know where the newest data is during process data
// So, make sure the routine will NOT reach here untill finished processing data
sta_SIG_StateMachine = SIG_STATE_WAITING_NEXT_TX;
}
break;
// case SIG_STATE_WORKING:
// // During working, all event is handled by interrupt for catch the time
// if (SET == FLAG_SIG_RECV_TIME_REACH)
// {
// FLAG_SIG_RECV_TIME_REACH = RESET;
// sta_SIG_StateMachine = SIG_STATE_WAITING_NEXT_TX;
// }
// break;
case SIG_STATE_WAITING_NEXT_TX:
if ((uint32_t)(gSystem_1ms_CNT - sta_LastTXTimeRecord) > SONAR_TXRX_PERIOD)
{
FLAG_SIG_NEW_DATA_INCOME = SET;
sta_SIG_StateMachine = SIG_STATE_PREPARE_TX;
}
break;
default :
break;
}
// Only when FLAG_SIG_NEW_DATA_INCOME == SET, sigDataHandler will be executed
sigDataHandler(receivedRawData, pReceivedRawData, HMI_WIDTH_PIX, receivedProcessedData);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -