📄 mcp2510.c
字号:
//测试代码
}
}
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 + -