上级目录TMS320F28335使用教程
CAN通讯协议——————待插入链接
CAN结构和特性介绍
Controller Area Network (CAN)
芯片框架和接口电路
模块架构:
有32个消息邮箱,传输消息时根据消息优先级进行传输,如果超过一个邮箱的消息有相同的优先级,则先传输高编号邮箱中的消息。
To initiate a data transfer, the transmission request bit (TRS.n) must be set.
The SCC(Standard CAN Controller) mode or the full featured eCAN mode is selected using the SCB bit (CANMC.13).
SCC模式:
The SCC Mode is a reduced functionality mode of the eCAN. Only 16 mailboxes (0 through 15) are available in this mode.
邮箱结构:
The mailbox module in the eCAN provides 32 message mailboxes of 8-byte data length, a 29-bit identifier,
and several control bits. Each mailbox can be configured as either transmit or receive. In the eCAN mode,
each mailbox has its individual acceptance mask.
寄存器访问应一次访问多少宽度的数据(8位、16位、32位):
The eCAN module has two different address segments mapped in the memory. The first segment is used
to access the control registers, the status registers, the acceptance masks, the time stamp, and the timeout of the message objects. The access to the control and status registers is limited to 32-bit wide
accesses. The local acceptance masks, the time stamp registers, and the time-out registers can be
accessed 8-bit, 16-bit and 32-bit wide. The second address segment is used to access the mailboxes.
This memory range can be accessed 8-bit, 16-bit and 32-bit wide.
上面提到一些寄存器只能32位读写,下面举例
当需要检查寄存器中某一位状态时应用do-while,而不要直接用while
CAN内存分布:
Each mailbox contains:
• The message identifier
– 29 bits for extended identifier
– 11 bits for standard identifier
• The identifier extension bit, IDE (MSGID.31)
• The acceptance mask enable bit, AME (MSGID.30)
• The auto answer mode bit, AAM (MSGID.29)
• The transmit priority level, TPL (MSGCTRL.12-8)
• The remote transmission request bit, RTR (MSGCTRL.4)
• The data length code, DLC (MSGCTRL.3-0)
• Up to eight bytes for the data field
每个消息邮箱可以设置成一下四种模式之一:
接受和回复消息可以是1对多连接,而请求数据和回复则是1对1.
发送消息特性
发送邮箱消息时,按照设定优先级开始发送,如果两个邮箱设定的优先级相同,则先发送高标号的邮箱中的消息。
发送邮箱消息时,有消息仲裁失败,此时有其他邮箱消息需要发送,且优先级更高,例如A邮箱的TRS位被置位,B邮箱的TRS位也被置位,分两种情况:
1.A邮箱仲裁失败前,B邮箱对应TRS置位,则会先发送B邮箱消息。
2.A邮箱仲裁失败后,B邮箱对应TRS置位,则会先发送A邮箱消息。
接收消息特性
RMP—receive-messagepending
RML—receive messagelost
OPC—overwrite-protection
接收消息后,会与接收邮箱比对标识符与控制位,如果相等,则会把数据存入对应邮箱中,对应的RMP[n]会置位,如果使能了接收中断则会产生中断,如果标识符与控制位没有匹配上,则不会存储数据。
比对标识符会先从高标号的消息邮箱开始,eCAN模式31到0,SCC模式15到0.
RMP[n]会在CPU读取对应消息后复位。
如果邮箱消息还没读取,此时来了第二条消息,对应的消息丢失位RML[n]会被置位,如果OPC[n]位被清除,第二条消息会覆盖第一条消息,否则,则会选中下一个邮箱(暂时未知选中下一个邮箱是什么意思)。
正常配置下的CAN模块
相同网络中的CAN模块应配置为相同的速率
CAN模块初始化流程
关于位时长的了解
CAN模块寄存器:
//官方文件
// eCAN Control & Status register file
//
struct ECAN_REGS {
union CANME_REG CANME; // Mailbox Enable
union CANMD_REG CANMD; // Mailbox Direction
union CANTRS_REG CANTRS; // Transmit Request Set
union CANTRR_REG CANTRR; // Transmit Request Reset
union CANTA_REG CANTA; // Transmit Acknowledge
union CANAA_REG CANAA; // Abort Acknowledge
union CANRMP_REG CANRMP; // Received Message Pending
union CANRML_REG CANRML; // Received Message Lost
union CANRFP_REG CANRFP; // Remote Frame Pending
union CANGAM_REG CANGAM; // Global Acceptance Mask
union CANMC_REG CANMC; // Master Control
union CANBTC_REG CANBTC; // Bit Timing
union CANES_REG CANES; // Error Status
union CANTEC_REG CANTEC; // Transmit Error Counter
union CANREC_REG CANREC; // Receive Error Counter
union CANGIF0_REG CANGIF0; // Global Interrupt Flag 0
union CANGIM_REG CANGIM; // Global Interrupt Mask 0
union CANGIF1_REG CANGIF1; // Global Interrupt Flag 1
union CANMIM_REG CANMIM; // Mailbox Interrupt Mask
union CANMIL_REG CANMIL; // Mailbox Interrupt Level
union CANOPC_REG CANOPC; // Overwrite Protection Control
union CANTIOC_REG CANTIOC; // TX I/O Control
union CANRIOC_REG CANRIOC; // RX I/O Control
Uint32 CANTSC; // Time-stamp counter
union CANTOC_REG CANTOC; // Time-out Control
union CANTOS_REG CANTOS; // Time-out Status
};
实验
本次实验实现CANA邮箱0发送,CANB邮箱0接收
开发板电路图
时钟参考:
TMS320F28335时钟和系统控制
比特率计算:SYSCLKOUT=150mhz
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx分界线xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
调整BRP的值,可以获得不同CAN模块的时钟,对应不同CAN总线速度。
设置CAN模块步骤
本次实验实现CANA邮箱0发送,CANB邮箱0接收
参考了下官方例程,感觉和技术手册不是很一样,所以我按照技术手册重写了下面的初始化的代码,代码中只是为了实现需要的功能,所以都是针对特定的功能实现的初始化,如果想要移植需要修改的地方比较多。实际应用中可以使用指针传参来初始化,这样移植和使用比较简单
step1.
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B
step2
//复用GPIOInitECanaGpio(void)
{
EALLOW;
//
// Enable internal pull-up for the selected CAN pins
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
//
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; //Enable pull-up for GPIO19 (CANTXA)
GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; //Enable pull-up for GPIO16(CANTXB)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17(CANRXB)
//
// Set qualification for selected CAN pins to asynch only
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.
//由参考手册得知,作为外设且异步输入,赋值3
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch qual for GPIO18 (CANRXA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)
//
// Configure eCAN-A pins using GPIO regs
// This specifies which of the possible GPIO pins will be eCAN functional
// pins.
//
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // Configure GPIO18 for CANRXA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; // Configure GPIO19 for CANTXA
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB
EDIS;
}
CANa模块配置:
//
// InitECana - Initialize eCAN-A module
//
void InitECana(void)
{
//
// Create a shadow register structure for the CAN control registers. This
// is needed, since only 32-bit access is allowed to these registers.
// 16-bit access to these registers could potentially corrupt the register
// contents or return false data. This is especially true while writing
// to/reading from a bit (or group of bits) among bits 16 - 31
//
struct ECAN_REGS ECanaShadow;
EALLOW; // EALLOW enables access to protected bits
//step2
// Configure eCAN RX and TX pins for CAN operation using eCAN regs
//
ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
ECanaShadow.CANTIOC.bit.TXFUNC = 1;
ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
ECanaShadow.CANRIOC.bit.RXFUNC = 1;
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
//step3
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
ECanaShadow.CANMC.bit.CCR = 1;
}while(ECanaShadow.CANES.bit.CCE != 1 );
//step4
// The following block for all 150 MHz SYSCLKOUT
// (75 MHz CAN clock) - default. Bit rate = 1 Mbps See Note at End of File
//
ECanaShadow.CANBTC.bit.BRPREG = 4;
ECanaShadow.CANBTC.bit.TSEG2REG = 2;
ECanaShadow.CANBTC.bit.TSEG1REG = 10;
ECanaShadow.CANBTC.bit.SAM = 1;//三次采样,并以多的结果为准,如采样3次,两次为1,一次为0,则结果为1
ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
//step5
// Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
// HECC mode also enables time-stamping feature
//
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.SCB = 1;//set 1 select eCAN mode
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
//step6
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.all &= 0xFFFFE000 ; // clean CANMC0-12
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
//step7
// Initialize all bits of 'Master Control Field' to zero
// Some bits of MSGCTRL register come up in an unknown state. For proper
// operation, all bits (including reserved bits) of MSGCTRL must be
// initialized to zero
//
ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;
//step8
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 0 );// Wait for CCE bit to be cleared
EDIS;
}
CANb模块配置:
//
// InitECanb - Initialize eCAN-B module
//
void InitECanb(void)
{
//
// Create a shadow register structure for the CAN control registers. This
// is needed, since only 32-bit access is allowed to these registers.
// 16-bit access to these registers could potentially corrupt the register
// contents or return false data. This is especially true while writing
// to/reading from a bit (or group of bits) among bits 16 - 31
//
struct ECAN_REGS ECanbShadow;
EALLOW; // EALLOW enables access to protected bits
//step2
// Configure eCAN RX and TX pins for CAN operation using eCAN regs
//
ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all;
ECanbShadow.CANTIOC.bit.TXFUNC = 1;
ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;
ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all;
ECanbShadow.CANRIOC.bit.RXFUNC = 1;
ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;
//step3
do
{
ECanbShadow.CANES.all = ECanbRegs.CANES.all;
ECanbShadow.CANMC.bit.CCR = 1;
}while(ECanbShadow.CANES.bit.CCE != 1 );
//step4
// The following block for all 150 MHz SYSCLKOUT
// (75 MHz CAN clock) - default. Bit rate = 1 Mbps See Note at End of File
//
ECanbShadow.CANBTC.bit.BRPREG = 4;
ECanbShadow.CANBTC.bit.TSEG2REG = 2;
ECanbShadow.CANBTC.bit.TSEG1REG = 10;
ECanbShadow.CANBTC.bit.SAM = 1;//三次采样,并以多的结果为准,如采样3次,两次为1,一次为0,则结果为1
ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;
//step5
// Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
// HECC mode also enables time-stamping feature
//
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
ECanbShadow.CANMC.bit.SCB = 1;//set 1 select eCAN mode
ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
//step6
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
ECanbShadow.CANMC.all &= 0xFFFFE000 ; // clean CANMC0-12
ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
//step7
// Initialize all bits of 'Master Control Field' to zero
// Some bits of MSGCTRL register come up in an unknown state. For proper
// operation, all bits (including reserved bits) of MSGCTRL must be
// initialized to zero
//
ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;
ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;
//step8
do
{
ECanbShadow.CANES.all = ECanbRegs.CANES.all;
} while(ECanbShadow.CANES.bit.CCE != 0 );// Wait for CCE bit to be cleared
EDIS;
}
配置发送消息邮箱(CANa的邮箱0作为发送邮箱):
//用一个邮箱作为测试 发送
void InitECanaMailbox(void)
{
struct ECAN_REGS ECanaShadow;
//1
//初始化CAN时,RTR已经清零
ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
ECanaShadow.CANTRS.bit.TRS0 = 0;
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
//2 disable mailbox
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = 0;//0xFFFFFFFF;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
//3
//0x95555555,1001 0101 0101 0101 0101 0101 0101 0101
//标准数据帧,17:0没有意义,28:18是id:1 0101 0101 01
ECanaMboxes.MBOX0.MSGID.all = 0x95555555;
ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;//8个字节数据
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD0 = 0;//作为发送邮箱
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
//4 enable mailbox
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
}
发出发送邮箱中的消息:
void CANTXData(Uint32 DataH,Uint32 DataL)
{
struct ECAN_REGS ECanaShadow;
//1
ECanaMboxes.MBOX0.MDH.all = DataH;
ECanaMboxes.MBOX0.MDL.all = DataL;
//2发送请求位置一
ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
ECanaShadow.CANTRS.bit.TRS0 = 1;
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
//3 等待传输完成,传输应答位会置位
do
{
ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
}while(ECanaShadow.CANTA.bit.TA0 != 1);
//4 发送完成后,对应TRS[]会置零,想要再次发送,需要置位对应TRS
//5 在下一次传输前,传输应答需要清理掉,向对应TA[]中写1会清理该位
ECanaShadow.CANTA.all = 0;
ECanaShadow.CANTA.bit.TA0 = 1; // Clear TA0
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
}
配置接受消息邮箱(CANb的邮箱0作为接受消息邮箱):
//用一个邮箱作为测试 接收
void InitECanbMailbox(void)
{
struct ECAN_REGS ECanbShadow;
//1 disable mailbox
ECanbShadow.CANME.all = ECanbRegs.CANME.all;
ECanbShadow.CANME.bit.ME0 = 0;//0xFFFFFFFF;
ECanbRegs.CANME.all = ECanbShadow.CANME.all;
//2 id
ECanbMboxes.MBOX0.MSGID.all = 0x95555555;
//3 AME未使用
//4 接收邮箱
ECanbShadow.CANMD.all = ECanbRegs.CANMD.all;
ECanbShadow.CANMD.bit.MD0 = 1;//作为发送邮箱
ECanbRegs.CANMD.all = ECanbShadow.CANMD.all;
//5
ECanbShadow.CANOPC.all = ECanbRegs.CANOPC.all;
ECanbShadow.CANOPC.bit.OPC0 = 1;//保护消息不被覆盖
ECanbRegs.CANOPC.all = ECanbShadow.CANOPC.all;
//6 enable mailbox
ECanbShadow.CANME.all = ECanbRegs.CANME.all;
ECanbShadow.CANME.bit.ME0 = 1;//0xFFFFFFFF;
ECanbRegs.CANME.all = ECanbShadow.CANME.all;
}
读取接收邮箱中的消息:
Uint64 CANRXData()
{
//当接收到消息后,CANRMP[]对应位会被置一,在读取接收到的数据之前,
//应先向对应位CANRMP[]写入1,以此来清除对应位的CANRMP[],
//读取完消息后要检查CANRMP[]是否是1,如果是1的话,说明在此期间
//来了新的数据,如果覆盖原有数据的话,cpu读取的数据就是错误的,刚
//才我们在初始化接收受邮箱时,已经对先收到的数据开保护了,所以不用检测了
struct ECAN_REGS ECanbShadow;
Uint32 DataH=0,DataL=0;
do
{
ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
}
while(ECanbShadow.CANRMP.bit.RMP0 != 1);
ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
ECanbShadow.CANRMP.bit.RMP0 = 1;
ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;
DataH = ECanbMboxes.MBOX0.MDH.all;
DataL = ECanbMboxes.MBOX0.MDL.all;
return DataH*0x100000000+DataL;
}
程序代码:
//主程序中直接调用测试代码即可
void CANTest()
{
Uint64 Temp=0,i=0;
InitECanGpio();
InitECana();
InitECanb();
InitECanaMailbox();
InitECanbMailbox();
//i放在发送邮箱中,发送到接收邮箱,cpu读取接收邮箱中的消息放在Temp中,如果i与Temp值相等则说明实验成功
for(;;)
{
CANTXData((i&0xffffffff00000000)>>32,(i&0xffffffff));
Temp = CANRXData();//有警告,只是因为Temp设置了没使用,在这Temp只是为了观察现象
i=i+1000000000;//加1000000000让实验现象更明显
}
}
在"i=i+1000000000;"处设置断点
实验现象:
多次运行到断点后:
结果如预期现象i等于Temp,发送和接受消息成功了
断开can通讯,现象:
程序会在这个位置等待,因为传输消息一直没成功
至此,基本发送和接受功能已经实现