|
#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 };
uchar SPIdata[16];
/****************************************/
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 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_SCO=(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_write_register( CNF1, 0x01 ); // 500kbps
mcp2515_write_register( CNF2, 0x8A );
mcp2515_write_register( CNF3, 0x01 );
// 设置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, 0x07);
//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;
}
/*****************************************************************************/
void can_send_message( unsigned long id, uchar *data1, uchar length, uchar flags)
{
uchar temp3[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
{
temp3[0] = (uchar) (id>>3); //取出基本ID的高8位
temp3[1] = (uchar) (id<<8); //取出基本ID的低3位 , 同时设置扩展标示符EXIDE为0,即禁用
temp3[2] = 0;
temp3[3] = 0;
}
mcp2515_write_register_p( TXB0SIDH, temp3, 1 );
mcp2515_write_register_p( TXB0SIDL, &temp3[1], 1 ); //发送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 );
mcp2515_write_register(CAN_RTS_TXB0,0x07);
// 请求发送报文,发送缓冲器为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周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|