圖1是我的AB相脈波規劃
Match0 AB相週期
Match4 觸發event4中斷,代表已經輸出完整AB相脈波。
進SCT0_IRQHandler()後判斷是否最後脈波,假如到達最後脈波,關閉SCT輸出。
以下程式是片段,實際應用我同時使用SCT0~3。
會發生圖2錯誤波形。
當四組SCT 同時發送時,各組SCT EVET4中斷觸發時間會延遲....導致無法即時關閉SCT和多送脈波。
void SCT0_SetFreq(uint32_t Freq)
{
uint32_t FreqS = 72000000 / Freq;
LPC_SCT0->MATCH[0].U = FreqS;
LPC_SCT0->MATCHREL[0].U = FreqS;
LPC_SCT0->MATCH[1].U = FreqS / 2;
LPC_SCT0->MATCHREL[1].U = FreqS / 2;
LPC_SCT0->MATCH[2].U = FreqS / 4;
LPC_SCT0->MATCHREL[2].U = FreqS / 4;
LPC_SCT0->MATCH[3].U = (FreqS / 4) + (FreqS / 2);
LPC_SCT0->MATCHREL[3].U = (FreqS / 4) + (FreqS / 2);
LPC_SCT0->MATCH[4].U = (FreqS);
LPC_SCT0->MATCHREL[4].U = (FreqS);
LPC_SCT0->EVENT[0].STATE = 0x00000001; /* event 0 only happens in state 0 */
LPC_SCT0->EVENT[0].CTRLA = (0 << 0) | /* MATCHSEL[3:0] = related to match 0 */
(1 << 12)| /* COMBMODE[13:12] = match condition only */
(1 << 14)| /* STATELD[14] = STATEV is loaded into state */
(0 << 15); /* STATEV[15] = 0 (new state is 0) */
LPC_SCT0->EVENT[1].STATE = 0x00000001; /* event 1 only happens in state 0 */
LPC_SCT0->EVENT[1].CTRLA = (1 << 0) | /* MATCHSEL[3:0] = related to match 1 */
(1 << 12)| /* COMBMODE[13:12] = match condition only */
(1 << 14)| /* STATELD[14] = STATEV is loaded into state */
(0 << 15); /* STATEV[15] = 0 (new state is 0) */
LPC_SCT0->EVENT[2].STATE = 0x00000001; /* event 2 only happens in state 0 */
LPC_SCT0->EVENT[2].CTRLA = (2 << 0) | /* MATCHSEL[3:0] = related to match 2 */
(1 << 12)| /* COMBMODE[13:12] = match condition only */
(1 << 14)| /* STATELD[14] = STATEV is loaded into state */
(0 << 15); /* STATEV[15] = 0 (new state is 0) */
LPC_SCT0->EVENT[3].STATE = 0x00000001; /* event 3 only happens in state 0 */
LPC_SCT0->EVENT[3].CTRLA = (3 << 0) | /* MATCHSEL[3:0] = related to match 3 */
(1 << 12)| /* COMBMODE[13:12] = match condition only */
(1 << 14)| /* STATELD[14] = STATEV is loaded into state */
(0 << 15); /* STATEV[15] = 0 (new state is 0) */
LPC_SCT0->EVENT[4].STATE = 0x00000001; /* event 4 only happens in state 0 */
LPC_SCT0->EVENT[4].CTRLA = (4 << 0) | /* MATCHSEL[3:0] = related to match 4 */
(1 << 12)| /* COMBMODE[13:12] = match condition only */
(1 << 14)| /* STATELD[14] = STATEV is loaded into state */
(0 << 15); /* STATEV[15] = 0 (new state is 0) */
LPC_SCT0->OUT[0].SET = 0;
LPC_SCT0->OUT[0].CLR = 0;
LPC_SCT0->OUT[1].SET = 0;
LPC_SCT0->OUT[1].CLR = 0;
LPC_SCT0->OUT[1].CLR = (1 << 0); /* event 0 will clear SCT0_OUT1 */
LPC_SCT0->OUT[1].SET = (1 << 1); /* event 1 will set SCT0_OUT1 */
LPC_SCT0->OUT[0].SET = (1 << 2); /* event 2 will set SCT0_OUT0 */
LPC_SCT0->OUT[0].CLR = (1 << 3); /* event 3 will clear SCT0_OUT0 */
}
#define SCT0_HALT_Enable LPC_SCT0->CTRL_L |= (1 << 2) /* Halt SCT0 */
#define SCT0_HALT_Disable LPC_SCT0->CTRL_L ^= (3 << 2) /* Unhalt(Start) SCT0 and clear counter */
#define SCT1_HALT_Enable LPC_SCT1->CTRL_L |= (1 << 2) /* Halt SCT1 */
#define SCT1_HALT_Disable LPC_SCT1->CTRL_L ^= (3 << 2) /* Unhalt(Start) SCT1 and clear counter */
#define SCT2_HALT_Enable LPC_SCT2->CTRL_L |= (1 << 2) /* Halt SCT2 */
#define SCT2_HALT_Disable LPC_SCT2->CTRL_L ^= (3 << 2) /* Unhalt(Start) SCT0 and clear counter */
#define SCT3_HALT_Enable LPC_SCT3->CTRL_L |= (1 << 2) /* Halt SCT3 */
#define SCT3_HALT_Disable LPC_SCT3->CTRL_L ^= (3 << 2) /* Unhalt(Start) SCT3 and clear counter */
#define SCT0_OUTPUT_RESET LPC_SCT0->OUTPUT = 0
#define SCT1_OUTPUT_RESET LPC_SCT1->OUTPUT = 0
#define SCT2_OUTPUT_RESET LPC_SCT2->OUTPUT = 0
#define SCT3_OUTPUT_RESET LPC_SCT3->OUTPUT = 0
void SCT0_IRQHandler(void)
{
SctCurPulsNum[0]++;
if ((SctGoalPulsNum[0] != 0)&&(SctCurPulsNum[0] >= SctGoalPulsNum[0]))
{
SCT0_HALT_Enable;
SCT0_OUTPUT_RESET;
}
LPC_SCT0->EVFLAG = 0x00000010; /* clear event 4 flag */
}
static void Setup_SCT(void)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_MovablePortPinAssign(SWM_SCT0_OUT0_O, 0, 0); //PIO0_0 Y0
Chip_SWM_MovablePortPinAssign(SWM_SCT0_OUT1_O, 0, 1); //PIO0_1 Y1
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
/* Config SCT0 */
LPC_SYSCON->SYSAHBCLKCTRL[1] |= (1 << 2); /* enable the SCT0 clock */
LPC_SCT0->CONFIG |= (1 << 0) | (1 << 17); /* unified 32-bit timer, auto limit */
LPC_SCT0->CTRL_L |= (0) << 5; /* set prescaler, SCT clock = 72M/(0+1) = 72Mhz */
LPC_SCT0->EVEN = (1 << 4); /* event 4 generates an interrupt */
NVIC_EnableIRQ (SCT0_IRQn); /* enable SCT0 interrupt */
}