STM32-13 透过SPI驱动MCP2515实现CAN(上)

STM32内建已经有CANBus了~这篇主要是练习SPI并透过MCP2515去实现CanBus通讯!

先来介绍一下MCP2515模组,他已经将MCP2515与TJA1050整合起来了,可以直接透过SPI去做驱动!
http://img2.58codes.com/2024/20146325YJuiWKDGzK.png
接下来我们来先看一下这块模组的DataSheet看看到底要如何使用它来实现CANBus通讯!


传送

http://img2.58codes.com/2024/20146325Z8aGufuh50.png
这一段提到在发送之前至少需要将TxBnSIDH、TxBnSIDL、TxBnDLC写入对应位元,假设有资料要发送则需要将TxBnDm填入要发送的资料,同时将TXBnSIDL.EXIDE设为1。

下方的Note则提到发送之前需要将TXBnCTRL.TXREQ设为0(代表目前没有正在等待发送的资料)

接下来看看有关于传送到底有那些暂存器吧~

TXBnCTRL :发送缓冲器n控制暂存器,MCP2515具有3个发送缓冲器(TxB0-TxB2),主要设置优先权与触发传送。可以看到当中bit3为TXREQ再传送时须将此位设1,并在发送后会自动清0。
http://img2.58codes.com/2024/20146325Ky4kTww7sg.pngTXBnSIDH/TXBnSIDL/TXBnEID8/TXBnEID0 : 这边则是设置ID的部分拉,也就是上一篇所提到仲裁码设置,SIDH与SIDL是标準格式(CAN2.0A)的ID设置,假设要使用扩展格式(CAN2.0B)则将SIDL当中EXIDE位设置为1,并将后续EID8与EID0填入资料就可以拉~
http://img2.58codes.com/2024/20146325Ee7w4khbBR.png
http://img2.58codes.com/2024/20146325cp3lNBuwCM.png
http://img2.58codes.com/2024/20146325AGOSTZyVl2.png
http://img2.58codes.com/2024/20146325Cn8OvEMkPG.pngTXBnDLC : 资料长度暂存器用来写入资料长度or是否为远端框架。依据后续data资料选择填入对应的资料长度,若为远端框架则将RTR位设置为1。
http://img2.58codes.com/2024/20146325z5gQ3sX4Sl.pngTXBnDm0-TXBnDm7 : 传送资料暂存器,如果传送讯息中带有资料,则将所要传送的资料写入此暂存器,并将对应资料量填入上方DLC当中。
http://img2.58codes.com/2024/20146325fwbwSsOnh2.png

接收

再MCP2515当中有两个接收Buffer,分别是RXB0跟RXB1会优先使用RXB0来做接收。
http://img2.58codes.com/2024/20146325ZbGUNz1ZOm.png
上方图片为手册当中说明如何接收,当接收到资料时会将CANINTF.RXnIF位设置为1,代表着接收到讯息并触发中断,这部分必须要由MCU再次将它设置为0才可以接收下一笔讯息。

接着同样来看看与接收相关的暂存器有哪些吧!

RXB0CTRL : 接收缓冲控制暂存器,用来设定接收讯息的条件与是否可接受滚存。(滚存为当RXB0已存在讯息时,下一条讯息不管条件为何皆由RXB1先接收)
http://img2.58codes.com/2024/20146325vUWqIQ83oC.pngRXBnSIDH/RXBnSIDL/RXBnEID8/RXBnEID0 : 接收仲裁码暂存器,当接收讯息时会将该讯息的ID写入,依照标準与扩展格式分别填入。要注意这四个Register只提供读而已!
http://img2.58codes.com/2024/20146325XuddwRQeQj.png
http://img2.58codes.com/2024/20146325gee2yqPXNb.png
http://img2.58codes.com/2024/20146325qzTr7Eb1uH.png
http://img2.58codes.com/2024/20146325E71sqMvLPG.pngRXBnDLC :接收资料长度暂存器,同样只能做读取,在接收到资料时可以依照此暂存器查看是否会RTR以及该笔讯息所带资料长度。
http://img2.58codes.com/2024/20146325tCnPPw5pGz.pngRXBnDm: 接收资料暂存器,当有资料接收时依照上方DLC长度来将资料陆续写入此暂存器,同样仅提供读取而已。
http://img2.58codes.com/2024/20146325gajWjTqCDM.png

Mask 与 Filter设置

前一篇文有提到CANBus在接收讯息时会需要验证ID、Mask与Filter来确定资料是否接收。

在MCP2515当中同样需要去做设定~建议在做测试时将Mask通通设定为0即可!

Mask Bit nFilter Bit nMessage Identifier BitAccept or Reject Bit n0x (任意值)x (任意值)Accept100Accept101Reject110Reject111Accept

Filter相关暂存器

RXFnSIDH/RXFnSIDL/RXFnEID8/RXFnEID0 : 同样依照是选择标準格式还是扩展格式来选填,标準格式只需填入RXFnSIDH/RXFnSIDL扩展格式则须写入4个暂存器。
http://img2.58codes.com/2024/20146325h09o6haevG.png
http://img2.58codes.com/2024/20146325YBB8tBuaTx.png
http://img2.58codes.com/2024/20146325kVvihz9A1Y.png
http://img2.58codes.com/2024/20146325fZdIEgb0WH.png

Mask相关暂存器

RXMnSIDH/RXMnSIDL/RXMnEID8/RXMnEID0 : 与上方Filter设定方式相同,建议在Mask当中填入0去做测试,方便接收所有ID讯息。
http://img2.58codes.com/2024/20146325ibGboOBWGM.png
http://img2.58codes.com/2024/20146325NQa6AslJJ7.png
http://img2.58codes.com/2024/20146325g9SaDqKXRD.png
http://img2.58codes.com/2024/20146325ANZo35zmRr.png

BIT TIMING

CANBus当中所有节点都必须以相同的Nominal Bit rate进行通讯,但不是所有的节点设备都具有相同的系统时钟频率,所以需要去Prescaler去对单位时间(TQ)做调整已达到相同的Nominal Bit rate。
https://chart.googleapis.com/chart?cht=tx&chl=NBR%20%3D%20fbit%20%3D%201%20%2Ftbit
https://chart.googleapis.com/chart?cht=tx&chl=tbit%20%3D%20tsyncSeg%20%2B%20tPropSeg%20%2B%20tPS1%20%2B%20tPS2
http://img2.58codes.com/2024/2014632575xFcOIrSx.png
PropSeg : 补偿节点间的物理传输延迟时间,可设定1-8TQ

PS1与PS2 : 补偿Bus上的边缘相位误差,其中PS1可设定1-8TQ PS2可设置2-8TQ

如何计算TQ

https://chart.googleapis.com/chart?cht=tx&chl=TQ%20%3D%202%20*%20BRP%20*%20TOSC%20%3D%202%20*%20%20(BRP%2B1)%20%2F%20FOSC
BRP : Bit rate 预分频器

同步

硬同步 : Bus在空闲状态时发生1→0的跳变边沿状况时进行应同步再同步 : 可能会导致PS1延长orPS2缩短,由SJW(同步跳转宽度)决定,会有以下三种情况(PS1 = PS1+SJW PS2 = PS2-SJW),SJW可设定1-4TQ不发生再同步 : 当Input Single 发生跳变(1→0)在同步区段当中(SyncSeg),则无相位误差无须调整。
http://img2.58codes.com/2024/20146325mRZAJ40NWR.png与较慢的发送设备再同步 : 当Input Single 发生跳变(1→0)大于同步区段(SyncSeg)且误差为正,则PS1加上SJW。
http://img2.58codes.com/2024/20146325fV4vVyoLj5.png与较快的发送设备再同步 : 当Input Single 发生跳变(1→0)大于同步区段(SyncSeg)且误差为负时,则PS2减去SJW。
http://img2.58codes.com/2024/201463255bCfvwJJIM.png

设置时间段时应注意

PropSeg + PS1 ≥ PS2PropSeg + PS2 ≥TdelayPS2>SJW

相关暂存器设置

CNF1 : bit6-7为同步跳转宽度(SJW),通常设置为1-2TQ bit5-0则为预分频係数设置。
http://img2.58codes.com/2024/20146325rGEBa0mBtW.pngCNF2 : 设置PropSeg 、PS1与採样位置,当SAM设置为0採样一次1则为3次採样点位置应该位于60%-90%
http://img2.58codes.com/2024/20146325HlcTCnze17.pngCNF3 : 设置SOF与PS2
http://img2.58codes.com/2024/20146325aas6n4T3Iv.png
EX : 假如FOSC = 16M BRP=7 且希望得到BRT为125kbps

1.可以得知tbit = 1/125kpbs = 8us(SyncSeg + PropSeg + PS1 +PS2 = 8TQ)

2.TQ = 2 * (7+1) / 16M = 1us (这时则会在CNF1中填入0x07)

接着CNF2当中的bit 7 (BTLMODE)选择1,也就是由CNF3去决定PS2长度

3.SyncSeg固定为1TQ 而PropSeg也选择 1TQ,这时已有2TQ则代表PS1与PS2共为6TQ,希望採样点落在大约60~90%之间,可以选择PS1为3 or 4TQ。

假设为3则是(1+1+3)/8TQ=62.5% ; 4则为(1+1+4)/8TQ = 75%。

4.若选择PS1 = 3TQ则CNF2应该填入0x90

5.根据上方Sync = 1 Prop = 1 PS1 = 3,所以PS2 = 3。这时CNF3可以填入0x02


中断

CANINTE 中断致能暂存器 : 可以选择开启哪一类型中断,0位禁止1为开启。在测试时我们会使用RXB0去做接收,可以开启RXB0接收中断。
http://img2.58codes.com/2024/20146325yuo7PBFwgX.pngCANINTF 中断旗标暂存器 : 当触发中断后会将该对应中断设为1表示出发中断,当处理完后需要手动设置为0清除中断旗标,以RXB0来说当接收完毕讯息需要在手动清0。
http://img2.58codes.com/2024/20146325oMUZakjrPX.png

工作模式

有五种工作模式分别为设置、正常、休眠、监听、环回

当需要对ID Mask Filter做设置时,一定要进入设置模式才可以做修改,修改完毕后需要退出设置模式。手边有两组设备的话可以透过正常模式去做测试与接收,只有一组可以利用环回模式进行测试。

CANCTRL : CAN控制暂存器用来设置工作模式
http://img2.58codes.com/2024/201463255k1WE0y79j.pngCANSTAT : CAN状态暂存器,可以用来查看目前所属工作模式与中断状况
http://img2.58codes.com/2024/20146325j0EpORLWsj.png

SPI 指令

这边介绍几个较常使用的SPI指令,其余可以参考手册当中说明。
http://img2.58codes.com/2024/20146325QvLYHrnTGm.png

Reset : 直接透过SPI发送0xC0即可进入配置模式Read : 可以看到下图优先将CS拉低后,透过MOSI传送0x03(读指令)接着接上要读取的暂存器地址,即可透过MISO获得该暂存器资料。
http://img2.58codes.com/2024/20146325OKTFV3Fcop.pngBYTE WRITE : 向指定暂存器写入一个byte,指令后方接上写入地址与写入资料
http://img2.58codes.com/2024/20146325H84B5fmluT.pngREQUEST-TO-SEND (RTS) :请求发送指令,当资料装载完毕后透过此指令可以发送讯息,其中T2 T1 T0分别为对应3个TxBuffer。
http://img2.58codes.com/2024/20146325wx32Goh7d0.png

这一篇主要介绍MCP2515 如何去做使用以及详细的设置说明,下一篇会介绍如何撰写MCP2515的程式码~
以上参考资料来源 : MCP2515 DataSheet


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章