⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 signalling.c

📁 STM32,5110液晶显示超声波测距探鱼器200KHz,带电路图,精确到厘米
💻 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 + -