SCT appliction for outout Specified freq and Specified pulse number

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SCT appliction for outout Specified freq and Specified pulse number

Jump to solution
8,459 Views
yansinli
Contributor III
I wirte an API for PLS(freq, PLS_num)//freq :1~200k , PLS_NUM 0~ 10000 . for example ,PLS(200K,100) : SCT will send 200K Hz 100 pluse.
when SCT complete a plule , SCT interunt will happen and count pluse number , than halt SCT.
sometime  inrerupt(set Priority highest)  is too late, SCT already send one pluse or more , than interupt happen.
for expample , PLS(200K, 100pluls) , when error sct will send 101 pule .
please give me have other Halt sct method for Faster ? 
我寫了一個 API for PLS(freq, PLS_num)//freq :1~200k , PLS_num 0~ 10000. 例如,example PLS(200K,100) : SCT 輸出200K HZ 100 pluse 數。
當SCT 完成一個脈波輸出,SCT觸發中斷,計算脈波數,當最後一個脈波到達時,停止SCT。
有時中斷太晚進,導致SCT 多送出脈波後,中斷才發生關SCT。
例如 PLS(200K, 100pluls) ,錯誤情況時,SCT 會送出101脈波數。
請給我一個較快能關閉SCT的方式?
1 Solution
7,726 Views
yansinli
Contributor III
0 Kudos
20 Replies
7,726 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

非常感谢使用NXP产品,很高兴为你提供技术支持!
我觉得问题的关键是你对最后一个PWM输出完成的识别是怎么做的,如何把它的刚刚结束'设置'成一个event来触发中断来中止计数器计数应该就能满足你的要求吧,但是我不知道你在设计时具体是怎样设计的,所以我建议你最好先介绍一下设计过程以及代码实现步骤。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,726 Views
AllenLee
Contributor I

Hi jeremyzhou

yansin lee

要的應該是SCT0產生一個200KHz AB pulse輸出波形,當user設定100次200KHz AB pulse後,自動將SCT0關掉. (不用中斷去關掉SCT0,因為隨CPU的負載量變大,會導致來不及去關掉SCT0,導致額外多輸出101次的波形)

SCT0有甚麼方法可以HW的機制去完成這個機制?

Allen

0 Kudos
7,726 Views
yansinli
Contributor III
圖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 */
}
0 Kudos
7,726 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

感谢回复。
参考你的论述,我的建议是你只需event 0, 1, 2, 3, 舍弃event 4, 同时也使能event 3 触发中断,并在中断函数中,计数PWM脉冲数,当脉冲数达到(预期PWM脉冲-1),重新设置LPC_SCT0->EVENT[0].CTRLA如下,使得在Event 0触发的时候,会更改state,使得event 2无法被触发,然后在Event 0触发的中断中关闭SCT计数器。
 LPC_SCT0->EVENT[0].CTRLA =  (0 << 0) |   /* MATCHSEL[3:0] = related to match 0 */
                                (1 << 12)|   /* COMBMODE[13:12] = match condition only */
                                (0 << 14)|   /* STATELD[14] = STATEV is loaded into state */
                                (0 << 15);   /* STATEV[15] = 0 (new state is 0) */  

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,726 Views
yansinli
Contributor III

目前是因為觸發一個完整脈波的中斷延遲。導致無法即時關閉SCT。假設目標100個,第100進中斷都可能延遲。那第99就也是會進中斷延遲。

因此透過中斷關閉SCT,無法再MCU高負載時,即時關閉。能再提供其他硬體停止方式嗎? 不透過中斷停止。

0 Kudos
7,726 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

感谢回复。

首先,上述方法是通过修改event 控制寄存器使得event 2无法再被触发,即使计数器还未被停止,也能保证只输出100 PWM脉冲,在第99脉冲发出时,修改event 控制寄存器是保证修改这个动作有充足的时间来完成,而这个时间就是一个脉冲周期。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,726 Views
yansinli
Contributor III

這方式我測試後,依然無法準確送100個。

假設第99個脈波完成中斷就已經延遲了!!! 硬體已經多打1個脈波。 後續的防止機制(例如Event 0触发的时候,会更改state,使得event 2无法被触发)也無法補救。

0 Kudos
7,726 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

根据你给出的测试和代码,现象的最终原因是4个SCT需要依次进入各自的中断函数去关停SCT 计数器,因依次进入会有时间延迟,使得最后进入中断函数的SCT在进入中断时,其本身已经开始了新一轮的脉冲输出。
在我建议的机制中,如果还是以依次进入中断的方式去修改对应的event 2控制寄存器可能还是会有问题,比如进入中断的延迟时间大于一个PWM周期时,所以我建议修改对应event 2控制寄存器的操作可以安排在优先级最高的SCT 中断函数一起来执行。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,723 Views
yansinli
Contributor III

"所以我建议修改对应event 2控制寄存器的操作可以安排在优先级最高的SCT 中断函数一起来执行。"

試過還是不行!!!

----------------------------------------------------------------------------------------------------------------------------

四組200K 同時送出100個脈波,精準不能錯誤。看來這顆MCU是沒辦法辦到。

----------------------------------------------------------------------------------------------------------------------------

兩組200K 同時送出100個脈波,精準不能錯誤。是否還有機會?

有個想法?看看可不可行

第一組(SCT0+SCT2)

1.SCT0 負責輸出,SCT2負責監控

2.由SCT2計數到100個脈波時,SCT2 輸出角位 去觸發SCT0 的EVENT,讓EVEVT去停止SCT。

以上都由硬體控制,沒有中斷。

第二組(SCT1+SCT3)

幫確認這想法是否可行?

0 Kudos
7,723 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

感谢回复, 这样响应会更快。

我还有个你能否发一个可以复现现象的完整,我这边也可以测试,这样解决问题效率会更高。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,723 Views
yansinli
Contributor III

方便給我你的信箱? 我mail 給你

1.中斷延遲基本上是無法避免~~因為系統不只有SCT 還有其他周邊中斷在(我的系統有CAN/ QEI/ MRT / +4組SCT)。

2. 要解決這問題,首先要提供解決方案 ,前提不透過中斷且在精準脈波數打完就能關閉SCT,不然這問題無解。

希望你們能朝不用中斷方式,計數到正確脈波數去關閉SCT,提供給我解決方案。

目前測試

2組SCT0/1 在100K同時輸出,能在脈波數到達,精準關閉。

2組SCT0/1 在200K同時輸出,會多送脈波。

我有量測我的SCT中斷 約0.52us(進去到出來時間,如下PIN24-PIN26),考慮是否我中斷時間過長。

為了測試我已經刪掉很多,只留這些才免強達到兩組150K精準不偷送。

但實際應用中斷程式會再長到1.25us。

void SCT0_IRQHandler(void)
{
 LPC_GPIO->SET[0] = (1 << 24); /* PIN24 H */  
    SctCurPulsNum[0]++;    
    CurPosi[0]++;  
    if ((SctCurPulsNum[0] >= SctGoalPulsNum[0]) && (SctGoalPulsNum[0] != 0))    /* over run */
    {
        SCT0_HALT_Enable;
        SCT0_OUTPUT_RESET;
        AxisState[0].bit.b3_CmdFinish = 1;
        AxisState[0].bit.b1_OutRunning = 0;
        CurSpeed[0] = 0;
    }    
    LPC_SCT0->EVFLAG = 0x00000010;  /* clear event 4 flag */        
    LPC_GPIO->SET[0] = (1 << 26); /* PIN26 H */
}

0 Kudos
7,723 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

感谢回复.

1. 代码中存在多个应用,可以通过提高中断优先级来保证SCT中断得到最快响应。

2. 请上传一个2組SCT0/1 在200K同時輸出的测试代码即可,直接上传到community就好,以及请介绍一下测试的步骤,以保证可复现现象。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,723 Views
yansinli
Contributor III

謝謝你的幫忙~~ 參考你的方案,我在修改一下, 我已經解決此問題~

最後解決方案是 在目標個數-1,時會產生中斷,修改m0(event0: halt SCT0)。

舉例,目標數100,在第99產生中斷時,修改下次m0(event0: halt SCT0)。

限制就是中斷延遲要確保 是在一個脈波週期內,也就是要在下次m0來前完成修改。就能精準送出100個且關閉。

7,723 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

是的,将中断延迟控制在一个PWM脉冲周期内,就来得及修改event 控制寄存器。

总之,很高兴你的问题解决了。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

7,723 Views
yansinli
Contributor III

壞消息~ 隨功能增加~我中斷延遲超過一個週期了!!! 所以這方法失效了

0 Kudos
7,723 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

只要Interrupt delay是稳定地,如果大于一个周期而小于两个周期的的话,你可以再提前一个周期,修改m0(event0: halt SCT0),这样可以保证虽然对紧接着的event0无效的,但是对紧接的第二个event0肯定是起作用的,这种方法根据Interrupt delay大小,依次类推。确定在哪个中断函数内修改m0(event0: halt SCT0)。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,723 Views
yansinli
Contributor III

目前中斷延遲大約0.5~ 2週期,不固定。

所以使用您的方式(目標數-2,設定m0為halt),只能用在固定延遲1~2週期。

當在0.5<中斷延遲 <1,會少輸出1個脈波。

0 Kudos
7,723 Views
jeremyzhou
NXP Employee
NXP Employee

Hi yansin lee,

感谢回复.

对啊,中断延迟保持在一个比较稳定的区间是前提条件,我建议你最好重新优化一下程代架构,使得中断延迟是可预期,可控的。

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
7,726 Views
StanleyH
NXP Employee
NXP Employee

Hi support team,

  Need your great support. Can you please provide a sample code that uses the SCT module(or another module suggested) to output 100 PWM pulses then stops PWM automatically ? When the PWM frequency is up to 200KHz.
Thanks.

Best regards,

Stanley

0 Kudos
7,727 Views
yansinli
Contributor III

err.JPG#IMG_20191113_172154.jpg

0 Kudos