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

📄 mcp2510.c

📁 can总线通信程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		//测试代码
		
	}
}
void CAN_SetFilter(uint8 FilterNum0_5,uint32 FilterID,BOOL isExt)
{
		uint8 i;
	uint32 temp;
	uint8 RXFnSIDH=0;
	uint8 RXFnSIDL=0;
	uint8 RXFnEID8=0;
	uint8 RXFnEID0=0;
	
	temp = FilterID;
	
	if(isExt)
	{
		for(i=0;i<8;i++)
		{
			if(temp & (1<<i))
			RXFnEID0 |= (1<<i);
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+8)))
			RXFnEID8 |= (1<<i);
		}
		for(i=0;i<2;i++)
		{
			if(temp & (1<<(i+16)))
			RXFnSIDL |= (1<<i);
		}
		for(i=0;i<3;i++)
		{
			if(temp & (1<<(i+18)))
			RXFnSIDL |= (1<<(i+5));
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+21)))
			RXFnSIDH |= (1<<i);
		}
	}
	else{
		for(i=0;i<3;i++)
		{
			if(temp & (1<<i))
			RXFnSIDL |= (1<<i+5);
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+3)))
			RXFnSIDH |= (1<<i);
		}
	}
	switch(FilterNum0_5)
	{
		case 0:
		MCPWriteByte(RXF0SIDH,RXFnSIDH);
		MCPWriteByte(RXF0SIDL,RXFnSIDH);
		MCPWriteByte(RXF0EID8,RXFnEID8);
		MCPWriteByte(RXF0EID0,RXFnEID0);
		break;
		
		case 1:
		MCPWriteByte(RXF1SIDH,RXFnSIDH);
		MCPWriteByte(RXF1SIDL,RXFnSIDH);
		MCPWriteByte(RXF1EID8,RXFnEID8);
		MCPWriteByte(RXF1EID0,RXFnEID0);
		break;
		
		case 2:
		MCPWriteByte(RXF2SIDH,RXFnSIDH);
		MCPWriteByte(RXF2SIDL,RXFnSIDH);
		MCPWriteByte(RXF2EID8,RXFnEID8);
		MCPWriteByte(RXF2EID0,RXFnEID0);
		break;
		case 3:
		MCPWriteByte(RXF3SIDH,RXFnSIDH);
		MCPWriteByte(RXF3SIDL,RXFnSIDH);
		MCPWriteByte(RXF3EID8,RXFnEID8);
		MCPWriteByte(RXF3EID0,RXFnEID0);
		break;
		case 4:
		MCPWriteByte(RXF4SIDH,RXFnSIDH);
		MCPWriteByte(RXF4SIDL,RXFnSIDH);
		MCPWriteByte(RXF4EID8,RXFnEID8);
		MCPWriteByte(RXF4EID0,RXFnEID0);
		break;
		case 5:
		MCPWriteByte(RXF5SIDH,RXFnSIDH);
		MCPWriteByte(RXF5SIDL,RXFnSIDH);
		MCPWriteByte(RXF5EID8,RXFnEID8);
		MCPWriteByte(RXF5EID0,RXFnEID0);
		break;
	
	}
}
void CAN_SetMaskAndFilter()
{
	CAN_SetMask(0,0,FALSE);//RX0MASK都为零,全部接收,无扩展帧;
	CAN_SetMask(1,0,FALSE);//RX1MASK都为零,全部接收,无扩展帧;
	
	
	//Filter0 - Filter5 都只接收 ID为零的数据
	CAN_SetFilter(0,0,FALSE);
	CAN_SetFilter(1,0,FALSE);
	CAN_SetFilter(2,0,FALSE);
	CAN_SetFilter(3,0,FALSE);
	CAN_SetFilter(4,0,FALSE);
	CAN_SetFilter(5,0,FALSE);
	/*
		// Mark all filter bits as don't care:
	CAN_SetID(RXM0SIDH, 0,0);  //不带扩展帧
	CAN_SetID(RXM1SIDH, 0,0);
	// Anyway, set all filters to 0:
	CAN_SetID(RXF0SIDH, 0, 0);
	CAN_SetID(RXF1SIDH, 0, 0);
	CAN_SetID(RXF2SIDH, 0, 0);
	CAN_SetID(RXF3SIDH, 0, 0);
	CAN_SetID(RXF4SIDH, 0, 0);
	CAN_SetID(RXF5SIDH, 0, 0);
	*/
}

void CAN_SetBandRate(CanBandRate bandrate)
{	//基于工作频率为 16MHz
	uint8 temp;
	switch(bandrate){
	case BandRate_125kbps:
		MCPWriteByte(CNF1, SJW1|BRP4);	//Synchronization Jump Width Length =1 TQ
		MCPWriteByte(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
		MCPWriteByte(CNF3, SEG4);// Phase Seg 2 = 4
		break;
	case BandRate_250kbps:
		MCPWriteByte(CNF1, SJW1|BRP2);	//Synchronization Jump Width Length =1 TQ
		
		//测试代码
		temp = MCPReadByte(CNF1);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
		
		//测试代码
		temp = MCPReadByte(CNF2);
		UART0_SendByte(temp); //0x80+0x06+0x18=0x9E
		//测试代码
		
		MCPWriteByte(CNF3, SEG4);// Phase Seg 2 = 4
		
		//测试代码
		temp = MCPReadByte(CNF3);
		UART0_SendByte(temp);//0x03
		//测试代码
		break;
	case BandRate_500kbps:
		MCPWriteByte(CNF1, SJW1|BRP1);	//Synchronization Jump Width Length =1 TQ
		MCPWriteByte(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
		MCPWriteByte(CNF3, SEG4);// Phase Seg 2 = 4
		break;
	case BandRate_1Mbps:
		MCPWriteByte(CNF1, SJW1|BRP1);	//Synchronization Jump Width Length =1 TQ
		MCPWriteByte(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG2); // Phase Seg 1 = 2, Prop Seg = 3
		MCPWriteByte(CNF3, SEG2);// Phase Seg 2 = 1
		break;
	}
}



/****************************************************
 
	  ****************CAN ************* 

****************************************************/
void CAN_Init()
{
	uint8 m,n,k;
	uint8 temp;
	/**********************************************\
				CAN配置流程
		//1、复位
		//2、进入配置模式
		//3、关CAN中断
		//4、设置屏蔽位,过滤位:filter,mask
		//5、设置波特率
		//6、切换到工作状态
		//7、清除三个接收寄存器,并且不激活它们
		//8、开中断(接收中断)
		//9、启动CAN
	**********************************************/
	//1、复位
	CANReset();
	CANReset();
	DelayNS(50);
	
	//2、进入配置模式	
	MCPWriteByte(CANCTRL,MODE_CONFIG);//MODE_CONFIG = 0A0 ,源程序为0xE0
	
	//测试代码
	temp = MCPReadByte(CANCTRL);
	UART0_SendByte(temp);
	temp = MCPReadByte(0x0e);
	UART0_SendByte(temp);
	//测试代码
	while(!((MCPReadByte(0x0E)&0xF0)==0x80));
	//5、设置波特率
	CAN_SetBandRate(BandRate_250kbps); //波特率为250kbps
	
	
	//4、设置屏蔽位,过滤位:filter,mask
	CAN_SetMaskAndFilter();
	
	//6、切换到工作状态	//使能频率输出 16MHz
	//MCPWriteByte(CANCTRL, MODE_LOOPBACK| CLKEN | CLK1);//回环模式 
	//temp = MCPReadByte(0x0e);
	//UART0_SendByte(temp);
	//while(!((MCPReadByte(0x0E)&0xF0)==0x40));
	//CANSTAT  读取CANSTAT值 确认处于该模式
	
	MCPWriteByte(CLKCTRL, MODE_NORMAL| CLKEN | CLK1);//标准模式
	while(!((MCPReadByte(0x0E)&0xE0)==0x00));
    //如果不能用两台设备联机实验的话,可以选择回环模式
    //这样利用串口调试程序进行单机调试
    
    //3、关CAN中断
	MCPWriteByte(CANINTE,DIS_INT);
    
	//7、清除三组接收寄存器,并且不激活它们
	
	m = TXB0CTRL;
	for (n = 0; n < 3; n++) {
		for (k = 0; k < 14; k++) {
			MCPWriteByte(m, 0);
			m++;
	        }
       	m += 2; // 不清除 CANSTAT 和 CANCTRL
	}
	//8、设置接收控制寄存器0_1 
	//MCPWriteByte(RXB0CTRL, 0);
	//MCPWriteByte(RXB1CTRL, 0);
	CAN_Modefybits(RXB0CTRL, (RXB_BUKT+RXB_RX_ANY), 0x64);//接收所有报文,如RXB0满则滚入RXB1
														//— RXM1 RXM0 — RXRTR BUKT BUKT1 FILHIT0
												/*
													RXB0CTRL - 接收缓冲器 0 控制寄存器( 地址: 60h)
													7 |   6  |   5  | 4 |   3   |    2 |     1 |      1
													— | RXM1 | RXM0 | — | RXRTR | BUKT | BUKT1 | FILHIT0
													bit 7 bit 0
													bit 7 未用: 读作 '0'
													bit 6-5 RXM<1:0>:接收缓冲器工作模式
													11 =关闭屏蔽/ 滤波功能;接收所有报文
													10 =只接收符合滤波器条件的带扩展标识符的有效报文
													01 =只接收符合滤波器条件的带标准标识符的有效报文
													00 =接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文
													bit 4 未用: 读作 '0'
													bit 3 RXRTR: 是否接收到远程传送请求
													1 = 接收到远程传送请求
													0 = 没有接收到远程传送请求
													bit 2 BUKT: 滚存使能
													1 = 如果RXB0 满, RXB0 接收到的报文将被滚存至RXB1
													0 = 滚存禁止
													bit 1 BUKT1: 只读位 , BUKT 位备份 (只在 MCP2510 器件内部使用).
													bit 0 FILHIT<0>:滤波器指示 - 指明使能报文接收的验收滤波寄存器编号
													1 = 验收滤波寄存器 1 (RXF1)
													0 = 验收滤波寄存器 0 (RXF0)
													注: 如果从RXB0 到RXB1 的滚存发生, FILHIT 位将反映接收滚存报文的滤波器
												*/
	CAN_Modefybits(RXB1CTRL, RXB_RX_ANY, 0x64);//接收所有报文
												/*
													RXB1CTRL - 接收缓冲器 1 控制寄存器	( 地址: 70h)
													U-0 R/W-0 R/W-0 U-0 R-0 R-0 R-0 R-0
													— RXM1 RXM0 — RXRTR FILHIT2 FILHIT1 FILHIT0
													bit 7 bit 0
													bit 7 未用: 读作 '0'
													bit 6-5 RXM<1:0>:接收缓冲器工作模式
													11 =关闭屏蔽/ 滤波功能;接收任何报文
													10 =只接收符合滤波器条件的带扩展标识符的有效报文
													01 =只接收符合滤波器条件的带标准标识符的有效报文
													00 =接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文
													bit 4 未用: 读作 '0'
													bit 3 RXRTR: 是否收到远程传递请求
													1 = 接收到远程传递请求
													0 = 未收到远程传递请求
													bit 2-0 FILHIT<2:0>: 滤波器指示 - 显示使能报文接收的过滤寄存器编号
													101 = 验收滤波寄存器 5 (RXF5)
													100 = 验收滤波寄存器 4 (RXF4)
													011 = 验收滤波寄存器3 (RXF3)
													010 = 验收滤波寄存器 2 (RXF2)
													001 = 验收滤波寄存器 1 (RXF1) ( 只有当RXB0CTRL 中的 BUKT 位置1 时)
													000 = 验收滤波寄存器 0 (RXF0) ( 只有当RXB0CTRL 中的 BUKT 位置1 时)
												*/
	//9、引脚RX0BF和RX1BF用来控制两个LED灯,设置为输出并清零
	//  MCPWriteByte(BFPCTRL, 0x3C);
												/*
													BFPCTRL - RXNBF 引脚控制和状态寄存器
													( 地址: 0Ch)
													寄存器 4-4: RXBNSIDH - 接收缓冲器 N 标准标识符高位
													( 地址: 61h, 71h)
													U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
													— — B1BFS B0BFS B1BFE B0BFE B1BFM B0BFM
													bit 7 bit 0
													bit 7 未用: 读作 '0'
													bit 6 未用: 读作 '0'
													bit 5 B1BFS: RX1BF 引脚状态 ( 只限数字输出工作模式)
													- 当RX1BF 配置为中断请求引脚时,读作 ‘0’
													bit 4 B0BFS: RX0BF 引脚状态 ( 只限数字输出工作模式)
													- 当RX0BF 配置为中断请求引脚时,读作 ‘0’
													bit 3 B1BFE: RX1BF 引脚功能使能
													1 = 引脚功能使能, 工作模式由 B1BFM 位的状态决定
													0 = 引脚功能禁止, 引脚为高阻状态
													bit 2 B0BFE: RX0BF 引脚功能使能
													1 = 引脚功能使能, 工作模式由 B0BFM 位的状态决定
													0 = 引脚功能禁止, 引脚为高阻状态
													bit 1 B1BFM: RX1BF 引脚工作模式
													1 = 当有效报文载入RXB1 时,该引脚用来产生中断请求
													0 = 数字输出模式
													bit 0 B0BFM: RX0BF 引脚工作模式
													1 = 当有效报文载入RXB0 时,该引脚用来产生中断请求
													0 = 数字输出模式
												*/
  
	  //10、设置发送寄存器 ()
														/*
						TXBNCTRL 发送缓冲器N 控制寄存器
														( 地址: 30h, 40h, 50h)
														U-0 R-0 R-0 R-0 R/W-0 U-0 R/W-0 R/W-0
														— ABTF MLOA TXERR TXREQ — TXP1 TXP0
														bit 7 bit 0
														bit 7 未用: 读作 '0'
														bit 6 ABTF: 报文发送中止标志
														1 = 报文中止
														0 = 报文发送成功
														bit 5 MLOA: 报文仲裁失败
														1 = 报文发送中仲裁失败
														0 = 报文发送中仲裁未失败
														bit 4 TXERR: 检测到的发送错误
														1 = 报文发送中发生了总线错误
														0 = 报文发送中未发生总线错误
														bit 3 TXREQ: 报文发送请求
														1 = 缓冲器等待报文发送
														( 单片机将此位置位以请求报文发送 - 报文发送后该位自动清零)
														0 = 缓冲器无报文发送
														( 单片机将此位清零以请求中止报文发送)
														bit 2 未使用: 读作 '0'
														bit 1-0 TXP<1:0>: 发送缓冲器优先级
														11 = 最高的报文发送优先级
														10 = 中偏高的报文发送优先级
														11 = 中偏低的报文发送优先级
														00 = 最低的报文发送优先级
												*/	
														/*	
				TXRTSCTRL - TXNRTS 引脚控制和状态寄存器
														( 地址: 0Dh)
														寄存器3-3: TXBNSIDH - 发送缓冲器N 标准标识符高位
														( 地址: 31h, 41h, 51h)
														U-0 U-0 R-x R-x R-x R/W-0 R/W-0 R/W-0
														— — B2RTS B1RTS B0RTS B2RTSM B1RTSM B0RTSM
														bit 7 bit 0
														bit 7 未使用: 读作 '0'
														bit 6 未使用: 读作 '0'
														bit 5 B2RTS: TX2RTS 引脚状态
														- 作为数字输入引脚时,读出值为 TX2RTS 引脚电平
														- 作为请求发送输入引脚时读作 ‘0’
														bit 4 B1RTS: TX1RTX 引脚状态
														- 作为数字输入引脚时,读出值为 TX1RTS 引脚电平
														- 作为请求发送输入引脚时读作 ‘0’
														bit 3 B0RTS: TX0RTS 引脚状态
														- 作为数字输入引脚时,读出值为 TX0RTS 引脚电平
														- 作为请求发送输入引脚时读作 ‘0’
														bit 2 B2RTSM: TX2RTS 引脚模式
														1 = 该引脚用来请求 TXB2 缓冲器发送报文 ( 在下降沿)
														0 = 数字输入
														bit 1 B1RTSM: TX1RTS 引脚模式
														1 = 该引脚用来请求 TXB1 缓冲器发送报文 ( 在下降沿)
														0 = 数字输入
														bit 0 B0RTSM: TX0RTS 引脚模式
														1 = 该引脚用来请求 TXB0 缓冲器发送报文 ( 在下降沿)
														0 = 数字输入
														*/
	//8、开中断(接收中断)
	MCPWriteByte(CANINTE, RX0IE|RX1IE);//移到配置模式下设置
	
	//9、启动CAN 
	
	
    
	
}




void CAN_Test()
{	uint8  i,j; 
    uint8 rcv_data;
 	//CANReset();
	//CANReset();
	DelayNS(50);
	
	MCPWriteByte(0x0F,0xA0);
	DelayNS(50);
    rcv_data = MCPReadByte(0x0F);
	UART0_SendByte( rcv_data);//
	
	MCPWriteByte(0x0F,0xA0);
    DelayNS(50);	
	rcv_data = MCPReadByte(0x0F);
	UART0_SendByte( rcv_data);//
	DelayNS(50);
	
	MCPWriteByte(0x61,0x23);	
	DelayNS(50);
	
	MCPWriteByte(0x2A,0x0a);	
	MCPWriteByte(0x2A,0x0a);
	DelayNS(50);
	
	MCPWriteByte(0x0F,0x05);
    DelayNS(50);	
	rcv_data = MCPReadByte(0x0F);
	UART0_SendByte( rcv_data);//
	DelayNS(50);
	
	rcv_data = MCPReadByte(0x61);
	UART0_SendByte( rcv_data);//
	
	MCPWriteByte(0x2A,0xb3);
    DelayNS(50);
	rcv_data = MCPReadByte(0x2A);
	UART0_SendByte( rcv_data);//
	DelayNS(50);
   
   while(1)	
   {  for(i=0; i<16; i++) 
      {  
        
      	// rcv_data = SpiSendData(DISP_TAB[i]);	//  发送显示数据
      	
      //	rcv_data = ReadStatus();
       //  j= MReadData();
      	// UART0_SendByte( rcv_data);
      	 for(j=0;j<64;j++)
      	 {
	      	 rcv_data = MCPReadByte(j);
	      	 UART0_SendByte( rcv_data);      	 
	         DelayNS(50);	
         }	
      }
   }
  }

⌨️ 快捷键说明

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