我是靠谱客的博主 义气蜡烛,最近开发中收集的这篇文章主要介绍CANopen开启PDO定时发送后心跳帧时间错误,PDO迟迟不发送,CANopen时间轴错乱,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

CANopen的例子中,一种使用很多也很简单的方式是用一个1ms定时器中断,然后用全局变量重写sertimer和getElapsedTime函数,然后中断服务函数中加入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;
}

但是这种方式存在一个致命问题,这种方式计算的时间,在只有心跳帧的时候是没问题的,加入PDO定时发送,就会混乱,例如1s心跳帧300msPDO定时,出现的现象是1s心跳帧保留,在1s心跳帧之后300ms会多出一个心跳帧,而PDO定时发送迟迟不出现!!!!!!,这种情况下应改为last_time_set = TimeCNT;放在timerForCan之前!!!!


```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;罪魁祸首
        return ret;
}
另外还要开一个1毫秒的定时器,每1毫秒调用一下下面这个函数。
void timerForCan(void)
{
        TimeCNT++;
        if (TimeCNT>=TIMER_MAX_COUNT)
        {
                TimeCNT=0;
        }
        if (TimeCNT==NextTime)
        {
                TimeDispatch();
        }
}
//1ms中断服务函数
void TIM7_IRQHandler(void)
{
	if(TIM7->SR&0X0001)//中断
	{
		
	}
	TIM7->SR&=~(1<<0);//清除中断标志位	
	last_time_set = TimeCNT;
	timerForCan();
}

最后

以上就是义气蜡烛为你收集整理的CANopen开启PDO定时发送后心跳帧时间错误,PDO迟迟不发送,CANopen时间轴错乱的全部内容,希望文章能够帮你解决CANopen开启PDO定时发送后心跳帧时间错误,PDO迟迟不发送,CANopen时间轴错乱所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部