📄 mcp2510.c
字号:
#include "config.h"
#include "UART_SPI.h"
#include "MCP2510.h"
#define CAN_RESET_ADD 0xc0
#define CAN_READ_ADD 0x03
#define CAN_WRITE_ADD 0x02
#define CAN_RTS_ADD 0x80 //发送请求
#define CAN_RDSTAT_ADD 0xa0 //读状态
#define CAN_BITMDFY_ADD 0x05 //位修改
/****************************************************
****************CAN Lib*************
****************************************************/
void MCPWriteByte(uint8 addr,uint8 data)
{
CAN_CS(); // 片选
SpiSendByte(CAN_WRITE_ADD);
SpiSendByte(addr);
SpiSendByte(data);
CAN_UnCS();
}
uint8 MCPReadByte(uint8 addr)
{
uint8 tempdata;
CAN_CS();
SpiSendByte(CAN_READ_ADD);
SpiSendByte(addr);
tempdata = SpiSendByte(0xFF);
CAN_UnCS();
return tempdata;
}
uint8 MCPReadCANStatus()
{
uint8 temp;
CAN_CS();
S0PDR = CAN_RDSTAT_ADD;
while( 0==(S0PSR&0x80) ); // 等待SPIF置位,即等待数据发送完毕
temp = S0PDR;
//S0PDR = 0x00; //得不到数据就写
S0PDR = 0xFF;
while( 0==(S0PSR&0x80) ); // 等待SPIF置位,即等待数据发送完毕
temp = S0PDR;
//temp = S0PDR;
CAN_UnCS();
return temp;
}
void CAN_Modefybits( uint8 address, uint8 data, uint8 mask )//mask 位为0:data中相应的位无效
{ // 位为1:data中相应的位写入
CAN_CS();
SpiSendByte(CAN_BITMDFY_ADD);
SpiSendByte(address);
SpiSendByte(mask);
SpiSendByte(data);
CAN_UnCS();
}
void CANReset()
{
CAN_CS();
SpiSendByte(CAN_RESET_ADD);
CAN_UnCS();
}
/*******************************************\
* 序列写入CAN控制器数据 *
\*******************************************/
void MCP_WriteSeq(uint8 address, uint8* pdata, uint8 nlength)
{
uint8 i;
CAN_CS();
SpiSendByte(CAN_WRITE_ADD); //从spi口写入write命令
SpiSendByte(address); //写入要写入的地址
for (i=0; i < nlength; i++) //写入数据0-8个byte
{
SpiSendByte(*pdata);
pdata++;
}
CAN_UnCS();
}
/*******************************************\
* 序列读出CAN控制器数据 *
\*******************************************/
void MCP_ReadSeq(uint8 address,uint8 *pdata,uint8 nlength)
{
uint8 i;
CAN_CS();
SpiSendByte(CAN_READ_ADD); //从spi口写入read命令
SpiSendByte(address); //写入读出的地址
for (i=0; i<nlength; i++) {
//SendSIOData(0);
*pdata=SpiSendByte(0xFF);
pdata++;
}
CAN_UnCS();
}
/***********************************************************\
* 写入MCP2510 发送的数据 *
* 参数: nbuffer为第几个缓冲区可以为0、1、2 *
* ext表示是否是扩展总线 *
* can_id为返回的ID值 *
* rxRTR表示是否是RXRTR *
* data表示读取的数据 *
* dlc表示data length code *
* FALSE,表示非扩展总线 *
\***********************************************************/
void CAN_WriteData(uint8 ntxbuffer0_2,uint32 id, uint8 *pdata, uint8 dlc, BOOL isExt, BOOL rxRTR)
{
uint8 i;
uint32 temp;
CANTXDATA txdata;
temp=id;
if(isExt)
{
for(i=0;i<8;i++)
{
if(temp & (1<<i))
{
txdata.TXBnEID0 |= (1<<i);
}
else
txdata.TXBnEID0 &= ~(1<<i);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+8)))
{
txdata.TXBnEID8 |= (1<<i);
}
else
txdata.TXBnEID8 &= ~(1<<i);
}
for(i=0;i<2;i++)
{
if(temp & (1<<(i+16)))
{
txdata.TXBnSIDL |= (1<<i);
}
else
txdata.TXBnSIDL &= ~(1<<i);
}
for(i=0;i<3;i++)
{
if(temp & (1<<(i+18)))
{
txdata.TXBnSIDL |= (1<<(i+5));
}
else
txdata.TXBnSIDL &= ~(1<<i);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+21)))
{
txdata.TXBnSIDH |= (1<<i);
}
else
txdata.TXBnSIDH &= ~(1<<i);
}
txdata.TXBnSIDL |= EXIDE;//扩展标识符使能
}
else{
for(i=0;i<3;i++)
{
if(temp & (1<<i))
{
txdata.TXBnSIDL |= (1<<i+5);
}
else
txdata.TXBnSIDL &= ~(1<<i);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+3)))
{
txdata.TXBnSIDH |= (1<<i);
}
else
txdata.TXBnSIDH &= ~(1<<i);
}
txdata.TXBnSIDL &= ~EXIDE;//扩展标识符使能
}
txdata.TXBnDLC = 0;
txdata.TXBnDLC = dlc;
if(rxRTR)
{
txdata.TXBnDLC |= 0x40;
}
else
txdata.TXBnDLC &= ~0x40;
for(i=0;i<8;i++)
{
txdata.TXBmDn[i]=*pdata++;
}
switch (ntxbuffer0_2)
{
case 0:
MCP_WriteSeq(TXB0SIDH,&txdata.TXBnSIDH,13);
UART0_SendByte(MCPReadByte(TXB0CTRL));
CAN_Modefybits(TXB0CTRL,0x0B,0x0B);//以最高优先级启动发送
break;
case 1:
MCP_WriteSeq(TXB1SIDH,&txdata.TXBnSIDH,13);
CAN_Modefybits(TXB1CTRL,0x0B,0x0B);//以最高优先级启动发送
break;
case 2:
MCP_WriteSeq(TXB2SIDH,&txdata.TXBnSIDH,13);
CAN_Modefybits(TXB2CTRL,0x0B,0x0B);//以最高优先级启动发送
break;
}
}
CANRXDATA MCPReadCANData(uint8 rxbuff0_1)
{
uint8 i;
CANRXDATAREG rxdata;
CANRXDATA MCPrxdata;
if(rxbuff0_1 == 0)
{
MCP_ReadSeq(RXB0SIDH,&rxdata.RXBnSIDH,13);
}
else
{
MCP_ReadSeq(RXB1SIDH,&rxdata.RXBnSIDH,13);
}
if((rxdata.RXBnSIDL & 0x18)==0x18)//收到的为扩展帧
{
MCPrxdata.isExt = TRUE;
if(rxdata.RXBnDLC & 0x40) //远程请求帧
{
MCPrxdata.isRTR = TRUE;
MCPrxdata.rxNum = 0;//没有数据
for(i=0;i<8;i++)
MCPrxdata.rxData[i]=0;
}
else //远程数据帧
MCPrxdata.isRTR = FALSE;
MCPrxdata.rxNum = (rxdata.RXBnDLC & 0x07); //远程数据帧的数据长度
MCPrxdata.id = (uint32)rxdata.RXBnEID0;
MCPrxdata.id |= ((uint32)rxdata.RXBnEID8)<<8;
MCPrxdata.id |= ((uint32)(rxdata.RXBnSIDL & 0x03))<<16;
MCPrxdata.id |= ((uint32)(rxdata.RXBnSIDL & 0xE0))<<13;//5->18
MCPrxdata.id |= ((uint32)rxdata.RXBnSIDH)<<21;
}
else if((rxdata.RXBnSIDL & 0x18)==0x00) //标准数据帧
{
MCPrxdata.isExt = FALSE;
MCPrxdata.id = (uint32)rxdata.RXBnSIDL;
MCPrxdata.id = ((uint32)rxdata.RXBnSIDH)<<8;
}
for(i=0;i<8;i++)
MCPrxdata.rxData[i]=rxdata.RXBmDn[i];
return (MCPrxdata);
}
CANRXDATA CAN_ReadData()//用中断模式的接收从另一个CAN总线发送过来的数据
{ //查询方式可读取CANSTAT值
uint8 byte;
//uint8 *pdata;
CANRXDATA mcprxdata;
byte = MCPReadByte(CANINTF);
if(byte & RX0INT)
{
mcprxdata = MCPReadCANData(0);
CAN_Modefybits(CANINTF,(uint8)~RX0INT,RX0INT);//清除中断标志
}
else if(byte & RX1INT)
{
mcprxdata = MCPReadCANData(1);
CAN_Modefybits(CANINTF,(uint8)~RX1INT,RX1INT);
}
return (mcprxdata);
}
/****************************************************
****** CAN *******
****************************************************/
/*******************************************\
* 设置MCP2510 CAN总线ID *
* 参数: address为MCP2510寄存器地址 *
* can_id为设置的ID值 *
* IsExt表示是否为扩展ID *
\*****************************************/
void CAN_SetMask(uint8 RXnMASK0_1,uint32 MaskID,BOOL isExt)//id:是扩展帧:0-17:扩展ID,18-28:标识符
{ //不是 :0-10标识符
uint8 i;
uint32 temp;
uint8 RXMnSIDH=0;
uint8 RXMnSIDL=0;
uint8 RXMnEID8=0;
uint8 RXMnEID0=0;
temp = MaskID;
if(isExt)
{
for(i=0;i<8;i++)
{
if(temp & (1<<i))
{
RXMnEID0 |= (1<<i);
}
else
RXMnEID0 &= ~(1<<i);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+8)))
{
RXMnEID8 |= (1<<i);
}
else
RXMnEID8 &= ~(1<<i);
}
for(i=0;i<2;i++)
{
if(temp & (1<<(i+16)))
{
RXMnSIDL |= (1<<i);
}
else
RXMnSIDL &= ~(1<<i);
}
for(i=0;i<3;i++)
{
if(temp & (1<<(i+18)))
{
RXMnSIDL |= (1<<(i+5));
}
else
RXMnSIDL &= ~(1<<i);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+21)))
{
RXMnSIDH |= (1<<i);
}
else
RXMnSIDH &= ~(1<<i);
}
}
else
{
for(i=0;i<3;i++)
{
if(temp & (1<<i))
{
RXMnSIDL |= (1<<i+5);
}
else
RXMnSIDL |= (1<<i+5);
}
for(i=0;i<8;i++)
{
if(temp & (1<<(i+3)))
{
RXMnSIDH |= (1<<i);
}
else
RXMnSIDH &= ~(1<<i);
}
}
if(RXnMASK0_1==0)
{
MCPWriteByte(RXM0SIDH,RXMnSIDH);
//测试代码
temp = MCPReadByte(RXM0SIDH);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM0SIDL,RXMnSIDH);
//测试代码
temp = MCPReadByte(RXM0SIDL);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM0EID8,RXMnEID8);
//测试代码
temp = MCPReadByte(RXM0EID8);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM0EID0,RXMnEID0);
//测试代码
temp = MCPReadByte(RXM0EID0);
UART0_SendByte(temp);//0x01
//测试代码
}
else
{
MCPWriteByte(RXM1SIDH,RXMnSIDH);
//测试代码
temp = MCPReadByte(RXM1SIDH);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM1SIDL,RXMnSIDH);
//测试代码
temp = MCPReadByte(RXM1SIDL);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM1EID8,RXMnEID8);
//测试代码
temp = MCPReadByte(RXM1EID8);
UART0_SendByte(temp);//0x01
//测试代码
MCPWriteByte(RXM1EID0,RXMnEID0);
//测试代码
temp = MCPReadByte(RXM1EID0);
UART0_SendByte(temp);//0x01
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -