unsigned char CAN_TX_Buf[8]={'1','2','3','5','8','3','1','4'};
unsigned char CAN_RX_Buf[9];
void Init2515(void)
{
SPIReset(); //CAN(MCP2515)复位
delay_ms(1);
BitModiMcp2515(CANCTRL,0xe0,REQOP_CONFIG);//进入配置模式
while(SPIByteRead(CANSTAT)&0xE0!=0x80) //判断是否已经进入配置模式
{
BitModiMcp2515(CANCTRL,0xe0,0x80);
delay_ms(100);
SendString("Position 1");
}
//设置波特率为10Kbps
//set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5us
SPIByteWrite(CNF1,CAN_125Kbps);
//set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ
SPIByteWrite(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
//set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位
SPIByteWrite(CNF3,PHSEG2_3TQ);
//配置发送
SPIByteWrite( TXRTSCTRL, 0 ); //禁用引脚的发送请求功能
//配置接收,
SPIByteWrite( BFPCTRL, 0 ); //禁用引脚的接收中断功能
SPIByteWrite(RXM0SIDH,0x00); //接收屏蔽
SPIByteWrite(RXM0SIDL,0x00); // H/L=0/0 ---- 接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文
SPIByteWrite(RXF0SIDH,0x00); //接收过滤
SPIByteWrite(RXF0SIDL,0x00); //接收所有数据
SPIByteWrite(RXB0CTRL,0x60); //0x60代表接收所有报文,0x20代表接收STDID的报文
//CAN中断的初始化
//MCP2515_INT_Init();
//配置模式(回环/正常模式)
while(SPIByteRead(CANSTAT)&0xe0!=REQOP_LOOPBACK);
{
SPIByteWrite(CANCTRL,REQOP_LOOPBACK); //进入回环模式
}
}
//CAN发送程序--包括ID、DLC(数据长度)、RTR(帧类型)、DATA
void CAN_Send(unsigned char *CAN_TX_Buf)
{
unsigned char tempdata;
//设置ID---每个节点的ID是唯一的,但接收的ID可以有多个
SPIByteWrite(TXB0SIDH,0xFF);//设置发送缓冲器0的标准标识符,
SPIByteWrite(TXB0SIDL,0xE0);//使用标准ID---发送标准标识符
//设置DLC和RTR
SPIByteWrite(TXB0DLC,DLC_8);//设置发送数据帧---长度为8个字节
//发送数据
SPIByteWrite(TXB0D0,CAN_TX_Buf[0]); //向发送缓冲器写数据
SPIByteWrite(TXB0D1,CAN_TX_Buf[1]);
SPIByteWrite(TXB0D2,CAN_TX_Buf[2]);
SPIByteWrite(TXB0D3,CAN_TX_Buf[3]);
SPIByteWrite(TXB0D4,CAN_TX_Buf[4]);
SPIByteWrite(TXB0D5,CAN_TX_Buf[5]);
SPIByteWrite(TXB0D6,CAN_TX_Buf[6]);
SPIByteWrite(TXB0D7,CAN_TX_Buf[7]);
//启动发送
BitModiMcp2515(TXB0CTRL,0x08,0x08); //发送缓冲器0请求发送
delay_ms(1);
tempdata=SPIByteRead(TXB0CTRL); //读状态寄存器--读发送状态
while(tempdata&0x08) //判断TXREQ标志位(此处可能有错)
{ //对应寄存器TXBnCTRL的位3
BitModiMcp2515(TXB0CTRL,0x08,0x08); //发送缓冲器0请求发送
delay_ms(1);
tempdata=SPIByteRead(TXB0CTRL); //读状态寄存器--读发送状态(读状态指令failed,但读TXB0CTRLsucceed)
SendString("TX is failed\n");
}
SendString("TX is succeed\n");
}
//CAN接收程序
void CAN_Receive(unsigned char *CAN_RX_Buf)
{
//接收数据
CAN_RX_Buf[0]=SPIByteRead(RXB0D0); //从接收缓冲器0中读数据
CAN_RX_Buf[1]=SPIByteRead(RXB0D1);
CAN_RX_Buf[2]=SPIByteRead(RXB0D2);
CAN_RX_Buf[3]=SPIByteRead(RXB0D3);
CAN_RX_Buf[4]=SPIByteRead(RXB0D4);
CAN_RX_Buf[5]=SPIByteRead(RXB0D5);
CAN_RX_Buf[6]=SPIByteRead(RXB0D6);
CAN_RX_Buf[7]=SPIByteRead(RXB0D7); //从接收缓冲器7中读数据
}
//外中断(主要用于接收数据)
void MCP2515_Int(void) interrupt 0 using 1
{
CAN_Receive(CAN_RX_Buf); //接收数据
SPIByteWrite(CANINTF,0); //CAN中断标志位清零
SendString("Receive data:");
SendString("CAN_RX_Buf");
}
//中断初始化
void MCP2515_INT_Init(void)
{
//外部中断初始化
EX0 = 1; //开外部中断0
IT0 = 1; //负边沿触发
EA = 1; //开总中断
//MCP2515中断初始化-----设置接收缓冲器0中断
SPIByteWrite(CANINTF,0x00);//清空中断标志位
SPIByteWrite(CANINTE,0x01);//接收缓冲器0满中断使能位
}
void main()
{
InitUart();
LED_OFF(all); //全熄灭代表进入配置模式
CAN_RX_Buf[9]=0;
while(1)
{
Init2515(); //CAN初始化
SendString("Position 3\n");
CAN_Send(CAN_TX_Buf);
//应该先判断是否接收到数据
if(SPIByteRead(RXB0DLC)&0x0f!=0)
{
SendString("Receive data:");
CAN_Receive(CAN_RX_Buf); //轮询法接收数据 (或者中断法接收数据)
SendString(CAN_RX_Buf);
SendUart('\n');
}
LED_ON_OFF(LED_2); //指示程序运行
delay_ms(100);
}
}
发送成功了,但是未收到数据,这是为什么?(使用的回环测试) |