예제 #1
0
파일: PLC.c 프로젝트: bearxiong99/XXOO_000
/*******************************************************************************
* Description : PLC_Tx_begin
* Syntax      : 
* Parameters I: 
* Parameters O: 
* return      : 
*******************************************************************************/
void PLC_Tx_begin(u8 *data)
{
    PLC_Tx_bitCnt = 0u;
    PLC_Tx_byteCnt = 0u;
    
    if (((*data) & 0x80) == 0x80)
    {
        TIMER_SET_PRESCALE_VALUE(TIMER1, 0);
        TIMER_SET_CMP_VALUE(TIMER1, 98);       //285KHz(0,98)
        Freq_cnt = MAX_285K;
    }
    else
    {
        TIMER_SET_PRESCALE_VALUE(TIMER1, 0);
        TIMER_SET_CMP_VALUE(TIMER1, 500);       //255KHz(0,88)
        Freq_cnt = MAX_255K;
    }   
   
//    digitalWrite(0, HIGH);                    //P0.0 = 1 SCC
//    digitalWrite(1, HIGH);                    //P0.1 = 1 SCCOUT
    digitalWrite(36, HIGH);                    //P0.1 = 1 SCCOUT
//    Freq_cnt = 0;
    
    /* Start Timer1 counting */
    TIMER_Start(TIMER1);
}
예제 #2
0
파일: PLC.c 프로젝트: bearxiong99/XXOO_000
/*******************************************************************************
* Description : PLC Tx ISR
* Syntax      : 
* Parameters I: 
* Parameters O: 
* return      : 
*******************************************************************************/
void TMR1_IRQHandler(void)
{
    u8 temp_bit = 0u;
    
//    if(TIMER_GetIntFlag(TIMER1) == 1)
    if ((TIMER1->TISR & TIMER_TISR_TIF_Msk) == 1)
    {
        /* Clear Timer1 time-out interrupt flag */
        //TIMER_ClearIntFlag(TIMER1);
        TIMER1->TISR = TIMER_TISR_TIF_Msk;

//        TimerIntCnt[1]++;  
        Freq_cnt--;
//        Freq_cnt ^= 1;
        
        P36 ^= HIGH;                             //P0.1 = 1 SCCOUT
        /* Tx running */
        if (Freq_cnt < 0)
        {
            PLC_Tx_bitCnt++;
            if (PLC_Tx_bitCnt >= 8u)
            {
                PLC_Tx_bitCnt = 0u;
                PLC_Tx_byteCnt++;
            }
            
            temp_bit = (PLC_Tx_PN9[PLC_Tx_byteCnt] << PLC_Tx_bitCnt) & 0x80;
            if (0x80 == temp_bit)
            {
//                TIMER_SET_PRESCALE_VALUE(TIMER1, 0);
                TIMER_SET_CMP_VALUE(TIMER1, 98);       //285KHz(0,98)
                Freq_cnt = MAX_285K;
            }
            else
            {
//                TIMER_SET_PRESCALE_VALUE(TIMER1, 0);
                TIMER_SET_CMP_VALUE(TIMER1, 500);       //255KHz(0,88)
                Freq_cnt = MAX_255K;
            }
        } 
        else
        {
        }
        
        /* check Tx ending */
        if (PLC_Tx_byte  <= PLC_Tx_byteCnt)
        {
            /* Stop Timer1 counting */
            TIMER_Close(TIMER1);
            P36 = 0;               //P0.0 = 0
        }
    }
}
예제 #3
0
__INLINE void PhaseChangedRoutine(void)
{
	FLAG_PHASE_CHANGED = RESET;
	tMotor.structMotor.unPhaseChangeCNT++;
	
	if (TRUE == tMotor.structMotor.MSR.bZeroCrossDetecting)
	{
//		iPhaseChangeTime = TIMER_GetCounter(TIMER1);
		// Miss ZXD or ZXD success filter
		// If continuously detected more than MIN_SUCC_ZXD_THRESHOLD ZX, OK! GOOD!!
		if (TRUE == tMotor.structMotor.MSR.bThisPhaseDetectedZX)
		{
			tMotor.structMotor.MSR.unMissedZXD_CNT = 0;

			if (tMotor.structMotor.MSR.unSuccessZXD_CNT > MIN_SUCC_ZXD_THRESHOLD)
			{
				tMotor.structMotor.MSR.bLocked = TRUE;
			}
			else
			{
				tMotor.structMotor.MSR.unSuccessZXD_CNT++;
			}
		}
		else	// If continuously missing detected more than MAX_MISS_ZXD_THRESHOLD ZX, loss lock
		{
			tMotor.structMotor.MSR.unSuccessZXD_CNT = 0;
			// If ZX was not detected in last phase, unLastZXDetectedTime was also not updated
			// Guess one value
			unLastZXDetectedTime = GET_TIMER_DIFF((tMotor.structMotor.unActualPeriod >> 2), TIMER_GetCounter(TIMER1));
			if (tMotor.structMotor.MSR.unMissedZXD_CNT > MAX_MISS_ZXD_THRESHOLD)
			{
				if (TRUE == tMotor.structMotor.MSR.bLocked)
				{	
					tMotor.structMotor.MSR.bLocked = FALSE;
					MOTOR_SHUT_DOWN;
					setError(ERR_INTERNAL);
				}
			}
			else
			{
				tMotor.structMotor.MSR.unMissedZXD_CNT++;
			}
		}

	}

	if (TRUE == tMotor.structMotor.MSR.bLocked)
	{
		// Set a rough next phase change time as the same with last phase
		// After detected ZX in TIM1 interrupt, next phase change time will be re-configured
		TIMER_SET_CMP_VALUE(TIMER0, tMotor.structMotor.unActualPeriod << 1);
	}

	tMotor.structMotor.MSR.bThisPhaseDetectedZX = FALSE;
	// For debug
	GPIO_TOGGLE(P50);
}
int Timer_InterTimerTriggerMode(void)
{
    int volatile i;

    /* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */
    SysInit();

    /* Init UART to 115200-8n1 for print message */
    UART_Open(UART0, 115200);

    /* This sample code demonstrate inter timer trigger mode using Timer0 and Timer1
     * In this mode, Timer0 is working as counter, and triggers Timer1. Using Timer1
     * to calculate the amount of time used by Timer0 to count specified amount of events.
     * By dividing the time period recorded in Timer1 by the event counts, we get
     * the event frequency.
     */
    printf("Inter timer trigger mode demo code\n");
    printf("Please connect input source with Timer 0 counter pin PB.8, press any key to continue\n");
    UART_GetChar();

    // Give a dummy target frequency here. Will over write prescale and compare value with macro
    TIMER_Open(TIMER0, TIMER_ONESHOT_MODE, 100);

    // Update prescale and compare value. Calculate average frequency every 1000 events
    TIMER_SET_PRESCALE_VALUE(TIMER0, 0);
    TIMER_SET_CMP_VALUE(TIMER0, 1000);

    // Update Timer 1 prescale value. So Timer 1 clock is 1MHz
    TIMER_SET_PRESCALE_VALUE(TIMER1, 11);

    // We need capture interrupt
    NVIC_EnableIRQ(TMR1_IRQn);

    while(1) {
        complete = 0;
        // Count event by timer 0, disable drop count (set to 0), disable timeout (set to 0). Enable interrupt after complete
        TIMER_EnableFreqCounter(TIMER0, 0, 0, TRUE);
        while(complete == 0);
    }

}
예제 #5
0
int Timer_FreeCountingMode(void)
{
    int volatile i;

    /* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */
    SysInit();

    /* Init UART to 115200-8n1 for print message */
    UART_Open(UART0, 115200);

    printf("\nThis sample code demonstrate timer free counting mode.\n");
    printf("Please connect input source with Timer 0 capture pin PD.11, press any key to continue\n");
    UART_GeyChar();

    // Give a dummy target frequency here. Will over write capture resolution with macro
    TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1000000);

    // Update prescale to set proper resolution.
    // Timer 0 clock source is 12MHz, to set resolution to 1us, we need to
    // set clock divider to 12. e.g. set prescale to 12 - 1 = 11
    TIMER_SET_PRESCALE_VALUE(TIMER0, 11);

    // Set compare value as large as possible, so don't need to worry about counter overrun too frequently.
    TIMER_SET_CMP_VALUE(TIMER0, 0xFFFFFF);

    // Configure Timer 0 free counting mode, capture TDR value on rising edge
    TIMER_EnableCapture(TIMER0, TIMER_CAPTURE_FREE_COUNTING_MODE, TIMER_CAPTURE_RISING_EDGE);

    // Start Timer 0
    TIMER_Start(TIMER0);

    // Enable timer interrupt
    TIMER_EnableCaptureInt(TIMER0);
    NVIC_EnableIRQ(TMR0_IRQn);

    while(1);

}
예제 #6
0
__INLINE void BLDCRampUp_Manager(void)
{
	if (SET == FLAG_PHASE_CHANGED)
	{
		PhaseChangedRoutine();
		if (unPhaseChangeCNT_AtCurrentPeriod > CHANGE_DT_PR_AFTER_PHASE_CHANGED_NUM)
		{
			unPhaseChangeCNT_AtCurrentPeriod = 0;
			// Change duty and period 
//			MOTOR_RAMPUP_DT_INCR(tMotor.structMotor.ACT_DUTY);			
			MOTOR_RAMPUP_PR_DCR(tMotor.structMotor.unActualPeriod);	
			if (tMotor.structMotor.unActualPeriod <= MOTOR_RAMPUP_PR_MIN)
			{
				unPeriodChangeCNT_AfterPR_ReachMini++;
			}
		}
		unPhaseChangeCNT_AtCurrentPeriod++;
//		MOTOR_SET_DUTY(tMotor.structMotor.ACT_DUTY);
		TIMER_SET_CMP_VALUE(TIMER0, tMotor.structMotor.unActualPeriod);
		PHASE_INCREASE(unCurrentPhase);
		// Modify PWM->PHCHGNXT at last because I don't know how long needed to reload PHCH with PHCHNEXT after TIM0 time-out
		PWM->PHCHGNXT = GET_PHASE_VALUE(unCurrentPhase);
	}
}
예제 #7
0
// Take charge of all Motot control
void BLDC_SensorLessManager(void)
{
	uint16_t unMotorAlreadyRotatingPhaseTime;
	static uint32_t iEnterTimeBeforeWait;

	dutyProtection();
	phaseDurationProtection(unLastPhaseChangeTime);

	switch (tMotorState)
	{
	case MOTOR_IDLE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			unRotateDetectStartTime = unSystemTick;
			tRotateDetectState = DETECT_START;
			tMotorState = MOTOR_START;
		}
		break;
		
	case MOTOR_START:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			// Later implement this when motor can rotate
			// Then stop it while rotating to measure the waveform
			// Manually rotate it is too slow 
			unMotorAlreadyRotatingPhaseTime = canMotorContinueRunning();
			if (unMotorAlreadyRotatingPhaseTime != IS_ROTATING_DETECTING)
			{
				if (unMotorAlreadyRotatingPhaseTime > 0)
				{
					// 1 to 65534
					tMotorState = MOTOR_LOCKED;
				}
				else
				{
					// When back to Idle state the motor was already shut down
					// MOTOR_SHUT_DOWN;
					unCurrentPhase = 0;
					unLocateIndex = 0;
					tMotor.structMotor.MSR.unMissedZXD_CNT = 0;
					unLastPhaseChangeTime = unSystemTick;
					tMotor.structMotor.MSR.bMotorPowerOn = TRUE;
					// Clear start detect zero cross flag
					tMotor.structMotor.MSR.bZeroCrossDetecting = FALSE;
					tMotor.structMotor.MSR.bLocked = FALSE;
					//setPhaseManually(tMotor.structMotor.LCT_DUTY, unCurrentPhase);
					BRG_ENABLE;
					tMotorState = MOTOR_LOCATE;
				}
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_LOCATE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if (BLDC_LocatingManager() == STATUS_FINISHED)
			{
				iEnterTimeBeforeWait = unSystemTick;
				tMotorState = MOTOR_WAIT_AFTER_LOCATE;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_WAIT_AFTER_LOCATE:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if ((uint32_t)(unSystemTick - iEnterTimeBeforeWait) >= WAIT_AFTER_LOCATE_TIME)
			{
				tMotor.structMotor.unActualDuty = tMotor.structMotor.unRampUpDuty;
				tMotor.structMotor.unActualPeriod = tMotor.structMotor.unRampUpPeriod;
				tMotor.structMotor.MSR.bMotorPowerOn = TRUE;
				PHASE_INCREASE(unCurrentPhase);
				setPhaseManually(tMotor.structMotor.unActualDuty, unCurrentPhase);
				BRG_ENABLE;
				// Set timer 0 valure, use timer 0 to change phase automatically
				// ************************************************************************
				// ----==== From here current unCurrentPhase is actually next phase ====----
				// ----==== Because we want to use the HW auto phase changer (PWM->PHCHGNXT) ====----
				// So increase unCurrentPhase again. Want to get real current phase value? Read PWM->PHCHG.
				// ************************************************************************
				PHASE_INCREASE(unCurrentPhase);
				PWM->PHCHGNXT = GET_PHASE_VALUE(unCurrentPhase);
				// !!!! Need to make sure CPU runs to here every min tMotor.structMotor.ACT_PERIOD time !!!
				// !!!! If not , timer counter may already passed tMotor.structMotor.ACT_PERIOD, !!!!
				// !!!! then need to count to max timer counter number (which is 2^24), !!!!
				// !!!! go back to 0 and triger interrupt when reach ACT_PERIOD again !!!!
				TIMER_SET_CMP_VALUE(TIMER0, tMotor.structMotor.unActualPeriod);
				TIMER_Start(TIMER0);	// Once started, running and interrupting until Motor stop
				TIMER_EnableInt(TIMER0);
				unPeriodChangeCNT_AfterPR_ReachMini = 0;
				unPhaseChangeCNT_AtCurrentDuty = 0;
				unPhaseChangeCNT_AtCurrentPeriod = 0;
				tMotorState = MOTOR_RAMPUP_WO_ZXD;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_RAMPUP_WO_ZXD:	// without zero cross detection
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			BLDCRampUp_Manager();
			if (tMotor.structMotor.unActualPeriod <= MOTOR_START_ZXD_SPEED)	//(iRampUpPeriodMiniCNT > MOTOR_START_ZXD_MINROT_CNT)  //
			{
				tMotor.structMotor.MSR.bThisPhaseDetectedZX = FALSE;
				tMotor.structMotor.MSR.bZeroCrossDetecting = TRUE;
				// Speed is enough for zero cross detecting
				// Prepare everything
				// T0 used to change phase automatically -- already configured
				// T1 used to filter ZX

//				TIMER_SET_CMP_VALUE(TIMER1, GET_TIM1_CMP_VALUE(TIMER1->TDR + AVOID_ZXD_AFTER_PHCHG));
//				FLAG_TIM1_USEAGE = ENUM_TIM1_AVOID_ZXD;
				ACMP0_ENABLE;
				TIMER_Start(TIMER1);	// Once started, running until Motor stop
//				TIMER_EnableInt(TIMER1);
				// Suppose last ZX detected time 
//				unLastZXDetectedTime = MINI51_TIM_CNT_MAX - tMotor.structMotor.ACT_PERIOD / 2;
				tMotorState = MOTOR_RAMPUP_W_ZXD;
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_RAMPUP_W_ZXD:	// with zero cross detection
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			if (TRUE == tMotor.structMotor.MSR.bLocked)
			{
				// Finally, everything was prepared:
				// T0 used to change phase automatically
				// T1 used to filter ZX
				tMotorState = MOTOR_LOCKED;
			}
			else
			{
				if (unPeriodChangeCNT_AfterPR_ReachMini < RAMP_UP_MIN_PERIOD_NUM_THRS)
				{
					BLDCRampUp_Manager(); 
				}
				else
				{
					setError(ERR_RAMPUP_FAIL);
				}
			}
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	case MOTOR_LOCKED:
		if (tMotor.structMotor.MCR.bMotorNeedToRun && NO_MOTOR_EEROR)
		{
			BLDCSpeedManager();	// Mainly PWM duty increase/decrease
		}
		else
		{
			BLDC_stopMotor();
		}
		break;

	default:
		break;
	}
}
예제 #8
0
void HardwareTimer::setCompare(uint32_t val) {
  TIMER_SET_CMP_VALUE(dev, val);
}
예제 #9
0
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    volatile uint32_t u32InitCount;

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\n\nCPU @ %d Hz\n", SystemCoreClock);
    printf("+-------------------------------------------------+\n");
    printf("|    Timer1 External Counter Input Sample Code    |\n");
    printf("+-------------------------------------------------+\n\n");

    printf("# Timer Settings:\n");
    printf("  Timer1: Clock source is HCLK(50 MHz); Continuous counting mode; Interrupt enable;\n");
    printf("          External counter input enable; TCMP is 56789.\n");
    printf("# Connect P2.0 to T1 pin and pull P2.0 High/Low as T1 counter input source.\n\n");

    /* Configure P2.0 as GPIO output pin and pull pin status to Low first */
    GPIO_SetMode(P2, 0, GPIO_PMD_OUTPUT);
    P20 = 0;

    /* Initial Timer1 default setting */
    TIMER_Open(TIMER1, TIMER_CONTINUOUS_MODE, 1);

    /* Configure Timer1 setting for external counter input function */
    TIMER_SELECT_TOUT_PIN(TIMER1, TIMER_TOUT_PIN_FROM_TX_PIN);
    TIMER_SET_PRESCALE_VALUE(TIMER1, 0);
    TIMER_SET_CMP_VALUE(TIMER1, 56789);
    TIMER_EnableEventCounter(TIMER1, TIMER_COUNTER_FALLING_EDGE);
    TIMER_EnableInt(TIMER1);

    /* Enable Timer1 NVIC */
    NVIC_EnableIRQ(TMR1_IRQn);

    /* Clear Timer1 interrupt counts to 0 */
    g_au32TMRINTCount[1] = 0;

    /* Start Timer1 counting */
    TIMER_Start(TIMER1);

    /* To check if TDR of Timer1 must be 0 as default value */
    if(TIMER_GetCounter(TIMER1) != 0)
    {
        printf("Default counter value is not 0. (%d)\n", TIMER_GetCounter(TIMER1));

        /* Stop Timer1 counting */
        TIMER_Close(TIMER1);
        while(1);
    }

    /* To generate one counter event to T1 pin */
    GeneratePORT2Counter(0, 1);

    /* To check if TDR of Timer1 must be 1 */
    while(TIMER_GetCounter(TIMER1) == 0);
    if(TIMER_GetCounter(TIMER1) != 1)
    {
        printf("Get unexpected counter value. (%d)\n", TIMER_GetCounter(TIMER1));

        /* Stop Timer1 counting */
        TIMER_Close(TIMER1);
        while(1);
    }

    /* To generate remains counts to T1 pin */
    GeneratePORT2Counter(0, (56789 - 1));

    while(1)
    {
        if((g_au32TMRINTCount[1] == 1) && (TIMER_GetCounter(TIMER1) == 56789))
        {
            printf("Timer1 external counter input function ... PASS.\n");
            break;
        }
    }

    /* Stop Timer1 counting */
    TIMER_Close(TIMER1);

    while(1);
}
예제 #10
0
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    volatile uint32_t u32InitCount;
    uint32_t au32CAPValus[10];

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\n\nCPU @ %d Hz\n", SystemCoreClock);
    printf("+---------------------------------------------------+\n");
    printf("|    Timer External Capture Function Sample Code    |\n");
    printf("+---------------------------------------------------+\n\n");

    printf("# Timer Settings:\n");
    printf("  Timer0: Clock source is 12 MHz; Toggle-output mode and frequency is 500 Hz.\n");
    printf("  Timer3: Clock source is 12 MHz; Toggle-output mode and frequency is 1 Hz.\n");
    printf("  Timer2: Clock source is HCLK(72 MHz); Continuous counting mode; TCMP is 0xFFFFFF;\n");
    printf("          Counter pin enable; Capture pin and capture interrupt enable;\n");
    printf("# Generate 500 Hz frequency from TM0 and connect TM0 pin to Timer2 counter pin.\n");
    printf("# Generate 1 Hz frequency from TM3 and connect TM3 pin to TM2_EXT capture pin.\n");
    printf("# Get 500 event counts from Timer2 counter pin when each TM2_EXT pin interrupt occurred.\n\n");

    /* Initial Timer0 and Timer3 default setting */
    TIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 1000);
    TIMER_Open(TIMER3, TIMER_TOGGLE_MODE, 2);

    /* Initial Timer2 default setting */
    TIMER_Open(TIMER2, TIMER_CONTINUOUS_MODE, 1);

    /* Configure Timer2 setting for external counter input and capture function */
    TIMER_SET_PRESCALE_VALUE(TIMER2, 0);
    TIMER_SET_CMP_VALUE(TIMER2, 0xFFFFFF);
    TIMER_EnableEventCounter(TIMER2, TIMER_COUNTER_FALLING_EDGE);
    TIMER_EnableCapture(TIMER2, TIMER_CAPTURE_FREE_COUNTING_MODE, TIMER_CAPTURE_FALLING_EDGE);
    TIMER_EnableCaptureInt(TIMER2);

    /* Enable Timer2 NVIC */
    NVIC_EnableIRQ(TMR2_IRQn);

    /* Clear Timer2 interrupt counts to 0 */
    u32InitCount = g_au32TMRINTCount[2] = 0;

    /* Start Timer0, Timer2 and Timer3 counting */
    TIMER_Start(TIMER0);
    TIMER_Start(TIMER2);
    TIMER_Start(TIMER3);

    /* Check TM2_EXT interrupt counts */
    while(1) {
        if(g_au32TMRINTCount[2] != u32InitCount) {
            au32CAPValus[u32InitCount] = TIMER_GetCaptureData(TIMER2);
            printf("[%2d] - %4d\n", g_au32TMRINTCount[2], au32CAPValus[u32InitCount]);
            if(u32InitCount > 1) {
                if((au32CAPValus[u32InitCount] - au32CAPValus[u32InitCount - 1]) != 500) {
                    printf("*** FAIL ***\n");
                    while(1);
                }
            }
            u32InitCount = g_au32TMRINTCount[2];
        }
        
        if(u32InitCount == 10)
            break;
    }

    /* Stop Timer0, Timer2 and Timer3 counting */
    TIMER_Close(TIMER0);
    TIMER_Close(TIMER2);
    TIMER_Close(TIMER3);

    printf("*** PASS ***\n");

    while(1);
}