⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcp2515.cpp

📁 CAN总线驱动程序
💻 CPP
字号:
#include "stdafx.h"
#include "mcp2515.h"
#include "spi.h"

#define  MAX_SEND_LEN  32
#define  MAX_RECV_LEN  32

const UINT8 BaudRate[][4] = 
{
	//CNF3  CNF2    CNF1   mode
	0x03,   0x9E,   0x03,  0x07,    //125k
	0x03,   0x9E,   0x01,  0x06,    //250k
	0x03,   0x9E,   0x00,  0x05,    //500k
	0x01,   0x91,   0x00,  0x05,    //1M
};

static INT32 Data_Read(UINT8 add, UINT8 * buf, UINT8 len)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 send[MAX_SEND_LEN];
	UINT8 recv[MAX_SEND_LEN];
	UINT8 i;

	send[0] = READ_COMMAND;  
	send[1] = add;

	SPI_Tranceive(send, recv, len + 2);
  
	for (i = 0; i < len; i++)
	{
		*(buf + i) = recv[i + 2];
	}

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return len;
}

static INT32 Data_Write(UINT8 add, UINT8 * buf, UINT8 len)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 send[MAX_SEND_LEN];
	UINT8 i;
	
	send[0] = WRITE_COMMAND;
	send[1] = add;

	for (i = 0; i < len; i++)
	{
		send[i + 2] = *(buf + i);
	}

	SPI_Tranceive(send, NULL, len + 2);

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return len;
}

static INT32 Tx_Write(UINT8 add, UINT8 * buf, UINT16 len)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 send[MAX_SEND_LEN];
	UINT8 i;
	
	send[0] = WRITETX_COMMAND | (add & 0x07);

	for (i = 0; i < len; i++)
	{
		send[i + 1] = *(buf + i);
	}

	SPI_Tranceive(send, NULL, len + 1);

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return len;
}

static INT32 Command_Write(UINT8 cmd)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 send[MAX_SEND_LEN];

	send[0] = cmd;

	SPI_Tranceive(send, NULL, 1);

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return 1;
}

static void BIT_Modify(UINT8 add, UINT8 mask, UINT8 data)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 send[MAX_SEND_LEN];

	send[0] = BITM_COMMAND;   
	send[1] = add;
	send[2] = mask;
	send[3] = data;

	SPI_Tranceive(send, NULL, 4);

	RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

}


BOOL MCP2515_Init(UINT8 baud)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 temp; 

	if (! MCP2515_Reset())
		return FALSE;

	MCP2515_SetBaudrate(baud);

	BIT_Modify(CAN_TXB0CTRL, 0x0B, 0x03);       //buf0最高优先级
	BIT_Modify(CAN_TXB1CTRL, 0x0B, 0x02);       //buf1次高优先级
	BIT_Modify(CAN_TXB2CTRL, 0x0B, 0x01);       //buf2最低优先级

	BIT_Modify(CAN_RXB0CTRL, 0xFF, 0x20);      //接收缓存0关闭屏蔽和滤波,接受所有报文,0x30正常屏蔽滤波
	BIT_Modify(CAN_RXB1CTRL, 0xFF, 0x21);      //接收缓存1关闭屏蔽和滤波,接受所有报文,0x00正常屏蔽滤波

    //接收滤波器0    
	temp = 0x00;                           
	Data_Write(RXF0SIDH, &temp, 1);         //RX0滤波ID 高8位 只使用高三位
	temp = 0x00;                            
	Data_Write(RXF0SIDL, &temp, 1);         //RX0滤波ID 低3位 

	//接收屏蔽滤波器0  
	temp = 0xE0;                            
	Data_Write(RXM0SIDH, &temp, 1);         //RX0滤波ID 屏蔽了高三位
	temp = 0x00;                            
	Data_Write(RXM0SIDL, &temp, 1);         //RX0滤波ID 低3位 

	//引脚配置
    temp = 0x00;                           //禁用引脚功能
    Data_Write(CAN_TXRTSCTRL,&temp,1);     //芯片发送引脚使能设置 
    Data_Write(CAN_BFPCTRL,&temp,1);      //接收引脚控制使能   

	//进入正常工作模式
    if (! MCP2515_SetMode(BaudRate[baud][3]))
		return FALSE;

    //中断开启   
    BIT_Modify(CANINTF, 0xFF, 0x00);     //运行到此说明初始化成功
    BIT_Modify(CANINTE, 0xFF, 0x01);  

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return TRUE;
}

BOOL MCP2515_Reset(VOID)
{
   UINT8 temp, i;

   RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

   for (i = 0; i < 3; i++)
   {
		Command_Write(RESET_COMMAND);

		Sleep(1);  

		Data_Read(CANSTAT, &temp,1);           
		
		if ((temp & 0xE0) == 0x80)            
		{
			return TRUE;
		}
   }

   RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

   return FALSE;
}

INT32 MCP2515_Read(CAN_MSG_t * pCanMsg)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 flag = 0, i;
	UINT8 recv[MAX_SEND_LEN];

    Data_Read(CANINTF, &flag, 1); 

    if (flag & 0x01)                
    {
		Data_Read(CAN_RXB0SIDH, recv, 13);

        pCanMsg->id = ((UINT32)recv[0]<<3)+(recv[1]>>5);
        pCanMsg->length = recv[4] & 0x0F;

        for (i = 0; i < 8; i++)
        {
			pCanMsg->data[i] = recv[5 + i];
        }

		flag = 0;
        Data_Write(CANINTF, &flag, 1);   
    }

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));
	return 0;
}

INT32 MCP2515_Write(CAN_MSG_t * pCanMsg)
{
   RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

   UINT8 idh, idl;

   pCanMsg->id = pCanMsg->id << 5;           
   idh = pCanMsg->id >> 8;
   idl = (UINT8)pCanMsg->id & 0xE0;       

   // Send ID and data length
   Data_Write(CAN_TXB0SIDH, &idh, 1);
   Data_Write(CAN_TXB0SIDL, &idl, 1);
   Data_Write(CAN_TXB0DLC, (UINT8 *)&pCanMsg->length, 1);

   // Send data
   Tx_Write(0x01, pCanMsg->data, pCanMsg->length);
   
   // Request to send
   Command_Write(RTS0_COMMAND);   
   
   RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

   return pCanMsg->length;
}

static BOOL MCP2515_SetBaudrate(UINT8 baud)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 temp[3], i;

	for (i = 0; i < 3; i++)
	{
		//CNF3 CNF2 CNF1
		Data_Write(CAN_CNF3, (UINT8 *)BaudRate[baud], 3);

		Sleep(1);
		
		Data_Read(CAN_CNF3, temp, 3);
		
		if ((temp[0] == BaudRate[baud][0])
			&& (temp[1] == BaudRate[baud][1])
			&&(temp[2] == BaudRate[baud][2]))
		{  
			return TRUE;
		}
	}

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return FALSE;
}

BOOL MCP2515_SetMode(UINT8 mode)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 temp[3], i;

	for (i = 0; i < 3; i++)
	{
		BIT_Modify(CAN_MODE, 0xFF, mode); 

		Sleep(1);

		Data_Read(CANSTAT, temp, 2);  
		if ((temp[1] == mode) 
			&& ((temp[0] & 0xE0) == (mode & 0xE0)))
		{
			return TRUE;
		}
   }

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -