搜索
bottom↓
回复: 1

为什么MCP2515不能发送出数据呢?大家帮我看看啊?

[复制链接]

出0入0汤圆

发表于 2010-7-17 08:24:31 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include"reg2515.h"
#define uchar unsigned char
#define uint  unsigned int
sbit  CAN_CS=P1^4;
sbit  RESET=P1^3;
sbit  CAN_SCI=P1^2;
sbit  CAN_SCO=P1^1;
sbit  CAN_SCK=P1^0;
/*****************SPI指令**************/
//#define  c_reset 0XC0
#define  c_read  0X03
#define  c_write 0X02
#define  c_bit   0x05
#define  RXB0DM  0X66
#define  RXB1DM  0X76
/***************************************/
unsigned char  uart_data;
unsigned long int ID= 0X2AF;
unsigned char code data1[]={0x32,0X33,0X35,0X36,0X37,0x38,0x39,0x3A};
uchar code temp[4] = { 0, 0, 0, 0 };
/****************************************/

void        mcp2515_reset();
void    mcp2515_bit_modify(uchar adress, uchar mask, uchar data1);
void    mcp2515_reset(void);
void    send_byte(uchar temp);
void    mcp2515_write_register(uchar adress,uchar data1);
void    mcp2515_write_register_p(uchar adress, uchar *data1, uchar length);
unsigned char  mcp2515_read(uchar adress);
/*********************************************************/
void delay_nms(unsigned int n)
{
        unsigned int i,j;
                for(i=n;i>0;i--)
                {
                        for(j=125;j>0;j--)
                                {
                                }
                }
}
/*******************************************
void send_byte(uchar temp)
{
        ES=0;
        TI=0;
        SBUF=temp;
        while(!TI);
        TI=0;
        ES=1;
}
******************************************
void uart_int() interrupt 4
{
        if(RI==1)
        {
                RI=0;
                uart_data=SBUF;
        //        send_byte(uart_data);       
        }
        else TI=0;
}
****************************************/

void Uart_Init()
{
    TMOD=0x20;//定时/计数器工作方式寄存器
        TL1=0xfd;
        TH1=0xfd;
        REN=1;//串行口控制寄存器
        SM0=0;
        SM1=1;
    ET1=0;//定时/计数器1中断允许位
        TR1=1;//定时器1运行控制位 ,1时启动定时器
        EA=1;//全局中断允许位
}
/**********************************************/
void spi_wr(uint data1 )
{
        uint i ;

        CAN_SCK=0;
        for(i=0;i<8;i++)
        {        CAN_CS=0;
                CAN_SCI=(data1&0x80);
                delay_nms(1);
                CAN_SCK=1;
                data1=(data1<<1);
                CAN_SCK=0;
           CAN_CS=1;
        }

               
}
/*************************************************/

/*********************************************/
void mcp2515_init(void)
{       
            // MCP2515 启动前进行软件复位
        mcp2515_reset();
       
        /*只有在配置模式下,才能对以下寄存器进行修改:
          1、CNF1、CNF2和CNF3
          2、TXRTSCTRL  TXnRTS 引脚控制和状态寄存器
          3、验收过滤寄存器
          4、验收屏蔽寄存器
          5、中断使能寄存器
        */
        //使用位修改指令将MCP2515设置为配置模式
        //也就是将CANCTRL寄存器的REQOP[2:0]设置为100,并使CLKOUT = Fclk / 4
       
        mcp2515_bit_modify( CANCTRL, REQOP|CLKPRE, REQOP_CONFIG|CLKOUT_PRE_4 );

        //计算并设置MCP2515的位时间
        // 时钟频率:Fosc  = 4MHz
        // 分频控制器 CNF1.BRP[5:0] = 1
        // 最小时间份额 TQ = 2 * ( BRP + 1 ) / Fosc   = 2*(1+1)/4M = 1uS
        // 同步段 Sync Seg   = 1TQ
        // 传播段 Prop Seg   = ( PRSEG + 1 ) * TQ  = 1 TQ
        // 相位缓冲段 Phase Seg1 = ( PHSEG1 + 1 ) * TQ = 3 TQ
        // 相位缓冲段 Phase Seg2 = ( PHSEG2 + 1 ) * TQ = 2 TQ
        // 同步跳转长度设置为 CNF1.SJW[1:0] = 00, 即 1TQ
        // 总线波特率 NBR = Fbit =  1/(sync seg + Prop seg + PS1 + PS2 ) = 1/(8TQ) = 1/8uS = 125kHz

        //设置为125kbps ,TQ = 1us
        //设置分频控制器CNF1.BRP[5:0] = 1,同步跳转长度设置为 CNF1.SJW[1:0] = 00
        mcp2515_write_register( CNF1, SJW_1TQ | 0x01 );    // 125kbps
       
        // 设置传播段 Prop Seg 为000,即1TQ,相位缓冲段 Phase, Seg1的长度3TQ
        mcp2515_write_register( CNF2, BTLMODE_CNF3 | SMPL_1X | PHSEG1_3TQ | PRSEG_1TQ  );
       
        // 设置相位缓冲段 Phase Seg2为 2TQ , 禁用唤醒滤波器
        mcp2515_write_register( CNF3, PHSEG2_2TQ );
       
        // 设置MCP2515中断使能寄存器,禁用所有中断
        mcp2515_write_register( CANINTE,  0 );
        // 设置MCP2515中断使能寄存器,使能接收缓冲器中断
        //mcp2515_write_register( CANINTE, (1<<RX1IE)|(1<<RX0IE) );
       
        //设置数据接收相关寄存器       
        // 设置RXM[1:0]=11,关闭接收缓冲器0屏蔽/滤波功能,接收所有报文;禁止滚存功能
        mcp2515_write_register( RXB0CTRL, RXM_RCV_ALL );
       
        // 设置RXM[1:0]=11,关闭接收缓冲器1屏蔽/滤波功能,接收所有报文;
        mcp2515_write_register( RXB1CTRL, RXM_RCV_ALL );


       
        //设置6个验收滤波寄存器为0,
        mcp2515_write_register_p( RXF0SIDH, temp, 4 );
        mcp2515_write_register_p( RXF1SIDH, temp, 4 );
        mcp2515_write_register_p( RXF2SIDH, temp, 4 );
        mcp2515_write_register_p( RXF3SIDH, temp, 4 );
        mcp2515_write_register_p( RXF4SIDH, temp, 4 );
        mcp2515_write_register_p( RXF5SIDH, temp, 4 );
       
        //设置2个验收屏蔽寄存器为0,
        mcp2515_write_register_p( RXM0SIDH, temp, 4 );
        mcp2515_write_register_p( RXM1SIDH, temp, 4 );
       
        //配置引脚
        //设置接收相关引脚控制寄存器,配置它们禁用第二功能
        mcp2515_write_register( BFPCTRL, 0 );
       
        //调试使用,设置BFPCTRL使RX0BF,RX1BF设置为数字输出。
        //mcp2515_bit_modify( BFPCTRL, (1<<B1BFE)|(1<<B0BFE)|(1<<B1BFM)|(1<<B0BFM), (1<<B1BFE)|(1<<B0BFE) );
       
       
        //设置发送相关引脚控制寄存器,配置它们禁用第二功能
        mcp2515_write_register( TXRTSCTRL, 0 );
       
        //MCP2515进入环回模式,进行功能测试
//        mcp2515_bit_modify( CANCTRL, REQOP, REQOP_LOOPBACK );
       
        //MCP2515进入正常模式
        mcp2515_bit_modify( CANCTRL, REQOP, REQOP_NORMAL);
}
/************************************************/
void mcp2515_reset(void)
{
        CAN_CS=0;
        spi_wr(CAN_RESET);
        CAN_CS=1;
        delay_nms(10);
}
/*************************************************/
void mcp2515_bit_modify(uchar adress,uchar mask,uchar data1)
{
        CAN_CS=0;
        spi_wr(c_bit);
        spi_wr(adress);
        spi_wr(mask);
        spi_wr(data1);
        CAN_CS=1;       
}
/********************************************************/
void mcp2515_write_register(uchar adress,uchar data1)
{
        CAN_CS=0;
        spi_wr(c_write);
        spi_wr(adress);
        spi_wr(data1);
        CAN_CS=1;
}
/*********************************************************/
void mcp2515_write_register_p(uchar adress, uchar *data1, uchar length )
{
        uchar i;
       

        CAN_CS=0;
       
        spi_wr(c_write);                        //发送SPI写指令
       
        spi_wr(adress);                        //发送起始寄存器地址
       
        for (i=0; i<length ;i++ )
                {
                        spi_wr(*data1);       
                          data1++;
                       
                }        //发送数据
       
        //CS high ,MCP2515 disable
        CAN_CS=1;
}

/**************************************************************
uchar  mcp2515_read(uchar adress)
{
    uchar data1;
        CAN_CS=0;
        spi_wr(c_read);
        spi_wr(adress);
        data1=CAN_SCO;
        return data1;
}
******************************************************************
void mcp2515_read_register_p( uchar adress, uchar *data1, uchar length )
{
        uchar i;
       
        // CS low ,MCP2515 enable
        CAN_CS=0;
       
        send_byte(c_read);                //发送SPI读指令
       
        send_byte(adress);                //发送起始寄存器地址
       
        for (i=0; i<length ;i++ )
            {
                        *data1 = uart_data;
                        data1++;
                }        //数据保存
       
        //CS high ,MCP2515 disable
        CAN_CS=1;
}
*****************************************************************************/
void can_send_message( unsigned long id, uchar *data1, uchar length, uchar flags)
{
        uchar temp[4];
        CAN_CS=0;
        if (length > 8)
                length = 0;
       
        //设置发送缓冲器0 发送优先级,TXP[1:0] = 11 , 为最高发送优先级
        mcp2515_bit_modify( TXB0CTRL, TXP, TXP_HIGHEST );
       
        // 根据标志位,确定其ID格式,标准格式或扩展格式,同时发送其ID
        //if (flags & CAN_EID) //扩展格式,11+18位ID
        if (flags)
        {
            /*
                temp[0] = (u08) (id>>21);  //取出基本ID的高8位
                //取出基本ID的低三位,加上扩展ID的高2位,同时设置扩展标示符EXIDE使能
                temp[1] = (((u08) (id>>16)) & 0x03) | (((u08) (id>>13)) & 0xE0) | (1<<EXIDE);
               
                temp[2] = (u08) (id>>8);  //取扩展ID
                temp[3] = (u08) id;
            */
        }
        else                                 //标准格式,11位ID
        {
                temp[0] = (uchar) (id>>3);                //取出基本ID的高8位
                temp[1] = (uchar) (id<<8);        //取出基本ID的低3位 , 同时设置扩展标示符EXIDE为0,即禁用
                temp[2] = 0;
                temp[3] = 0;
        }
       
        mcp2515_write_register_p( TXB0SIDH, temp, 4 );                //发送ID
       
        // 根据标志位,设定报文是否为远程发送请求,同时设定数据字节数
        //if (flags & CAN_RTR)
        if (flags)
        {
            //mcp2515_write_register( TXB0DLC, length | (1<<RTR) );                //设定发送的报文为远程发送请求,并定义报文数据字节数
            ;
        }
        else
                mcp2515_write_register( TXB0DLC, length );                        // 设定报文的数据字节数
       
        //写入发送数据
        mcp2515_write_register_p( TXB0D0, data1, length );
       
       
        // 请求发送报文,发送缓冲器为TXB0
        mcp2515_bit_modify( TXB0CTRL, TXREQ, TXREQ_SET );

        /*
        CLR_CS;
        SPI_MasterTransmit(CAN_RTS_TXB0);
        SET_CS;
        */

}

void main()
{
  
  Uart_Init();
  mcp2515_init();
  CAN_CS=0;
  while(1)
  {
    can_send_message(ID, data1,8, 0)        ;
  }
}

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

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

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-10-3 18:04

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

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