CAN应用笔记.docx
- 文档编号:9969162
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:29
- 大小:820.18KB
CAN应用笔记.docx
《CAN应用笔记.docx》由会员分享,可在线阅读,更多相关《CAN应用笔记.docx(29页珍藏版)》请在冰豆网上搜索。
CAN应用笔记
LPC2294-CAN状态寄存器
LPC2294CANModule状态寄存器:
1、每个CAN控制器均带有两个在操作状态下(NormalOperationMode)只读状态寄存器:
CANGSR和CANSR;
2、CANGSR包含全局状态包括每个CAN控制器的发送(TBS、TCS、TS)、接收(RBS、RS)、接收过载(DOS)、错误(ES)及CAN-Bus状态(BS),另外有两个8Bits的Rx/Tx错误计数器;
CANSR中的RBS、DOS、RS、ES、BS位与CANGSR中的相同,由于每个CAN控制器带三个发送缓冲区,因此CANSR对每个缓存的状态作出更为细致的反馈:
TBS(发送缓冲区状态)被肢解成三:
TBS1,TBS2,TBS3
TCS(发送完成)被肢解成三:
TCS1,TCS2,TCS3
TS(正在发送)被肢解成三:
TS1,TS2,TS3
2、CANGSR与CANSR中寄存器位之间的关系:
TBS=TBS1&TBS2&TBS3(与操作)
TCS=TCS1&TCS2&TCS3(与操作)
TS =TS1 |TS2 |TS3 (或操作)
3、发送函数中一般应对CANSR查询以决定向某一个空闲的缓冲区写入发送数据;接收函数若采用中断方式应在服务例程末对CANCMR进行操作,以释放接收缓冲区单元同时RBS位清零;
4、发送、接收例程(本例程已通过测试可用):
/*
***************************************************************************************************
***函数名:
CAN_PushMsg
***功能描述:
CAN数据发送
***输入输出:
***创建日期:
2007-5-72:
18 by:
CANopen
***修改日期:
2007-5-72:
18 by:
***************************************************************************************************
*/
voidCAN_PushMsg(int8ucan_port,CAN_MSG*pTxBuf)
{
int32u*pAddr=0;
int8u tBuf=0;
if(can_port<1||can_port>2)return;
switch(can_port)
{
case1:
if(CAN1SR&(__1<<2))
{
pAddr=(int32u*)&(CAN1TFI1);
tBuf=1;
}
else //tBuf1不可用
{
if(CAN1SR&(__1<<10))
{
pAddr=(int32u*)&(CAN1TFI2);
tBuf=2;
}
else //tBuf2不可用
{
if(CAN1SR&(__1<<18))
{
pAddr=(int32u*)&(CAN1TFI3);
tBuf=3;
}
else //tBuf3不可用
return; //所有的tBuf都不可用,则返回
}
}
*pAddr=pTxBuf->Frame;
pAddr++;
*pAddr=pTxBuf->MsgID;
pAddr++;
*pAddr=pTxBuf->DatA;
pAddr++;
*pAddr=pTxBuf->DatB;
switch(tBuf)
{
case1:
CAN1CMR=0x21; //选择tBuf1发送
break;
case2:
CAN1CMR=0x41; //选择tBuf2发送
break;
case3:
CAN1CMR=0x81; //选择tBuf3发送
break;
default:
break;
}
break;
case2:
if(CAN2SR&(__1<<2))
{
pAddr=(int32u*)&(CAN2TFI1);
tBuf=1;
}
else
{
if(CAN2SR&(__1<<10))
{
pAddr=(int32u*)&(CAN2TFI2);
tBuf=2;
}
else
{
if(CAN2SR&(__1<<18))
{
pAddr=(int32u*)&(CAN2TFI3);
tBuf=3;
}
else
return;
}
}
*pAddr=pTxBuf->Frame; //相应寄存器装入发送数据Msg
pAddr++;
*pAddr=pTxBuf->MsgID;
pAddr++;
*pAddr=pTxBuf->DatA;
pAddr++;
*pAddr=pTxBuf->DatB;
switch(tBuf) //置位发送请求
{
case1:
CAN2CMR=0x21;
break;
case2:
CAN2CMR=0x41;
break;
case3:
CAN2CMR=0x81;
break;
default:
break;
}
break;
default:
break;
}
}
/*
***********************************************************************************
***函数名:
CAN2_Rx_ISR
***功能描述:
CAN数据接收,中断服务例程,将接收数据装入数据队列,同时Led3闪烁
***输入输出:
***创建日期:
2007-5-72:
19 by:
CANopen
***修改日期:
2007-5-72:
19 by:
***********************************************************************************
*/
__irqvoidCAN2_Rx_ISR(void)
{
int32u*pAddr;
if(CAN2RFS&0x00000400) //查询BP位,1标识该数据为BypassMode下接收
{
pAddr=(int32u*)&(gCAN_RxQ[1][gRxQ_In[1]]);
*pAddr++=CAN2RFS; //Frame
*pAddr++=CAN2RID; //ID
*pAddr++=CAN2RDA; //DataA
*pAddr++=CAN2RDB; //DataB
gRxQ_In[1]++; //数据队列指针调整
if(gRxQ_In[1]>=MAX_Q)
{
gRxQ_In[1]=0;
}
}
CAN2CMR=0x04; //释放接收寄存器,同时RBS位清零
VICVectAddr=0x00U; //acknowledgeInterrupt
LedFlash(Led3);
}
5、CANGSR、CANSR寄存器截图:
<<-------CANGSR
<<---------CANSR
(1)
<<--------CANSR
(2)
LPC2294-CAN调试
两天前调试CAN通讯,LPC2294CAN模块初始化为BypassMode(旁路模式),CAN1发送,CAN2接收,调试结果:
CAN1GSR总停留在数据正在发送状态(TS=1),而CAN2的所有寄存器均为初始化或复位之后的状态,如下为调试截图:
CAN1寄存器状态截图
CAN2寄存器状态截图
CAN1GSR=0x80000020==>TS=1,说明写入的数据在不停的发送,发送错误计数器为128,标识CAN1进入了Errorpass(错误被动)状态,按理说数据发N次了不成功错误累加CAN1将进入Busoff状态,可调试结果偏偏显示CAN1停留在Errorpass状态;
不晓得是因为什么,而且我所有的C语句流都是遵照流程图写完的,查N遍了没发现什么差错;一个晚上的时间就要过去了,走出实验室晃悠--天边正现鱼肚白,想着越发觉得伤心正准备跳楼的时候,老天助我,原来引脚初始化时的一个致命疏忽,将P0.23置为了GPIO!
!
马上修改回来,设置为RD2,调试,通了,终于又舒舒服服的回家洗澡,睡了一个好觉.
今天重看了一遍协议规范,摘录如下:
Note:
> Ifduringstart-uponly1nodeisonline,andifthisnodetranmitssomemessage,itwillgetnoacknowledgment,detectanerrorandrepeatthemessage.Itcanbecome'Errorpassive'butnot'busoff'duetothisreason. /* ******************************************************************************************** ByPassMode: 不能单独对某一个CAN控制器设置为该模式,一旦设置所有的CAN控制器均为BypassMode 所有的CAN控制器都会无条件的接收CANbus上非自身发送的数据 ByPassMode与TestMode并不相同,CAN1并不接收自身发送的数据 ******************************************************************************************** */ CAN笔记1 1、CAN协议(ConrollerAreaNetworkProtocol)为RobertBosch公司开发(1982年),最初应用于汽车内部网络的通讯。 CAN通讯具有严格的错误检测机制、高传输速率,兼低成本、易于实施,特别适合节点之间关键数据传输的小型嵌入式网络通讯; 2、CAN网络各节点平等竞争,无所谓主从,CAN通讯基于生产/消费者模型,一个节点生产(发送)的数据可同时为网络上的一个或几个节点同时消费也即接收(本人强烈鄙视某些教科书上将CAN网络描述为多主方式! ! ); 3、CAN协议严格的规范了OSI模型中的数据链路层,并未对物理层作出强硬的约束,因此,CAN帧msg可传输在各种物理介质上,比较常见的为双绞线信号传输; 4、CAN总线上的逻辑电平: CAN-bus采用差分电压信号驱动,用显性电平(逻辑0)、隐性电平(逻辑1)标识,当CAN-bus表现为显性时,CAN-bus为差分电压驱动状态,CANL电平为“Gnd”偏上,CANH电平为“Vcc”偏下;当CAN-bus表现为隐性状态时,CAN-bus为未驱动空闲状态,此时CANL、CANH电平均为“Vcc”的一半,比如: 假设Gnd=0V,Vcc=5V,则CANH=CANL=2.5V。 总线上的先行隐性电平会被显性电平所改写; 5、CAN-bus上的位流序列: 仲裁场-CANID最高位最先发送;数据场-Data0最先发送,Data7最后传输,对应每一个字节,高位msb将会先发送; 位填充规则: 位流序列中一旦出现五个连续的显性位将插入一个隐性位,如下图示;同时位流序列中一旦出现五个连续的隐性位将插入一个显性位。 位编码规则: 1、错误帧和过载帧形式固定,并不通过位填充编码; 2、数据帧或远程帧的CRC界定符、应答场、帧结束等位场形式固定,不通过位填充编码; 3、数据帧或远程帧的帧起始、仲裁场、控制场、数据场、CRC序列等位场,均通过位填充规则编码。 6、关于CAN协议规范,可标识为三种,它们最基本的区别为: V2.0A 操作11位标识符 V2.0BPassive V2.0A的增强版,操作11位标识符 V2.0BActive 可操作29位标识符 当满足不同CAN规范的CAN控制器同时出现与一个CAN网络中时,这些CAN控制器各自的表现为: CAN笔记2 1、Message一词在CAN通讯中有特殊的内涵: 首先它是一个位流序列,有固定的长度,并且有固定的格式; 2、通常用一个ID(IDENTIFIER)来标识一个CAN-bus上的Message,在同一个CAN-bus上(如一条双铰线)传输的Message必须具有不同的ID; 3、一个以某ID值标识的CANMessage也称一个CAN帧(CANFrame),当这个CAN帧的ID用11位二进制来标识时为一个标准帧(StandardFrame),用29位二进制来标识时为一个扩展帧(ExtendedFrame); 4、CAN通讯严格执行“非破坏性仲裁”机制,最低优先级的CAN帧具有最高的ID二进制值,因为CAN-bus采用差分驱动,同时写入总线上的显性电平、隐性电平仅表现为显性电平; 5、标准帧的优先级高于扩展帧,后续将会阐释为什么; 6、数据帧和远程帧用ID标识,错误帧和过载帧并不占用ID标识符,因为程序员不可能向CAN网络发送错误帧或过载帧,这两种帧由CAN控制器单独编码解码,CAN控制器内部集成错误、过载检测机制,一旦检测到传输错误或过载,CAN控制器会自动发送错误帧或过载帧,程序员只能查询CAN控制器状态位观察网络状态(是什么错误或者是否出现过载); 7、数据帧和远程帧: 扩展帧ID标识符为ID28-ID0,标准帧ID标识符取扩展帧的高11位(ID28-ID18); CAN通讯通过规约IDE位作为对标准帧和扩展帧的标识,在标准帧中该位为显性电平(0),扩展帧中该位为隐性电平 (1),接收器检测位流序列的IDE位以识别接收的是标准帧还是扩展帧; CAN通讯通过规约RTR位作为对数据帧和远程帧的标识,在数据帧中该位为显性电平(0),远程帧中该位为隐性电平 (1),接收器检测位流序列的RTR位以决定对接收状态寄存器中的RTR位置位/复位,而对状态位RTR是否作出响应由程序员决定; 不管在标准帧还是扩展帧,IDE在位序流中的位置不变,标准帧的RTR位被扩展帧的SRR位替代,SRR位在扩展帧中必须为隐性位,扩展帧的RTR位被置于保留为r1前。 这样,当一扩展帧和一标准帧同时出现在网络并且扩展帧的高11位与标准帧相同时,若该标准帧为数据帧,则RTR为显性而对应的扩展帧中SSR位为隐性,于是标准帧竞争总线成功继续发送而扩展帧对应节点竞争失败转为接收节点; 若该标准帧为远程帧,RTR位与SRR为同为隐性,不存在冲突两帧继续发送IDE位,标准帧中IDE为显性而扩展帧中IDE为隐性,同样标准帧竞争成功继续享用总线而扩展帧对应的节点竞争总线失败转为接收器; 这也就是标准帧的优先级总高于扩展帧的原因。 远程帧除不具有数据帧的数据场之外,其它各位场与数据帧一致。 8、错误帧: 错误帧包括两个位场: ErrorFlag(错误标识场)和ErrorDelimiter(错误界定场)。 ErrorDelimiter为八个连续的隐性位; CAN通讯的DefaultConfinement(故障界定)机制会自动的将网络上进入错误状态的节点划入三个不同的等级: ErrorActive,ErrorPassive,BusOff。 处于BusOff状态的节点完全和总线脱离,这里先鄙视它。 因此,ErrorFlag也就仅有两种不同的形式(位编码): ACTIVEERRORFLAG及PASSIVEERRORFLAG; ACTIVEERRORFLAG由处于ErrorActive状态的节点发出,编码为六个连续的显性位; PASSIVEERRORFLAG由处于ErrorPassive状态的节点发出,编码为六个连续的隐性位; 处于ErrorActive和ErrorPassive状态的CAN节点都会一丝不苟的执行CAN通讯的ErrorDectection(错误检测)机制,一旦检测到错误就会立即发出相应的ErrorFlag报告; ErrorActive状态下节点发出的ErrorFlag破坏了位填充规则,并且不能被改写因此一旦发出其他节点会立马识别出这是一个错误帧;个人觉得ErrorPassive状态下节点发出的ErrorFlag有一种瞎搅乎的味道,它并不驱动总线,其它节点还以为总线空闲而启动传输哩,呵呵; ErrorActive节点检测到错误发出六个连续的显性位随即发送隐性位,直至检测CAN-bus也表现为隐性,接着发送7个连续的隐性电平,错误帧发送完毕; ErrorPassive节点检测到错误后发出连续的隐性位,若检测CAN-bus出现六个连续的显性位或隐性位则PassiveErrorFlag发送完成,接着继续发送隐性位至检测CAN-bus也表现为隐性,最后送出7个连续的隐性位,错误帧发送完毕。 注意: 由于错误叠加,最终表现在CAN-bus的ActiveErrorFlag会有6-12bits不等。 错误帧的发出时刻: 一旦节点检测到位错误、或位填充错误、或帧格式错误、或应答错误,错误帧立即在比特流的下一个bit发出;若接收节点检测CRC错误,该错误帧在应答界定位处发出,除非之前上述四种错误如应答错误或位错误已经发出。 9、过载帧: 有三种情况会发送过载帧: 1、接收端: 上次接收的数据未被CPU读取就已经被再次滤波进来的CAN数据改写; 2、CAN节点检测到帧间隔的第一位或第二位为显性位; 3、CAN节点采样到错误帧的错误界定场或过载帧的过载界定场有显性位; OverloadFlag及OverloadDelimiter与ActiveErrorFlag及ErrorDelimiter一致,不赘述。 过载帧的发出时刻: (1、)必须、只能在其接收的数据帧结束后马上发出,而且必须、只能在帧间歇的第一个位时间发出;(2、3、)在检测到显性位后马上发出。 10、帧间隔(InterFrameSpacing): CAN通讯规范: 数据帧和远程帧在发送前必须有一个帧间隔,错误帧和过载帧可连续发送无帧间隔限制。 帧间隔期间,CAN-bus表现为隐性未驱动状态。 根据CAN节点所处的故障界定等级及之前为发送器还是接收器,其帧间隔位时也不同: 对于ErrorActive节点(不管之前为发送器还是接收器),其发送数据帧或远程帧必须在上一个CAN帧结束后等待至少3个隐性位(这三个隐性位被称为Intermission); 对于ErrorPassive节点,若之前为发送器,其发送数据帧或远程帧必须在上一个CAN帧结束后等待至少11个隐性位方可继续发送;若之前为接收器,其发送数据帧或远程帧在上一个CAN帧结束后等待至少3个隐性位。 帧间隔(InterFrameSpace)之后CAN-Bus若仍表现为隐性未驱动状态,该总线状态被标识为BusIdle。 CAN笔记3 1、当同一个CAN网络中出现相同的CANID时 CAN总线的非破坏性仲裁机制不允许两个(多个)相同ID的CAN帧存在同一网络,当这种情况出现时,就存在一种可能: 两个CAN帧同时参与总线竞争,要不同时竞争失败,要不同时竞争成功均获得总线使用权,一旦这两个具有相同ID的CAN帧同时享用总线,仲裁场发送完毕接着发送控制场、数据场……当然这两个位流序列不可能完全相同于是位错误(BitCheckError)必将同时被两节点检测到,两节点同时发出错误帧接着CAN-bus重启两个CAN帧重新参与竞争…………有一种可能,网络上将出现死循环,所以必须小心! ! 2、以标准帧(数据帧)为例,拆解CAN帧位序流 SOF(StartOfFrame): 显性位(0),必须在BusIdle状态发出,网络上所有节点在“下降沿”执行一次同步; IdentifierField: 11bits,CANID; RTR(RemoteTransmissionRequestBit): 显性位(0),隐性 (1)时标识该帧为远程帧; IDE(IdentifierExtensionBit): 显性位(0),标识该帧为标准帧; r0(reservedbit): 保留位,发送器必须发送显性位,但接收器检测到该位表现为不敏感,不会激发biterror错误; DLC(DataLengthCode): 4bits,标识数据场的数据字节数,DLC=0时,数据场无数据,DLC>=0x1000时,数据场为8字节数据; DataField: 将要发送的过程数据,0-8字节,具体有DLC确定,Data0先发送,Data0的Msb先发送; CRCSequence: 循环冗余检测序列,校验和,15bits,由CAN控制器硬件完成CRC算法并位场填充; CRCDelimiter: CRC界定符,1bit,必须为隐性; AckSlot: 应答间隙,1bit,发送器端送出隐性电平,接收端送出显性位标识握手信号,发送器检测该位为隐性将激发应答错误; AckDelimiter: 应答界
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CAN 应用 笔记
![提示](https://static.bdocx.com/images/bang_tan.gif)