fishyy 发表于 2015-6-17 15:17

CAN总线通讯问题

大家好,我用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通讯有两种模式吧,不知道你用的哪种。

fishyy 发表于 2015-6-23 17:15

JY-DX-JY 发表于 2015-6-23 15:18
记得28335CAN通讯有两种模式吧,不知道你用的哪种。

你是说回环和正常模式?

JY-DX-JY 发表于 2015-6-23 17:30

不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。

fishyy 发表于 2015-6-23 18:19

JY-DX-JY 发表于 2015-6-23 17:30
不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。 ...

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

JY-DX-JY 发表于 2015-6-23 18:26

ARM应该不是增强模式,我以前试过。

fishyy 发表于 2015-6-23 18:38

JY-DX-JY 发表于 2015-6-23 18:26
ARM应该不是增强模式,我以前试过。

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

JY-DX-JY 发表于 2015-6-23 18:43

好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。

fishyy 发表于 2015-6-23 19:43

JY-DX-JY 发表于 2015-6-23 18:43
好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。 ...

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

JY-DX-JY 发表于 2015-6-23 19:49

不客气。

fishyy 发表于 2015-6-23 20:52

JY-DX-JY 发表于 2015-6-23 19:49
不客气。

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

JY-DX-JY 发表于 2015-6-23 21:09

波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。

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 becleared..

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

    EDIS;
}

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;
      DATA1=RxMessage.Data;
}
      
}



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_FilterInitTypeDefCAN_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();   
}

JY-DX-JY 发表于 2015-6-24 08:48

ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。

海中水 发表于 2015-6-24 09:27

JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...

观察的很仔细。:)

fishyy 发表于 2015-6-24 09:29

JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...

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

JY-DX-JY 发表于 2015-6-24 09:53

应该不影响。你28335用的CAN的数据腿是哪两个?有没有设置?
页: [1] 2
查看完整版本: CAN总线通讯问题