搜索
bottom↓
回复: 3

C8051F045的CAN程序出问题,请大师帮忙,酬谢。

[复制链接]

出0入0汤圆

发表于 2013-5-12 20:33:35 | 显示全部楼层 |阅读模式
本帖最后由 89057445 于 2013-5-12 20:45 编辑

我想通过can接收can总线上的所以数据,固定相ID位0011108A的设备发送数据。不知道是没有正确初始化还是什么原因,不能接收到数据,请大师帮忙,加QQ酬谢:911781291。程序如下:已经核对过,波特率正确,250K,物理连接正确。


#include "C8051F040.h"
#include "can.h"
#include "uart.h"
//CAN接收缓冲区
xdata unsigned char g_ucCanRecvBuff[16];        //CAN接收数据缓冲区
unsigned char g_ucCanSendBuff[16];        //CAN发送数据缓冲区
xdata unsigned char g_ucCanSendId[4];        //存对应发送CAN_ID
char status;
extern unsigned char canflag;

void clear_msg_objects (void)
{
        unsigned char i;
        SFRPAGE  = CAN0_PAGE;
        CAN0ADR  = IF1CMDMSK;    // Point to Command Mask Register 1
        CAN0DATL = 0xFF;         // Set direction to WRITE all IF registers to Msg Obj
        for(i=1;i<33;i++)
        {
                CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
                CAN0DATL = i;
        }
        }

//Initialize Message Object for RX
void init_msg_object_RX (char MsgNum)
{
        SFRPAGE  = CAN0_PAGE;
        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
        CAN0DAT  = 0x00B8;     // Set to WRITE, and alter all Msg Obj except ID MASK
                             // and data bits
        CAN0ADR  = IF1MSK1;  // Point to IF1 Mask1 register
        CAN0DAT  = 0x0000;
        CAN0DAT  = 0xE000;

        CAN0ADR  = IF1ARB1;    // Point to arbitration1 register
        CAN0DAT  = 0x0001;     // Set arbitration1 ID to "1"
        CAN0DAT  = 0xC000;     // Arb2 high byte:Set MsgVal bit, no extended ID,                 扩展ID
                             // Dir = RECEIVE
        CAN0DAT  = 0x0488;     // Msg Cntrl: set RXIE, remote frame function disabled
        CAN0ADR  = IF1CMDRQST; // Point to Command Request reg.
        CAN0DATL = MsgNum;     // Select Msg Obj passed into function parameter list
                             // --initiates write to Msg Obj
        // 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
}

//Initialize Message Object for TX
void init_msg_object_TX (char MsgNum)
{
  SFRPAGE = CAN0_PAGE;
  CAN0ADR = IF1CMDMSK;  // Point to Command Mask 1
  CAN0DAT = 0x00B2;     // Set to WRITE, & alter all Msg Obj except ID MASK bits
  CAN0ADR = IF1ARB1;    // Point to arbitration1 register
  CAN0DAT = 0x108A;     // Set arbitration1 ID to highest priority
  CAN0DAT = 0xE011;     // Autoincrement to Arb2 high byte:                    0xA002;                扩展ID
                        // Set MsgVal bit, no extended ID, Dir = WRITE
  CAN0DAT = 0x0088;     // Msg Cntrl: DLC = 1, remote frame function not enabled
  CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
  CAN0DAT = MsgNum;     // Select Msg Obj passed into function parameter list
                        // --initiates write to Msg Obj
  // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}
/***********************************************
** 函数名        :OpenCanInt
** 函数说明        :打开CAN中断
** 输入                :无
** 输出                :无
** 其它                :无
************************************************/
void OpenCanInt(void)                 //打开CAN中断
{
        EIE2 |= 0x20;                      //CPU开can中断
}

/***********************************************
** 函数名        :CloseCanInt
** 函数说明        :关闭CAN中断
** 输入                :无
** 输出                :无
** 其它                :无
************************************************/
void CloseCanInt(void)               //关闭CAN中断  
{
        EIE2 &= ~0x20;                    //CPU关can中断
}
/***********************************************
** 函数名        :Can_Init
** 函数说明        :初始化CAN
** 输入                :baudRate,CAN波特率
** 输出                :无
** 其它                :无
************************************************/
void Can_Init(unsigned int baudRate)
{

        SFRPAGE  = CAN0_PAGE;
        CAN0CN   = 0x41;       // Configuration Change Enable CCE and INIT
        CAN0ADR  = BITREG;     // Point to Bit Timing register
        CAN0DATH         = HIGH_WORD(baudRate);         //设置CAN波特率            
        CAN0DATL         = LOW_WORD(baudRate);        //设置CAN波特率  
        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
        CAN0DAT  = 0x0087;     // Config for TX : WRITE to CAN RAM, write data bytes,
                             // set TXrqst/NewDat, clr IntPnd
       
        // RX-IF2 operation may interrupt TX-IF1 operation
        CAN0ADR  = IF2CMDMSK;  // Point to Command Mask 2
        CAN0DATL = 0x1F;       // Config for RX : READ CAN RAM, read data bytes,
                             // clr NewDat and IntPnd
        CAN0CN  |= 0x06;       // Global Int. Enable IE and SIE
        CAN0CN  &= ~0x41;      // Clear CCE and INIT bits, starts CAN state machine
        EIE2                 |=0x20;                                 //开启CAN中断
}
void start_CAN (void)
{
        // Clear CAN RAM
        clear_msg_objects();
       
        // Initialize message object to transmit data
        init_msg_object_TX (0x02);
       
        // Initialize message object to receive data
        init_msg_object_RX (0x01);
       
        // Enable CAN interrupts in CIP-51
        EIE2 = 0x20;
       
        //Function call to start CAN
        Can_Init(CAN_RATE);
       
        //Global enable 8051 interrupts
        EA = 1;
}
void SendCanData (unsigned char MsgNum,unsigned char *sendcmdtocan)
{
        SFRPAGE  = CAN0_PAGE;  // IF1 already set up for TX
       
        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
        CAN0DAT  = 0x0087;     // Config to WRITE to CAN RAM, write data bytes,
                             // set TXrqst/NewDat, Clr IntPnd
        CAN0ADR  = IF1DATA1;   // Point to 1st byte of Data Field
        CAN0DATH = *(sendcmdtocan+1);
        CAN0DATL = *(sendcmdtocan);       // Ones signals to turn LED's light ON in data A1 field
        CAN0DATH = *(sendcmdtocan+3);
        CAN0DATL = *(sendcmdtocan+2);
        CAN0DATH = *(sendcmdtocan+5);
        CAN0DATL = *(sendcmdtocan+4);
        CAN0DATH = *(sendcmdtocan+7);
        CAN0DATL = *(sendcmdtocan+6);   
        CAN0ADR  = IF1CMDRQST; // Point to Command Request Reg.
        CAN0DATL = MsgNum;     // Move new data for TX to Msg Obj "MsgNum"
       
}

void receive_data (unsigned char MsgNum,unsigned char i)
{
       
        SFRPAGE  = CAN0_PAGE; // IF1 already set up for RX
        CloseCanInt();
        CAN0ADR  = IF2CMDRQST;// Point to Command Request Reg.
        CAN0DATL = MsgNum;    // Move new data for RX from Msg Obj "MsgNum"
                            // Move new data to a
        CAN0ADR  = IF2DATA1;  // Point to 1st byte of Data Field
       
        g_ucCanRecvBuff[i+1] = CAN0DATH;
        g_ucCanRecvBuff = CAN0DATL;
        g_ucCanRecvBuff[i+3] = CAN0DATH;
        g_ucCanRecvBuff[i+2] = CAN0DATL;
        g_ucCanRecvBuff[i+5] = CAN0DATH;
        g_ucCanRecvBuff[i+4] = CAN0DATL;
        g_ucCanRecvBuff[i+7] = CAN0DATH;
        g_ucCanRecvBuff[i+6] = CAN0DATL;
        OpenCanInt();
        canflag=1;
}
void ISRname (void) interrupt 19
{
        unsigned char temp;
        temp=SFRPAGE;
        SFRPAGE=CAN0_PAGE;
        status = CAN0STA;
        if ((status&0x10) != 0)
        {                            // RxOk is set, interrupt caused by reception
          CAN0STA = (CAN0STA&0xEF)|0x07;         // Reset RxOk, set LEC to NoChange
          /* read message number from CAN INTREG */
          receive_data (0x01,0);             // Up to now, we have only one RX message         注意,目前只接收八个数据
        }
        if ((status&0x08) != 0)
        {                            // TxOk is set, interrupt caused by transmision
          CAN0STA = (CAN0STA&0xF7)|0x07;        // Reset TxOk, set LEC to NoChange
        }
        if (((status&0x07) != 0)&&((status&0x07) != 7))
        {                           // Error interrupt, LEC changed
          /* error handling ? */
          CAN0STA = CAN0STA|0x07;              // Set LEC to NoChange
        }
        SFRPAGE=temp;
}
/***********************************************
** 函数名        :ComToCan
** 函数说明        :复制上位机命令,发送到角度传感器
** 输入                :n:发送数据的个数
** 输出                :无
** 其它                :无
************************************************/
void CopyComToCan(unsigned char n,unsigned char *comcmd)
{
        unsigned char i,j,k;
        for(i=0;i<4;i++)
        {
                g_ucCanSendId=*(comcmd+i);
                send_char_com(g_ucCanSendId);
        }

        if(n<=8)                                //如果n小于等于8,可以一次发送完
        {
                j=n;
                k=0;
        }
        else                                         //如果n大于8,要分多次发送
        {
                j=8;
                k=n-8;
        }

        delay(50);
        for(i=0;i<j;i++)                //数据拷备
        g_ucCanSendBuff=*(comcmd+(i+4));
//        k=g_ucCanSendBuff[0];
//        send_char_com(j);
//        send_char_com(k);
        SendCanData (0x02,g_ucCanSendBuff);                                           //第一次发送数据
        delay(500);
        for(i=0;i<16;i++)
        {
                g_ucCanSendBuff=0;   //清除CAN发送缓冲区       
        }
       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2013-5-12 20:39:24 | 显示全部楼层
C7081F045的CAN程序

神马奇怪的型号???C8051F045吧???

出0入0汤圆

 楼主| 发表于 2013-5-12 20:46:04 | 显示全部楼层
jetli 发表于 2013-5-12 20:39
C7081F045的CAN程序

神马奇怪的型号???C8051F045吧???

是的,C8051F045

出0入0汤圆

发表于 2013-7-10 21:34:08 | 显示全部楼层
帮顶,lz还没搞定?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 09:09

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表