打印
[STM32F1]

关于CAN的问题

[复制链接]
1404|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
JasonWon|  楼主 | 2014-11-25 15:44 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
你好,关于CAN的问题想请教你下,stm32始终无法与C8051f040通信,但同类型的就可以,调试发现stm32的CAN电压平均值在1V左右,而040的在-1v左右,问题究竟在哪,不甚感激
沙发
mmuuss586| | 2014-11-25 18:29 | 只看该作者
是不是2个的CAN标准不一样;
2块板子并共地看看;

使用特权

评论回复
板凳
JasonWon|  楼主 | 2014-11-25 19:24 | 只看该作者
mmuuss586 发表于 2014-11-25 18:29
是不是2个的CAN标准不一样;
2块板子并共地看看;

共地试了下,还是不行!我把两个CAN接口的电路图弄上,麻烦看看是不是电路有问题
040CAN接口:

图中CAN收发器用的是VP230
stm32CAN 接口:


file:///C:\Documents and Settings\Administrator\Application Data\Tencent\Users\359235484\QQ\WinTemp\RichOle\3}$6LN5~M45U$49H29US0T4.jpg

使用特权

评论回复
地板
mmuuss586| | 2014-11-25 19:42 | 只看该作者
本帖最后由 mmuuss586 于 2014-11-25 19:47 编辑

120欧电阻,2个板子都接了吗?
你如果2个同样的MCU间可以通讯,硬件问题不大;

还是想办法改软件吧;

使用特权

评论回复
5
JasonWon|  楼主 | 2014-11-25 20:00 | 只看该作者
mmuuss586 发表于 2014-11-25 19:42
120欧电阻,2个板子都接了吗?
你如果2个同样的MCU间可以通讯,硬件问题不大;

接了的!但两者作为发送,都有波形输出,波特率一样,电压平均值一个是正的,一个是负的,无法实现通信!麻烦你在简单看看两者的程序,我觉得应该没问题
stm32:
static void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
        GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
       
        /* Configure CAN pin: RX */                                                                          // PB8
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                     // ÉÏÀ­ÊäÈë
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        /* Configure CAN pin: TX */                                                                         // PB9
    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);
}


static void CAN_NVIC_Config(void)
{
           NVIC_InitTypeDef NVIC_InitStructure;
        /* Configure one bit for preemption priority */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
        /*ÖжÏÉèÖÃ*/
        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_Init(&NVIC_InitStructure);
}


static void CAN_Mode_Config(void)
{
           CAN_InitTypeDef        CAN_InitStructure;
                 /************************CANͨÐŲÎÊýÉèÖÃ**********************************/
        /*CAN¼Ä´æÆ÷³õʼ»¯*/
        CAN_DeInit(CAN1);
        CAN_StructInit(&CAN_InitStructure);
       
        /*CANµ¥Ôª³õʼ»¯*/
        CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM  ¹Ø±Õʱ¼ä´¥·¢Í¨ÐÅģʽʹÄÜ
    CAN_InitStructure.CAN_ABOM=DISABLE;//ENABLE;                           //MCR-ABOM  ×Ô¶¯ÀëÏß¹ÜÀí
    CAN_InitStructure.CAN_AWUM=DISABLE;//ENABLE;                           //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_2tq;                   //BTR-SJW ÖØÐÂͬ²½ÌøÔ¾¿í¶È 2¸öʱ¼äµ¥Ôª
    CAN_InitStructure.CAN_BS1=CAN_BS1_10tq;                   //BTR-TS1 ʱ¼ä¶Î1 Õ¼ÓÃÁË10¸öʱ¼äµ¥Ôª
    CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                   //BTR-TS2 ʱ¼ä¶Î2 Õ¼ÓÃÁË7¸öʱ¼äµ¥Ôª
    CAN_InitStructure.CAN_Prescaler =4;                       //BTR-BRP ²¨ÌØÂÊ·ÖƵÆ÷  ¶¨ÒåÁËʱ¼äµ¥ÔªµÄʱ¼ä³¤¶È 36/(1+10+7)/4=0.5Mbps
        CAN_Init(CAN1, &CAN_InitStructure);
}


static void CAN_Filter_Config(void)
{
   CAN_FilterInitTypeDef  CAN_FilterInitStructure;


       
        CAN_FilterInitStructure.CAN_FilterNumber=0;                                       
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;       
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;       
    CAN_FilterInitStructure.CAN_FilterIdHigh= 0x0000;//(((u32)0x01<<21)&0xFFFF0000)>>16;       
    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; //(((u32)0x01<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000;                       
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;                       
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;       
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                       
        CAN_FilterInit(&CAN_FilterInitStructure);

        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}


void CAN_Config(void)
{
  CAN_GPIO_Config();
  CAN_NVIC_Config();
  CAN_Mode_Config();
  CAN_Filter_Config();   
}


void CAN_SetMsg(void)
{          
  TxMessage.StdId=0x02;       
  TxMessage.ExtId=0x0000;
  TxMessage.IDE=CAN_ID_STD;
  //TxMessage.ExtId=0x1314;                                       
  //TxMessage.IDE=CAN_ID_EXT;                               
  TxMessage.RTR=CAN_RTR_DATA;                               
  TxMessage.DLC=1;                                                       
  TxMessage.Data[0]=0x01;


}

040:
void init_msg_object_TX (char MsgNum,uchar id)
{
        uint temp;
        char SFRPAGE_SAVE=SFRPAGE;
          SFRPAGE = CAN0_PAGE;
        CAN0ADR = IF1CMDMSK; //
        CAN0DAT = 0x00b3;
        /*   IF1 Command Mask Registers  =0x00b3
        WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=0,TxRqst=0,DataA=1,DataB=1,一次发送8字节数据*/

        CAN0ADR = IF1ARB1;            
        CAN0DAT = 0x0000;  
        /*IF1 Arbitration Registers1 =0x0000,即ID15-0=0*/
        temp=id<<2;//标准id为ID28-ID18,所以要左移2位
        temp&=0x1fff;
        temp|=0xa000;
        CAN0DAT = temp; //地址自增,指向IF1 Arbitration Registers2
        /*IF1 Arbitration Registers2=101(id)00b
        MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=1,为发送*/
        CAN0DAT = 0x0088;
        /*IF1 Message Control Registers=0x0088
        NewDat=0,MsgLst=0,IntPnd=0,UMask=0,TxIE=0,RxIE=0,RmtEn=0,TxRqst=0
        EoB=1,DLC3-0=1000,即数据长度为8*/
        CAN0ADR = IF1CMDRQST;         
        CAN0DAT = MsgNum;   
        /*IF1 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/
        SFRPAGE=SFRPAGE_SAVE;
}
void init_msg_object_RX (char MsgNum,uchar id)
{
        uint temp;
        char SFRPAGE_SAVE=SFRPAGE;
        SFRPAGE = CAN0_PAGE;
        CAN0ADR = IF1CMDMSK;
        CAN0DAT = 0x00b8;        
        /*   IF2 Command Mask Registers  =0x00bb
        WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=1,TxRqst=0,DataA=1,DataB=1,一次发送8字节数据*/

        CAN0ADR = IF1ARB1;           
        CAN0DAT = 0x0000;
        /*IF2 Arbitration Registers1 =0x0000,即ID15-0=0*/            
        temp=id<<2;//标准id为ID28-ID18,所以要左移2位
        temp&=0x1fff;
        temp|=0x8000;
        CAN0DAT = temp;
        /*IF2 Arbitration Registers2=100(id)00b
        MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=0,为接收*/
        CAN0DAT = 0x0488;
        /*IF2 Message Control Registers=0x0488
        NewDat=0,MsgLst=0,IntPnd=0,UMask=0,TxIE=0,RxIE=1,接收中断使能;RmtEn=0,TxRqst=0
        EoB=1,DLC3-0=1000,即数据长度为8*/
        CAN0ADR = IF1CMDRQST;        
        CAN0DATL = MsgNum;           
          /*IF2 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/
        SFRPAGE=SFRPAGE_SAVE;
}
void clear_msg_objects (void) //将所有消息清零
{       
        uchar i;
        char SFRPAGE_SAVE=SFRPAGE;
        SFRPAGE = CAN0_PAGE;
        CAN0ADR = IF1CMDMSK;      
        CAN0DATL = 0xFF;            
        for (i=1;i<33;i++)
        {
                CAN0ADR = IF1CMDRQST;     
                CAN0DATL = i;
        }
        SFRPAGE=SFRPAGE_SAVE;

}

void start_CAN (int baud)
{
    char SFRPAGE_SAVE=SFRPAGE;
        SFRPAGE = CAN0_PAGE;       
        CAN0CN|=0x41;
        CAN0ADR=BITREG;
    CAN0DAT=baud;
        CAN0ADR  = IF2CMDMSK;              
        CAN0DATL = 0x1f;  
        CAN0CN = 0x02;               
        /*IE置1,使能CAN模块中断,Init清零,结束初始化操作,CAN控制器进入正常工作*/       
        SFRPAGE=SFRPAGE_SAVE;
}


void receive_data(uchar MsgNum,uchar *p,uchar len)
{
        int i=0;
        char SFRPAGE_PAGE=SFRPAGE;       
          SFRPAGE  = CAN0_PAGE;
        CAN0ADR  = IF2CMDMSK;              
//        CAN0DATL = 0x1f;         
        CAN0ADR  = IF2CMDRQST;      
        CAN0DATL = MsgNum;                 
        CAN0ADR  = IF2DATA1;               
        //连续接收8个字节,存入接收缓冲器中          
        for(i=0;i<len;i++)
        {
                *p++=CAN0DATH;
                i++;
                *p++=CAN0DATL;
        }

        SFRPAGE=SFRPAGE_PAGE;
}


void ISRname (void) interrupt 19
{       
    char SFRPAGE_SAVE=SFRPAGE;
        SFRPAGE = CAN0_PAGE;
        status = CAN0STA;
        if ((status&0x10) != 0)
        {
           CAN0STA=(CAN0STA&0xef)|0x07;
                   receive_data (MSGR,rdata,1);
        }
        if(((status&0x07)!=0)&&((status&0x07)!=7))
                CAN0STA|=0x07;
        SFRPAGE=temppage;
}


void main()
{

    Init(); //包括CAN初始化,IO口配置及关看门狗

        while(1)
    {
                if(rdata[0]==0x01)
                {
                        LED=0;
                }
                if(rdata[0]==0x02)
                {
                        LED=1;
                }
        }
}

使用特权

评论回复
6
mmuuss586| | 2014-11-25 20:22 | 只看该作者
JasonWon 发表于 2014-11-25 20:00
接了的!但两者作为发送,都有波形输出,波特率一样,电压平均值一个是正的,一个是负的,无法实现通信! ...

如果CAN的芯片用的一样,怎么也不会出现-1V啊;
2个CAN芯片之间通讯,输出应该是并联的吧;

正常通讯的时候,最好不要2个同时发;
最好1收,1发,采用主从的方式;

使用特权

评论回复
7
JasonWon|  楼主 | 2014-11-25 20:26 | 只看该作者
我是用STM32作为发送着,040作为接收者,采用的就是主从方式,stm32调试出现应答错误

使用特权

评论回复
8
JasonWon|  楼主 | 2014-11-26 13:37 | 只看该作者
问题仍旧没有解决啊,哪位大虾给指点指点

使用特权

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

本版积分规则

7

主题

35

帖子

0

粉丝