jiankewuying 发表于 2014-8-21 14:57:36

stm32 can发送邮箱被占满

最近在做CAN通讯,当连续发送超过3帧的数据时,发送邮箱被占满,导致后面数据无法发送,数据发送完之后TME位应该硬件置1才对,为什么数值没有改变,还有就是我单步调试的时候多少帧的数据都是能发送的,为什么程序烧进去之后就出错了。

papa0305 发表于 2014-8-21 15:22:41

stm32 can好用吗

syp910 发表于 2014-8-21 15:33:05

我也用STM32,没有遇到过类似问题
帧与帧之间延时测试 ,看还有这样的问题吗

Felix257 发表于 2014-8-21 16:56:58

是一对一,还是一对多?

jiankewuying 发表于 2014-8-21 20:32:57

Felix257 发表于 2014-8-21 16:56
是一对一,还是一对多?

1对1,还请大神指教

Felix257 发表于 2014-8-21 22:34:27

jiankewuying 发表于 2014-8-21 20:32
1对1,还请大神指教

有没有尝试过串口打log的方式?当程序运行到某一步的时候,通过串口发送一些标志上来,这样就确定了这一步是否执行了

您是用库开发的吗?我记得库里有个函数是读取错误代码的,可以调用这个函数把错误代码通过串口发上来,可以进一步分析。具体是哪个函数我是真想不起来了

希望能给你提供一点思路

cwei 发表于 2014-8-22 09:28:28

是中断发生?

xxqmcu 发表于 2014-8-22 09:29:24

这个问题很好解决的!

jiankewuying 发表于 2014-8-22 18:06:32

Felix257 发表于 2014-8-21 22:34
有没有尝试过串口打log的方式?当程序运行到某一步的时候,通过串口发送一些标志上来,这样就确定了这一 ...

找到原因了,连续发数据,中间要有延时,不过对于实时性要求比较高的话,那该怎么办呢

jiankewuying 发表于 2014-8-22 18:07:42

Felix257 发表于 2014-8-21 22:34
有没有尝试过串口打log的方式?当程序运行到某一步的时候,通过串口发送一些标志上来,这样就确定了这一 ...

用了,我先发送数据,然后打印邮箱号,打印的邮箱号为0、1、2、4,4就是没有邮箱可用了

jiankewuying 发表于 2014-8-22 18:08:34

syp910 发表于 2014-8-21 15:33
我也用STM32,没有遇到过类似问题
帧与帧之间延时测试 ,看还有这样的问题吗
...

是延时的问题,要是不用延时那该怎么实现连续发送呢?

jiankewuying 发表于 2014-8-22 18:09:03

papa0305 发表于 2014-8-21 15:22
stm32 can好用吗

还可以,借助库函数很简单的

Felix257 发表于 2014-8-22 19:56:21

jiankewuying 发表于 2014-8-22 18:06
找到原因了,连续发数据,中间要有延时,不过对于实时性要求比较高的话,那该怎么办呢 ...

恭喜你啊
我之前的应用可能实时性不太高,主要是通信量不大,一个包肯定够……有耐心的话,多试几次吧,看中间延时多久比较合适。 Good luck!               

maimaige 发表于 2014-8-22 20:28:23

有标志,显示是否发送成功了不

liujie14565 发表于 2014-8-23 09:36:26

syp910 发表于 2014-8-23 10:17:27

通过判断发送完成标志位,再发送下一帧

craigtao 发表于 2014-8-23 17:31:19

你的实时性要求多高?几秒发送一次?毫秒级?你可以在库函数的基础上封装一个发送函数,
发送的时候先检测邮箱是否有可用的,如果没有只能先不发,或者往缓冲队列里存放,这样是否好点呢?如果你的实时已经超出can能承受的范围了,
是不是该考虑设计问题了,? 我也是菜鸟啊,相互交流想法,学习,

zjtzlqr 发表于 2014-8-23 23:02:08

采用中断方式发送既可

jiankewuying 发表于 2014-8-25 21:01:36

Felix257 发表于 2014-8-22 19:56
恭喜你啊
我之前的应用可能实时性不太高,主要是通信量不大,一个包肯定够……有耐心的话,多试几次吧, ...

这个我试过,可是这是两机通讯,要是3机。4机,那延时岂不是更长了

jiankewuying 发表于 2014-8-25 21:05:10

maimaige 发表于 2014-8-22 20:28
有标志,显示是否发送成功了不

要写while等标志位很慢的,有没有快一点的

jiankewuying 发表于 2014-8-25 21:05:55

zjtzlqr 发表于 2014-8-23 23:02
采用中断方式发送既可

求大神指教,我搞了一下午用中断方式,没弄出来

jiankewuying 发表于 2014-8-25 21:06:39

craigtao 发表于 2014-8-23 17:31
你的实时性要求多高?几秒发送一次?毫秒级?你可以在库函数的基础上封装一个发送函数,
发送的时候先检测 ...

做工业控制的,数据缓存怎么用,求指教

jiankewuying 发表于 2014-8-25 21:29:04

xxqmcu 发表于 2014-8-22 09:29
这个问题很好解决的!

求指教,本人新手

maimaige 发表于 2014-8-25 22:03:40

jiankewuying 发表于 2014-8-25 21:05
要写while等标志位很慢的,有没有快一点的

发送前查询一下,邮箱是否有空位,如果有空位就放入,如果没有就返回,

jiankewuying 发表于 2014-8-25 22:12:07

maimaige 发表于 2014-8-25 22:03
发送前查询一下,邮箱是否有空位,如果有空位就放入,如果没有就返回, ...

返回,然后呢,最后数据不还是要发送出去吗?

maimaige 发表于 2014-8-25 22:38:56

#define MESSAGE_ARRAY_NUM100
uint8_t CanMessage_Array;
uint16_t InsertMessageIndex =0;
uint16_t GetMessageIndex =0;
uint16_t MessageCnt =0;

void SendToCanHWTask(void)
{
    uint8_t sendmsg ;
    if(邮箱有空位){
       if(0 < MessageCnt){
                 sendmsg = CanMessage_Array;
                 GetMessageIndex++;
            GetMessageIndex=GetMessageIndex%MESSAGE_ARRAY_NUM ;

            MessageCnt-- ;
            将sendmsg放入邮箱寄存器;
       }
    }
}

/*不要在中断中调用这个函数*/
/*msg是要发送的数据*/
void sendCanMsg(uint8_t msg)
{
    CanMessage_Array = msg ;
    InsertMessageIndex ++ ;
    InsertMessageIndex = InsertMessageIndex%MESSAGE_ARRAY_NUM ;
   
    MessageCnt++ ;
    if(MESSAGE_ARRAY_NUM == MessageCnt){
        //error,增大数组
   }
   
}

int main()
{
....
...
while(1){
   ...
   ...
   ...
   SendToCanHWTask();
}
}

craigtao 发表于 2014-8-26 08:14:42

jiankewuying 发表于 2014-8-25 21:06
做工业控制的,数据缓存怎么用,求指教

使用一个环形队列,就OK了,

jiankewuying 发表于 2014-8-27 22:09:51

craigtao 发表于 2014-8-26 08:14
使用一个环形队列,就OK了,

怎么使用,还请大神帮助

craigtao 发表于 2014-8-28 08:25:40

jiankewuying 发表于 2014-8-27 22:09
怎么使用,还请大神帮助

就是在can的接收中断服务函数中,把接收到的数据放到环形队列中,在main函数中取出来处理,
不难的,

mikal 发表于 2014-8-28 13:56:58

用发送中断肯定没有问题!
前个月,花了1天时间,做了个can通讯升级的,这个可是已以帧(256bytes)为单位发送的,而且还接收,交互处理。
溜的很!所以肯定是你的处理方法要改下。

jiankewuying 发表于 2014-8-28 17:38:26

mikal 发表于 2014-8-28 13:56
用发送中断肯定没有问题!
前个月,花了1天时间,做了个can通讯升级的,这个可是已以帧(256bytes)为单位 ...

我使用中断的方式发送,但是遇到一个问题,can是发送成功之后才进入中断,当我要连续想两个地址发送两组数据的时候,第一个发送请求完成后等待进入中断,发送第一个数组的其他字节,可是这个时候如果要向第二个地址发送数据,第一个发送的数据还没有进入中段,第二个地址的数据就会覆盖第一个数据

jiankewuying 发表于 2014-8-28 17:39:38

craigtao 发表于 2014-8-28 08:25
就是在can的接收中断服务函数中,把接收到的数据放到环形队列中,在main函数中取出来处理,
不难的, ...

本人小白,对环形队列不是很熟悉,还请指教,有程序可以分享一下吗?谢谢

craigtao 发表于 2014-8-28 22:52:13

jiankewuying 发表于 2014-8-28 17:39
本人小白,对环形队列不是很熟悉,还请指教,有程序可以分享一下吗?谢谢 ...

你可以百度一下嘛,环形队列的实现,

dso_2012 发表于 2014-8-29 09:10:58

用中断方式即可,在中断中查询队列里面是否有待发数据

qs6361036 发表于 2015-4-3 16:07:26

也遇到这样的问题 ,发送数据丢帧 !

wfy 发表于 2015-10-9 23:56:41

确实连续发送4帧,最后一帧丢失。

yu2008 发表于 2015-10-10 07:43:26

发送完成中断+环形队列(论坛里分享了一大把)

月光疾風 发表于 2015-11-5 23:57:45

之前也碰到类似问题,超过3帧,后面的就没有了,后来帧与帧之间加延时的

quder 发表于 2020-12-12 00:11:49

jiankewuying 发表于 2014-8-22 18:06
找到原因了,连续发数据,中间要有延时,不过对于实时性要求比较高的话,那该怎么办呢 ...

要用多久的时延啊?我用的HAL_Delay(100);还是不行

eddia2012 发表于 2022-3-3 19:58:39

打卡,标记下.
页: [1]
查看完整版本: stm32 can发送邮箱被占满