打印

CAN总线通讯问题

[复制链接]
3391|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fishyy|  楼主 | 2015-6-17 15:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,我用28335做发送器,stm32做接收器,但试验中,28335寄存器CANTA一直不置位,观察原因发现CANES.SMA位置1,CAN模块被激活挂起模式,控制器被冻结,我自己思考的原因是总线没有识别还有一个接收节点,所以将发送节点挂起,但问题是我之前用两块stm32做通讯的时候是成功的。为什么换了发送器后就变成这样了呢,我该怎么解决呢?求有经验的大神进来交流探讨一下。

相关帖子

沙发
airwill| | 2015-6-22 15:13 | 只看该作者
"总线没有识别还有一个接收节点,所以将发送节点挂起"

不应该是这样的, 总线不需要识别接收节点, 接收节点在正确收到数据后会自动给出应答. 主机也就知道了有节点收到了数据了. 所以你的问题很可能是从机没有正确收到数据包, 这种情况最可能出现的原因是波特率不一致.

使用特权

评论回复
板凳
fishyy|  楼主 | 2015-6-23 15:11 | 只看该作者
airwill 发表于 2015-6-22 15:13
"总线没有识别还有一个接收节点,所以将发送节点挂起"

不应该是这样的, 总线不需要识别接收节点, 接收节点 ...

谢谢你的回应,我的波特率应该是没问题,我想问一下,用示波器能看出波特率吗?

使用特权

评论回复
地板
JY-DX-JY| | 2015-6-23 15:18 | 只看该作者
记得28335CAN通讯有两种模式吧,不知道你用的哪种。

使用特权

评论回复
5
fishyy|  楼主 | 2015-6-23 17:15 | 只看该作者
JY-DX-JY 发表于 2015-6-23 15:18
记得28335CAN通讯有两种模式吧,不知道你用的哪种。

你是说回环和正常模式?

使用特权

评论回复
6
JY-DX-JY| | 2015-6-23 17:30 | 只看该作者
不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。

使用特权

评论回复
7
fishyy|  楼主 | 2015-6-23 18:19 | 只看该作者
JY-DX-JY 发表于 2015-6-23 17:30
不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。 ...

你的意思是有16个和31个邮箱之分的?为什么不能用增强的,是ARM不接受吗

使用特权

评论回复
8
JY-DX-JY| | 2015-6-23 18:26 | 只看该作者
ARM应该不是增强模式,我以前试过。

使用特权

评论回复
9
fishyy|  楼主 | 2015-6-23 18:38 | 只看该作者
JY-DX-JY 发表于 2015-6-23 18:26
ARM应该不是增强模式,我以前试过。

那CANMC.SCB赋值为0是不是就可以了呢?选择普通模式?

使用特权

评论回复
10
JY-DX-JY| | 2015-6-23 18:43 | 只看该作者
好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。

使用特权

评论回复
11
fishyy|  楼主 | 2015-6-23 19:43 | 只看该作者
JY-DX-JY 发表于 2015-6-23 18:43
好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。 ...

先谢谢了,我试试,不懂再请教你

使用特权

评论回复
12
JY-DX-JY| | 2015-6-23 19:49 | 只看该作者
不客气。

使用特权

评论回复
13
fishyy|  楼主 | 2015-6-23 20:52 | 只看该作者

我试了一下,和之前情况一样,是不是还需要设置什么?

使用特权

评论回复
14
JY-DX-JY| | 2015-6-23 21:09 | 只看该作者
波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。

使用特权

评论回复
15
fishyy|  楼主 | 2015-6-23 21:50 | 只看该作者
JY-DX-JY 发表于 2015-6-23 21:09
波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。 ...

这是DSP发送部分
void main()
{
struct ECAN_REGS ECanaShadow;

InitSysCtrl();

InitECanaGpio();

DINT;

InitPieCtrl();

IER=0x0000;

IFR=0x0000;

InitPieVectTable();

InitECana();

ECanaMboxes.MBOX6.MSGID.all = 0x81231314;

ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
   
ECanaShadow.CANMD.bit.MD6 = 0;
   
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

ECanaShadow.CANME.all = ECanaRegs.CANME.all;
   
ECanaShadow.CANME.bit.ME6 = 1;
   
ECanaRegs.CANME.all = ECanaShadow.CANME.all;

ECanaMboxes.MBOX6.MSGCTRL.bit.DLC = 2;

ECanaMboxes.MBOX6.MSGCTRL.bit.RTR = 0;

ECanaMboxes.MBOX6.MSGCTRL.bit.TPL = 0;
  
while(1)
{

ECanaMboxes.MBOX6.MDL.all = 0x12;
   
ECanaMboxes.MBOX6.MDH.all = 0x87;

ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;

ECanaShadow.CANTRS.all = 0;
      
ECanaShadow.CANTRS.bit.TRS6 = 1;        
      
  ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
do
{
      ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;

    } while(ECanaShadow.CANTA.bit.TA6 == 0 );  

ECanaShadow.CANTA.all = 0;
      
ECanaShadow.CANTA.bit.TA6 = 1;                     
      
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;



can设置部分

void InitECana(void)                // Initialize eCAN-A module
{
struct ECAN_REGS ECanaShadow;

        EALLOW;                // EALLOW enables access to protected bits

/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.all = 8;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.all = 8;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

/* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
                                                                        // HECC mode also enables time-stamping feature

        ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.ABO = 1;
        ECanaShadow.CANMC.bit.SCB = 0;
        ECanaShadow.CANMC.bit.STM = 0;
        ECanaShadow.CANMC.bit.CDR = 1;
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//        as a matter of precaution.
   
    ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
        ECanaShadow.CANTA.all = 0xFFFFFFFF;        /* Clear all TAn bits */
        ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;


    ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
        ECanaRegs.CANRMP.all = 0xFFFFFFFF;        /* Clear all RMPn bits */
        ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;

        ECanaRegs.CANGIF0.all = 0xFFFFFFFF;        /* Clear all interrupt flag bits */
        ECanaRegs.CANGIF1.all = 0xFFFFFFFF;


/* Configure bit timing parameters for eCANA*/
        ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

   // ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
        {
            ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );                  // Wait for CCE bit to be set..

    ECanaShadow.CANBTC.all = 0;

    //#if (CPU_FRQ_150MHZ)                       // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
                /* The following block for all 150 MHz SYSCLKOUT (75 MHz CAN clock) - default. Bit rate = 1 Mbps
                   See Note at End of File */
                ECanaShadow.CANBTC.bit.BRPREG = 9;
                ECanaShadow.CANBTC.bit.TSEG2REG = 2;
                ECanaShadow.CANBTC.bit.TSEG1REG = 10;
                //        ECanaShadow.CANBTC.bit.BRPREG =14 ;
                //        ECanaShadow.CANBTC.bit.TSEG2REG = 5;
                //        ECanaShadow.CANBTC.bit.TSEG1REG = 12;
  //  #endif
//        #if (CPU_FRQ_100MHZ)                       // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
        /* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps
           See Note at End of File */
           // ECanaShadow.CANBTC.bit.BRPREG = 4;
        //        ECanaShadow.CANBTC.bit.TSEG2REG = 1;
        //        ECanaShadow.CANBTC.bit.TSEG1REG = 6;
//        #endif


     ECanaShadow.CANBTC.bit.SAM = 1;
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

  //  ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
       ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );                 // Wait for CCE bit to be  cleared..

/* Disable all Mailboxes  */
        ECanaRegs.CANME.all = 0;                // Required before writing the MSGIDs

    EDIS;
}

使用特权

评论回复
16
fishyy|  楼主 | 2015-6-23 21:53 | 只看该作者
本帖最后由 fishyy 于 2015-6-23 21:54 编辑
JY-DX-JY 发表于 2015-6-23 21:09
波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。 ...

这是ARM接受部分
__IO uint32_t flag = 0xff;        
CanTxMsg TxMessage;                            //发送缓冲区
CanRxMsg RxMessage;                         //接收缓冲区
/*
* 函数名:main
* 描述  : “从机”的主函数
* 输入  :无
* 输出  : 无
*/
int main(void)
{
/*初始化配置CAN*/
CAN_Config();        
/*等待数据,接收数据*/
while(1)
{
         while( flag == 0xff );
        IDEx=RxMessage.ExtId;
        IDSt=RxMessage.StdId;
        DATA0=RxMessage.Data[0];
        DATA1=RxMessage.Data[1];
}
        
}



can设置部分
extern   CanTxMsg TxMessage;
/*
* 函数名:CAN_GPIO_Config
* 描述  :CAN的GPIO 配置,PB8上拉输入,PB9推挽输出
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_GPIO_Config(void)
{
        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;//三个成员,引脚号,引脚模式,引脚速度
                /*外设时钟设置*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);//打开AFIO,开启复用时钟,用于引脚重映射
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//打开CAN的时钟
          /*IO设置*/
        GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);//将CAN功能映射到引脚
          /*接收引脚设置*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选择8号引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入,作为接收引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//引脚最大输入速度为50M
        GPIO_Init(GPIOB, &GPIO_InitStructure);//调用库函数,初始化GPIOB
         /*发送引脚设置*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;// 复用推挽输出,作为发送引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
        GPIO_Init(GPIOB, &GPIO_InitStructure);        
}
/*
* 函数名:CAN_NVIC_Config
* 描述  :CAN的NVIC 配置,第1优先级组,0,0优先级
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //选择2*8优先级模式
        /*中断设置*/
        NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;//CAN1 RX0中断占用优先级通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0(最高)
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级为0(最高)
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//在成员NVIC_IRQChannel中定义的IRQ通道被使能
  NVIC_Init(&NVIC_InitStructure);//初始化
}
/*
* 函数名:CAN_Mode_Config
* 描述  :CAN的模式 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_Mode_Config(void)
{
        CAN_InitTypeDef CAN_InitStructure;
        /*CAN寄存器初始化*/
        CAN_DeInit(CAN1);//设置成缺省值
        CAN_StructInit(&CAN_InitStructure);//初始化
        /*CAN单元初始化*/
        CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM  时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE;                           //MCR-ABOM  自动离线管理
  CAN_InitStructure.CAN_AWUM=DISABLE;                           //MCR-AWUM  自动唤醒模式
  CAN_InitStructure.CAN_NART=DISABLE;                           //MCR-NART  禁止报文自动重传          DISABLE-自动重传
  CAN_InitStructure.CAN_RFLM=DISABLE;                           //MCR-RFLM  接收FIFO 锁定模式  DISABLE-溢出时新报文会覆盖原有报文  
  CAN_InitStructure.CAN_TXFP=DISABLE;                           //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //正常发送模式
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                   //BTR-SJW 重新同步跳跃宽度 2个时间单元
  CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;                   //BTR-TS1 时间段1 占用了6个时间单元
  CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;                   //BTR-TS1 时间段2 占用了3个时间单元
  CAN_InitStructure.CAN_Prescaler =8;                   //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+5+3)/8=0.5Mbps
//         CAN_InitStructure.CAN_BS1=CAN_BS1_7tq;                   //BTR-TS1 时间段1 占用了6个时间单元
//   CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;                   //BTR-TS1 时间段2 占用了3个时间单元
//   CAN_InitStructure.CAN_Prescaler =12;                 //36/12/(7+4+1)=0.25M
        CAN_Init(CAN1, &CAN_InitStructure);//初始化
}
/*
* 函数名:CAN_Filter_Config
* 描述  :CAN的过滤器 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_Filter_Config(void)
{
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;
        /*CAN过滤器初始化*/
        CAN_FilterInitStructure.CAN_FilterNumber=0;                                                //过滤器组0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;        //工作在标识符屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;        //过滤器位宽为单个32位。
        /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */
        CAN_FilterInitStructure.CAN_FilterIdHigh= 0x0000;    //要过滤的ID高位
  CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000;     //要过滤的ID低位
// CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)0x1314<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  //6CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  //CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFFFF;                        //过滤器高16位每位必须匹配
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000;   //ID全部接受
  //CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFFF;                        //过滤器低16位每位必须匹配
        CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;                                //过滤器被关联到FIFO0
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                        //使能过滤器
        CAN_FilterInit(&CAN_FilterInitStructure);//初始化
        /*CAN通信中断使能*/
        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
/*
* 函数名:CAN_Config
* 描述  :完整配置CAN的功能
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*/
void CAN_Config(void)
{
  CAN_GPIO_Config();
  CAN_NVIC_Config();
  CAN_Mode_Config();
  CAN_Filter_Config();   
}

使用特权

评论回复
17
JY-DX-JY| | 2015-6-24 08:48 | 只看该作者
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。

使用特权

评论回复
18
海中水| | 2015-6-24 09:27 | 只看该作者
JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...

观察的很仔细。:)

使用特权

评论回复
19
fishyy|  楼主 | 2015-6-24 09:29 | 只看该作者
JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...

这个就是标识符,在ARM里,我设置的是无论什么ID都不过滤,所以应该没有影响吧?

使用特权

评论回复
20
JY-DX-JY| | 2015-6-24 09:53 | 只看该作者
应该不影响。你28335用的CAN的数据腿是哪两个?有没有设置?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

35

帖子

1

粉丝