|
#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碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|