当前位置:网站首页>After CANopen starts PDO timing transmission, the heartbeat frame time is wrong, PDO is delayed, and CANopen time axis is disordered

After CANopen starts PDO timing transmission, the heartbeat frame time is wrong, PDO is delayed, and CANopen time axis is disordered

2022-04-23 18:22:00 Things will turn when they reach the extreme 1024

CANopen In the case of , A simple way to use a lot is to use a 1ms Timer interrupt , Then rewrite... With global variables sertimer and getElapsedTime function , Then add... To the interrupt service function timerForCan

//Set the next alarm //
void setTimer(TIMEVAL value)
{
    
        NextTime=(TimeCNT+value)%TIMER_MAX_COUNT;
}

// Get the elapsed time since the last occured alarm //
TIMEVAL getElapsedTime(void)
{
    
        int ret=0;
        ret = TimeCNT> last_time_set ? TimeCNT - last_time_set : TimeCNT + TIMER_MAX_COUNT - last_time_set;
        last_time_set = TimeCNT;
        return ret;
}

But there is a fatal problem with this approach , The time calculated in this way , When there are only heartbeat frames, there is no problem , Join in PDO Regularly send , Will be chaos , for example 1s Heartbeat frame 300msPDO timing , The phenomenon is 1s Heartbeat frame retention , stay 1s After heartbeat frame 300ms There will be one more heartbeat frame , and PDO Timed transmission does not appear !!!!!!, In this case, it should be changed to last_time_set = TimeCNT; Put it in timerForCan Before !!!!


```c
//Set the next alarm //
void setTimer(TIMEVAL value)
{
    
        NextTime=(TimeCNT+value)%TIMER_MAX_COUNT;
}

// Get the elapsed time since the last occured alarm //
TIMEVAL getElapsedTime(void)
{
    
        int ret=0;
        ret = TimeCNT> last_time_set ? TimeCNT - last_time_set : TimeCNT + TIMER_MAX_COUNT - last_time_set;
        //last_time_set = TimeCNT; The culprit 
        return ret;
}
 In addition, there will be a 1 Millisecond timer , Every time 1 Call the following function in milliseconds .
void timerForCan(void)
{
    
        TimeCNT++;
        if (TimeCNT>=TIMER_MAX_COUNT)
        {
    
                TimeCNT=0;
        }
        if (TimeCNT==NextTime)
        {
    
                TimeDispatch();
        }
}
//1ms Interrupt service function 
void TIM7_IRQHandler(void)
{
    
	if(TIM7->SR&0X0001)// interrupt 
	{
    
		
	}
	TIM7->SR&=~(1<<0);// Clears the interrupt flag bit  
	last_time_set = TimeCNT;
	timerForCan();
}

版权声明
本文为[Things will turn when they reach the extreme 1024]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210610057187.html