华恒 ARM9 嵌入式教学实验指导书 第1页,共1页实验十五:SPI 实验+CAN 串行接口总线 通讯实验 一.实验目的 1. 了解 SPI 总线的原理,掌握通过 SPI 总线访问器件的方法; 2. 掌握在 HHARM9-EDU 上的 CAN 总线通讯原理; 3. 学习编程实现 MCP2510 的CAN 总线通讯; 二.实验原理和说明 1. CAN 总线概述 CAN 全称为 Controller Area Network,即控制器局域网,是国际上应用最广泛的现场 总线之一.最初,CAN 总线被设计为汽车环境中的微控制器通讯,在车载的各电子控制装 置ECU 之间交换信息,形成汽车电子控制网络.比如,发动机管理系统、变速箱控制器、 仪表装置和电子主干系统中均嵌入 CAN 控制装置. 一个由 CAN 总线构成的单一网络中,理论上可以挂接无数个节点.但是,实际应用中 节点数目受网络硬件的电气特性所限制. CAN 可提供高达 1Mbit/s 的数据传输速率,这使实时控制变的非常容易.另外,硬件 的错误检测特性也增强了 CAN 的抗电磁干扰能力. 2. CAN 总线技术的应用优点 (1) CAN 网络上的任何一节点均可作为主结点主动地与其他节点交换数据,大大提高了系 统的性能. (2) CAN 网络节点的信息帧可分出优先级,且单帧字节长度短,有很好的实时性. (3) CAN 的物理层及数据链路层采用独特的设计技术,使其在抗干扰、错误检测能力等方面 的性能超过其它总线. (4) CAN 的通信速率相当高.当网络线的长度不超过 40 米时,其通信速率可达 1Mbit/s. (5) CAN 总线每帧数据都包含有 CRC 校验及其他校验措施,数据出错率低. (6) CAN 总线节点在严重错误的情况下,可自动切断与总线的通信联系,以使总线上的其它 操作不受影响. 3.典型系统实现方法图 图3.1 所示的是典型系统实现方法图.在本实验设计中,CAN 控制器用的是 MCP2510 芯片, CAN 收发器用的是 PCA82C251 芯片, 节点控制器是 S3C2410 微处理器, 如图 3.2 所示.MCP2510 芯片具有 SPI 接口,所以先把 SPI 的相关知识介绍一下. 4. S3C2410 的SPI 介绍 SPI(Serial Peripheral Interface)系统是一个同步串行外围接口,允许 MCU 与各种外 华恒 ARM9 嵌入式教学实验指导书 第2页,共2页围设备以串行方式进行通信. S3C2410 微处理器包括两路 SPI, 每一路分别有两个 8 位转移寄存器, 用来发送和接收 数据.在SPI 进行传输时,数据同时发送和接收.如果只想发送数据,接收到的数据将是 无效的;如果只想接收数据,应当发送全是 1 的数据. 图3.1 典型系统实现方法图 图3.2 本实验系统实现方法图 4.1 SPI 引脚介绍 SPI 系统使用四个 I/O 引脚,它们是主机输入/从机输出数据线 MISO;主机输出/从机 输入数据线 MOSI;串行时钟 SCK 和低有效的选择线 SS. (1) 串行数据线(MISO、MOSI) 华恒 ARM9 嵌入式教学实验指导书 第3页,共3页MISO 和MOSI 用于串行接收和发送数据,先为 MSB(高位),后为 LSB(低位).在SPI 设置为主机方式时,MISO 是主机数据输入线,MOSI 是主机数据输出线.在SPI 设置为从机方式时,MISO 变成从机数据输出线,而MOSI 成为从机数据输入线. (2) 从机选择线(SS) 该控制线用来控制从机的打开或者关闭. 在数据传输过程中,一个 SPI 系统充当主机来控制数据流,其它的系统充当从机. 一个主机可以同时转移数据到多个从机,然而,在某一时刻,只能有一个从机向主机发 送数据. 在主模式下,外设选择有两种不同的方法: 固定外设选择:SPI 只和固定的一个外设进行数据交换 可变外设选择:数据能和一个以上外设的进行交换 4.2 SPI 传输模式 S3C2410 支持 4 种不同的数据传输模式,分别如下图所示: 图4.1 0-0 模式 图4.2 0-1 模式 华恒 ARM9 嵌入式教学实验指导书 第4页,共4页图4.3 1-0 模式 图4.4 1-1 模式 MCP2510 芯片支持 0,0 和1,1SPI 模式.这是我们在编程中要特别注意的. 4.3 SPI 寄存器介绍 由于我们准备采用 SPI channel 0,我们将只介绍相应的寄存器. 寄存器 地址 R/W 描述 SPCON0 0x59000000 R/W SPI 通道 0 控制寄存器 SPSTA0 0x59000004 R SPI 通道 0 状态寄存器 SPPIN0 0x59000008 R/W SPI 通道 0 引脚控制寄存器 SPPRE0 0x5900000C R/W SPI 通道 0 波特率寄存器 SPTDAT0 0x59000010 R/W SPI 通道 0 发送数据寄存器 SPRDAT0 0x59000014 R SPI 通道 0 接收数据寄存器 表4.1 SPI 寄存器 华恒 ARM9 嵌入式教学实验指导书 第5页,共5页表4.2 SPI 控制寄存器 表4.3 SPI 状态寄存器 华恒 ARM9 嵌入式教学实验指导书 第6页,共6页表4.4 引脚控制寄存器 表4.5 波特率寄存器 表4.6 发送数据寄存器 表4.7 接收数据寄存器 4.4 SPI 程序流程 (1) (2) (3) 初始化 SPPRE0 寄存器,对波特率进行设置; 设置 SPCON0 寄存器,设置相应的 SPI 模式,这里采用 polling 模式,数据传输模式是 0,0 SPI 模式; 向SPTDAT0 寄存器写 0xFF 十次,为了初始化 MCP2510; 华恒 ARM9 嵌入式教学实验指导书 第7页,共7页(4) (5) (6) (1) (2) (3) (4) (5) (6) (7) 设置 GPIO 引脚,用来充当片选,变低以激活 MCP2510; 发送数据:检查发送状态位 REDY 是否位 1,是就向 SPTDAT0 寄存器写数据; 接收数据: SPCON0 寄存器的 TAGD 不使能(即普通模式) ,向SPTDAT0 寄存器写入 FF,在确 认REDY 后,从读缓存读数据;TAGD 使能,确认 REDY 后,从读缓存读数据,然后 自动的开始发送数据; (7) 设置 GPIO 引脚,信号变高,片选不使能; 5.PCA82C251 芯片介绍 PCA82C251是CAN 协议控制器和物理总线之间的接口.它主要在卡车和公共汽车中 速度达1Mbaud的应用中使用.这个器件向总线提供了差动的发送能力,向CAN 控制器提 供了差动的接收能力. 5.1 PCA82C251 芯片的特性 热保护 在24V系统中防止电池对地的短路 待机模式电流低 不上电的节点不会影响总线线路 至少可以连接110个节点 高速(可达1Mbaud) 对电磁干扰有高的抗干扰性 5.2 PCA82C251 芯片管脚 助记符 管脚 描述 实际接法 TXD 1 发送数据输入 连MCP2510 的TXCAN 引脚 GND 2 地 接地 Vcc 3 电源电压 接5V 电压 RXD 4 接收数据输出 连MCP2510 的RXCAN 引脚 Vref 5 参考电压输出 悬空 CANL 6 输入/输出低电平 CAN 电压 引出 CANH 7 输入/输出高电平 CAN 电压 引出 Rs 8 斜率电阻输入 接地 表5.1 PCA82C251 管脚图 图5.1 管脚配置图 华恒 ARM9 嵌入式教学实验指导书 第8页,共8页图5.2 PCA82C251 原理图 5.3 PCA82C251 功能描述 PCA82C251 是CAN 协议控制器和物理总线之间的接口.它主要在卡车和公共汽车中 速度达1Mbaud的应用中使用.这个器件向总线提供了差动的发送能力,向CAN 控制器提 供了差动的接收能力.它完全符合"ISO 11898-24 V"标准. 一个限流电路可防止发送器的输出级对电池电压的正端和负端短路. 虽然在出现这种故 障条件时功耗将增加,但这种特性可以防止破坏发送器的输出级. 在节点温度超过大约160度时,两个发送器输出端的极限电流将减少.由于发送器是功 耗的主要部分,因此芯片温度会迅速降低.IC 的所有其他部分将继续工作.当总线短路时 尤其需要这个热保护电路. CANH、 CANL两条线也能防止受到在汽车环境下可能发生的电气瞬变现象的影响. 管脚8 Rs可以选择三种不同的工作模式:高速模式、斜率控制模式和待机模式. 在高速工作模式下,发送器输出级晶体管将以尽可能快的速度开、闭.在这种模式下, 不采取任何措施限制上升斜率和下降斜率.建议使用屏蔽电缆以避免射频干扰RFI问题.把 管脚8接地可选择高速模式. 斜率控制模式允许使用非屏蔽双绞线或平行线作为总线.为降低射频干扰RFI,应限制 上升斜率和下降斜率.上升斜率和下降斜率可通过由管脚8接至地的连接电阻进行控制.斜 率正比于管脚8的电流输出. 如果向管脚8加高电平,则电路进入低电流待机模式.在这种模式下,发送器被关闭, 而接收器转至低电流.若在总线上检测到显性位(差动总线电压>0.9V),RXD将变为低电 平.微控制器应通过将收发器切换至正常工作状态(通过管脚8),对此信号作出响应.由 于在待机方式下接收器是慢速的,因此,当位速率很高时,第一个报文将丢失. 由上面的原理图可以看到,我们采用的是高速工作模式. 6. MCP2510 芯片介绍 该部分节选自 MCP2510 芯片手册,主要介绍了一些重要的知识.如果读者感 兴趣,可以参考该手册. 6.1 器件功能介绍 MCP2510是一款独立CAN控制器,是为简化连接CAN总线的应用而开发的.图6.1简 要显示了MCP2510的结构框图.该器件主要由三个部分组成: (1) CAN 协议引擎 (2) 用来为器件及其运行进行配置的控制逻辑和SRAM寄存器 (3) SPI协议模块 华恒 ARM9 嵌入式教学实验指导书 第9页,共9页图6.1 结构框图 CAN 协议引擎的功能是处理所有总线上的报文发送和接收.报文发送时,首先将报文 装载到正确的报文缓冲器和控制寄存器中.利用控制寄存器位,通过SPI 接口或使用发送 使能引脚均可启动发送操作. 通过读取相应的寄存器可以检查通信状态和错误. 任何在CAN 总线上侦测到的报文都会进行错误检测, 然后与用户定义的滤波器进行匹配, 以确定是否将 其转移到两个接收缓冲之一中. MCU 通过SPI 接口与器件进行通信.通过使用标准SPI读写命令对寄存器进行读写操 作. 所提供的中断引脚提高了系统的灵活性. 器件上有一个多用途中断引脚, 以及各接收缓 冲器专用的中断引脚, 以及各接收缓冲器专用的中断引脚, 可用于指示有效报文是否被接收 和载入各接收缓冲器.是否使用专用中断引脚由用户决定,若不使用,也可用通用中断引脚 和状态寄存器(通过SPI 接口访问)确定有效报文是否已被接收. 器件还有三个引脚, 用来将装载在三个发送缓冲器之一中的报文立即发送出去. 是否使 用这些引脚由用户决定,若不使用,也可通过SPI 接口访问控制寄存器的方式来启动报文 发送. 6.2 芯片管脚介绍 图6.2 管脚配置图 在我们的实验中, 并不需要用到所有的引脚, 下面的表格将只对我们用到的引脚进行介 华恒 ARM9 嵌入式教学实验指导书 第10 页,共10 页绍.如果读者想了解其它的引脚信息,请参考该芯片手册. 名称 管脚 描述 实际接法 TXCAN 1 连接到 CAN 总线的发送输出 引脚 接PCA82C251 的TXD 引脚 RXCAN 2 连接到 CAN 总线的接收输入 引脚 接PCA82C251 的RXD 引脚 OCS2 8 振荡器输出 接16MHZ 的晶振 OCS1 9 振荡器输入 接16MHZ 的晶振 Vss 10 逻辑和 I/O 引脚的参考地端 接地 INT 13 中断输出引脚 接GPG13 引脚 SCK 14 SPI 接口时钟输入引脚 接CPU 的SPCK 引脚 SI 16 SPI 接口数据输入引脚 接CPU 的MOSI 引脚 SO 17 SPI 接口输入输出引脚 接CPU 的MISO 脚CS 18 SPI 接口片选输入引脚 接CPU 的GPIO 引脚 RESET 19 低电平有效器件复位输入引 脚接CPU 的TIOB5 引脚 VDD 20 逻辑和 I/O 引脚的正电源 接5V 电压 表6.1 管脚介绍 MCP2510 芯片原理图如下图 6.3 所示. 图6.3 MCP2510芯片原理图 7. CAN 报文帧 MCP2510 支持CAN 2.0B技术规范中所定义的标准数据帧、 扩展数据帧以及远程帧 (标 准和扩展).这里将只介绍标准数据帧和扩展数据帧. (1) 标准数据帧 CAN 标准数据帧如图7.1所示. 与其它所有帧相同, 帧以起始帧(SOF) 位开始. SOF 为 华恒 ARM9 嵌入式教学实验指导书 第11 页,共11 页 显性状态,允许所有节点进行硬同步.在SOF之后是仲裁字段,由12 个位组成,分别为11 个识别位和一个远程发送请求 (RTR) 位.RTR 位用于 区分报文是数据帧 (RTR位为显性) 还是远程帧(RTR位为隐性状态).在仲裁字段之后是控 制字段,由6 个位组成.控制字段的第一位为识别扩展(IDE) 位,该位为显性状态时, 说明这是标准帧.识别扩展位的下一位为零保留位(RB0),这一保留位将由CAN 协议定义 为显性位.控制字段的其余4 位为数据长度码(DLC),说明了报文中包含的数据字节数. 控制字段之后为数据字段, 包含正在发送的数据字节. 数据字段长度由上述数据长度码DLC 定义(0-8字节).数据字段后为循环冗余校验字段(CRC),用来检测报文传输错误.CRC 字段包含一个15位的CRC序列,之后是隐性CRC定界位.最后一个字段是确认字段,由两 个位组成.在确认间隙(ACK slot) 位执行期间,发送节点发出一个接收位.任何收到无错 误帧的节点会发回一个显性位( 无论该节点是否配置为接收该报文与否),确认帧收到无误. 确认字段以隐性确认定界符结束,该字符可能不允许被改写为显性位. 图7.1 标准数据帧 (2) 扩展数据帧 在扩展数据帧中,紧随SOF位的是32位仲裁字段,如图7.2所示.仲裁字段的前11位为 29位标识符的最有效位(基本ID). 紧随这11位的是替换远程请求(SRR)位, 定义为隐性状态. SRR位之后是IDE位,该位隐性时表示这是扩展的CAN帧.应注意的是,如果在扩展帧标识 符的前11位发送完后,总线仲裁无果,而此时仲裁中的节点之一发出标准数据帧(11位标识 符),那么,由于节点发出了显性IDE位而使标准CAN帧赢得总线仲裁.另外,扩展CAN帧的SRR位应为隐性, 以允许正在发送标准CAN远程帧的节点发出显性RTR位. SRR位和IDE 位之后是标识符的其余18位(扩展ID)以及一个远程发送请求位.为使标准帧和扩展帧都 能在共享网络上发送,应将29位的扩展报文标识符拆分成最高11位和最低18位两部分.拆 分后可确保IDE位在标准数据帧和扩展帧中的位置保持不变.仲裁字段之后是6位控制字段. 控制字段前两位为保留位,必须定义为显性位.其余4位为数据长度码(DLC),说明报文中包 含的数据字节数.扩展数据帧的其它部分(数据字段,CRC字段,确认字段,帧结尾和间 断)与标准数据帧的结构相同. 华恒 ARM9 嵌入式教学实验指导书 第12 页,共12 页图7.2 扩展数据帧 8. 报文发送 8.1 发送缓冲器 MCP2510采用三个发送缓冲器.每个发送缓冲器占据14字节的SRAM,并映射到存储 器中.其中第一字节TXBNCTRL是与报文缓冲器相关的控制寄器.该寄存器中的信息决定 了报文在何种条件下被发送,并在报文发送时指示其状态.用5个字节用来装载标准和扩展 标识符以及其它报文仲裁信息.最后8个字节用来装载等待发送的报文的八个可能的数据字 节. 对于可访问报文缓冲器的单片机来说,必须清除TXBNCTRL寄存器TXREQ 位,表明 发送缓冲器无等待发送的报文.至少须将TXBNSIDH、TXBNSIDL 和TXBNDLC寄存器装 载数据.如果报文包含数据字节,还需对TXBNDm寄存器进行装载.若报文采用扩展标识 符,应对TXBNEIDm寄存器进行装载,并将 TXBNSIDL寄存器的EXIDE位置位.在报文发 送之前,单片机应CANINTE寄存器TXINE位进行初始化,以便在报文发送时使能或禁止中 断的产生.MCU还应对TXBNCTRL寄存器的TXP优先级控制位进行初始化. 8.2 发送优先级 发送优先级是指MCP2510内部等待发送报文之间的优先级.它与CAN协议中固有的报 文仲裁的优先级无关.在发送起始帧SOF之前,器件将所有等待发送报文的发送缓冲器的 优先级进行比较.具有较高优先级的发送缓冲器将首先发送.例如,如果发送缓冲器0的优 先级设定比发送缓冲器1高,缓冲器0将首先发送.如果两个缓冲器的优先级相同,编号较 高的发送缓冲器将优先发送.例如,如果发送缓冲器1与发送缓冲器0的优先级设定相同, 缓冲器1将优先发送.发送优先级的设定共有4个等级.如果某个发送缓冲器的TXBNCTRL 寄存器的TXP<1:0> 设定为11,该发送缓冲器具有最高的发送优先级.如果TXBNCTRL寄 存器的TXP<1:0> 设定为00,该发送缓冲的发送优先级最低. 8.3 发送启动 通过设定控制寄存器中TXBNCTRL寄存器的TXREQ发送控制位可以启动相应发送缓 冲器的报文发送.通过SPI接口写寄存器或向某一发送缓冲器TXNRTS 引脚输入低电平可 以进行设定.如果选择SPI接口方式进行位设定以启动报文发送,可以同时设定TXREQ位和TXP优先级控制位.当TXBNCTRL寄存器TXREQ 置位后,TXBNCTRL寄存器ABTF, TXBNCTRL寄存器的MLOA位和TXERR位都将被清除. 将TXBNCTRL寄存器的TXREQ位置位并不能启动报文发送,仅将发送缓冲器标记为准 备发送.当器件检测到总线空闲时,才会启动报文发送.优先级最高的报文将首先发送. 报文发送成功后,TXBNCTRL寄存器的TXREQ位将被清除,CANINTF寄存器的TXNIF 位将被置位,置位后将产生中断.如果报文发送失败,TXBNCTRL寄存器的TXREQ将保持 置位,表明该报文仍在等待发送.此时以下条件标志之一将被置位.如果报文发送已开始但 发生错误,TXBNCTRL寄存器的TXERR和CANINTF寄存器的MERRF位将被置位,此时 在CANINTE寄存器的MERRE位置位后,器件将会在INT引脚产生中断.若发送报文总线仲 裁失败,TXBNCTRL寄存器的MLOA位将被置位.发送流程图如下: 华恒 ARM9 嵌入式教学实验指导书 第13 页,共13 页图8.1 报文发送流程图 8.4 寄存器介绍 华恒 ARM9 嵌入式教学实验指导书 第14 页,共14 页图8.2 TXBNCTRL 发送缓冲器N 控制寄存器 图8.3 TXBNSIDH 发送缓冲器N 标准标识符高位 图8.4 TXBNSIDL 发送缓冲器N 标准标识符低位 华恒 ARM9 嵌入式教学实验指导书 第15 页,共15 页图8.5 TXBNEID8 发送缓冲器N 扩展标识符高位 图8.6 TXBNEID0 发送缓冲器N 扩展标识符低位 图8.7 TXBNDLC 发送缓冲器N 数据长度码 图8.8 发送缓冲器寄存器 9. 报文接收 9.1 报文接收缓冲器 MCP2510具有两个全文接收缓冲器.每个接收缓冲器配备有多个验收滤波器.除上述 专用接收缓冲器外,MCP2510还具有单独的报文集成缓冲器(MAB),可作为第三个接收缓 冲器,如图9.1所示. 华恒 ARM9 嵌入式教学实验指导书 第16 页,共16 页图9.1 接收缓冲器原理图 9.2 接收缓冲器 在三个接收缓冲器中,MAB总能够接收来自总线的下一条报文.其余两个接收缓冲器 RXB0和RXB1则从协议引擎接收完整的报文.当其中一个缓冲器处于接收等待或保存着上 一条接收到的报文时,MCU可对另一缓冲器进行访问. MAB对接收到的报文进行组合,并将满足验收滤波器条件的报文传送到至RXBN缓冲 器. 当报文传送至某一接收缓冲器,与该接收缓冲器对应的CANINTF寄存器的RXNIF位将 置1.一旦缓冲器中的报文处理完毕,MCU就必须将该位清除以接收下一条报文. 该控制 位提供的锁定功能确保在MCU尚未处理完上一条报文前, MCP2510不会将新的报文载入 接收缓冲器.如果CANINTE寄存器的RXNIE位被置1,器件会在INT引脚产生一个中断, 显 示接收到有效报文. 9.3 接收优先级 RXB0是具有较高优先级的寄存器, 并配置有2个报文验收滤波寄存器.RXB1优先级较 低,配置有4个验收滤波器寄存器.RXB0的验收滤波寄存器数量较少,因此RXB0接受匹配 条件更为严格,表明RXB0具有较高的优先级.此外通过配置RXB0CTRL寄存器,还可以实 现以下功能:如果RXB0中装有上一条有效报文,而另一条报文也正被接收,该项设置将避 华恒 ARM9 嵌入式教学实验指导书 第17 页,共17 页 免发生溢出错误.无论新的报文是否符合RXB1验收条件,都将被滚存至RXB1.每个接收 缓冲器还分别配置有一个可编程验收滤波屏蔽寄存器(见第6.5.4节). 当报文被接收时,RXBNCTRL 寄存器的<3:0>位状态将显示使能该接收操作的验收滤 波器的编号, 以及接收到的报文是否为远程传输请求.通过RXBNCTRL寄存器的RXM位可 以设定特殊接收工作模式.该位通常设置为00,以接收所有被验收滤波器器认可的报文. 在这种情况下, 标准或扩展帧报文的接收与否取决于验收滤波寄存器中RFXNSIDL寄存器的 EXIDE控制位的状态.如果RXBNCTRL寄存器的RXM设定值为01或10,接收缓冲器将分别 只接收标准帧或扩展帧.如果验收滤波寄存器RFXNSIDL中的EXIDE位的设置不对应于 RXBNCTRL寄存器的RXM工作模式, 验收滤波器将不起作用. 上述两种由RXBNCTRL寄存 器的RXM控制位决定的接收模式可以应用在总线上只有标准帧或扩展帧的系统中.如果 RXBNCTRL寄存器的RXM位设置为11,无论验收滤波器的设置值是什么, 缓冲器都将接收 所有报文.如果报文在帧结束前出错,在MAB中组合的出错前的那部分报文将被移入缓冲 器.该工作模式可在CAN系统调试时使用,一般不在实际系统环境中使用. 9.4 报文验收滤波器及屏蔽寄存器 验收滤波器及屏蔽寄存器用来确定报文集成缓冲器中的报文是否应被载入接收缓冲器. 一旦MAB接收到有效报文,报文中的标识符字段将与过滤寄存器 中的值进行比较.如果两者匹配,该报文将被载入相应的接收缓冲器.滤波屏蔽寄存器用来 确定滤波器对标识符中的哪些位进行校验.表9.1所示的真值表显示了标识符中每一位是如 何与验收屏蔽器和滤波器进行比较, 以确定该报文是否应被载入接收缓冲器. 屏蔽寄存器主 要确定对标识符中的哪一位进行滤波. 如果某屏蔽位设置为零, 对应的标识符位将被自动接 收而不被滤波. 屏蔽位 n 过滤位 n 报文标识符位 n001 接收或拒绝位 n 0 X X 接受 1 0 0 接受 1 0 1 拒绝 1 1 0 拒绝 1 1 1 接受 表9.1 滤波/屏蔽寄存器真值表(X 可为任意值) RXB0接收缓冲器配备有验收滤波寄存器RXF0和RXF1, 以及过滤屏蔽寄存器RXM0. RXB1配备有验收滤波寄存器RXF2、RXF3、RXF4和RXF5以及滤波屏蔽寄存器RXM1.当 新报文符合验收滤波条件并被载入接收缓冲器时, 使能报文接收的滤波器编号将被装载到 RXBNCTRL寄存器FILHIT位中.对于RXB1, RXB1CTRL寄存器包含FILHIT<2:0>位. 华恒 ARM9 嵌入式教学实验指导书 第18 页,共18 页图9.2 报文接收流程图 如果接收报文符合一个以上滤波寄存器的接受条件,FILHIT位中的二进制代码将反映 其中编号最小的寄存器.例如,如果滤波器RXF2和RXF4同时与接收报文匹配,FILHIT中 将装载RXF2编码值. 这实际上为编号较小的验收滤波寄存器赋予较高的优先级.接收报 文将按照编号上升的原则依次与滤波寄存器进行匹配比较. 只有MCP2510处于配置模式时, 华恒 ARM9 嵌入式教学实验指导书 第19 页,共19 页 才能对屏蔽和滤波寄存器中的内容进行修改.报文接收流程图见图9.2. 9.5 寄存器介绍 图9.3 RXB0CTRL 接收缓冲器0 控制寄存器 图9.4 RXB1CTRL 接收缓冲器1 控制寄存器 华恒 ARM9 嵌入式教学实验指导书 第20 页,共20 页图9.5 RXBNSIDH 接收缓冲器N 标准标识符高位 图9.6 RXBNSIDL 接收缓冲器N 标准标识符低位 图9.7 RXBNEID8 接收缓冲器N 扩展标识符中间位 图9.8 RXBNEID0 - 接收缓冲器N 扩展标识符低位 图9.9 RXBNDLC 接收缓冲器N 数据长度码 华恒 ARM9 嵌入式教学实验指导书 第21 页,共21 页图9.10 RXBNDM 接收缓冲器N 数据字段字节M 图9.12 RXFNSIDH 验收滤波寄存器N 标准标识符的高位 图9.13 RXFNSIDL 验收滤波寄存器N 标准标识符的低位 图9.14 RXFNEID8 验收滤波器N 扩展标识符的高位 图9.15 RXFNEID0 验收滤波寄存器N 扩展标识符的低位 华恒 ARM9 嵌入式教学实验指导书 第22 页,共22 页图9.16 RXMNSIDH 验收滤波屏蔽寄存器N 标准标识符的高位 图9.17 RXMNSIDL 验收滤波屏蔽寄存器N 标准标识符低位 图9.18 RXMNEID8 验收滤波屏蔽寄存器N 扩展标识码的高位 图9.19 RXMNEID0 接受屏蔽寄存器N 扩展标识符的低位字节 10. 位定时 10.1 位定时配置寄存器 CAN总线接口的位定时由配置寄存器(CNF1,CNF2,CNF3)控制.只有当MCP2510 处于配置模式时,才能对这些寄存器进行修改. 下面对这三个寄存器简单的进行介绍: 华恒 ARM9 嵌入式教学实验指导书 第23 页,共23 页图10.1 CNF1 配置寄存器1 图10.2 CNF2 配置寄存器2 图10.3 CNF3 配置寄存器 3 11. 错误检测 略. 12. 中断 该器件具有8个中断源. CANINTE 寄存器中包含了使能各个中断源的中断使能控制位. CANINTF寄存器中包含了各个中断源的中断标志位.当有中断请求发生,INT引脚将置为低 电平,并维持低电平状态直至MCU清除中断标志.中断标志只有在引起相应中断请求条件 华恒 ARM9 嵌入式教学实验指导书 第24 页,共24 页 消失后,才能被清除.建议在对CANINTF 寄存器中的中断标志位进行复位操作时,采用位 修改命令而不要使用普通的写操作. 这是为了避免在写命令执行中无意间修改了标志位, 从 而导致中断请求信号的丢失.应注意, CANINTF中的中断标志位为可读写位,因此在相关 CANINTE中断使能位置1的前提下,对上述任何一位进行置位均可使MCU产生中断请求. 12.1 发送中断 在发送中断使能(CANINTE.TXNIE = 1)的条件下,如果相关发送缓冲器空并处于新 报文装载就绪状态时, 器件会在INT引脚产生中断请求信号. CANINTF.TXNIF发送中断标志 位将被置位以显示中断源.MCU通过将TXNIF位置0来清除中断. 12.2 接收中断 在接收中断使能(CANINTE.RXNIE = 1)的条件下,如果报文成功接收并被载入相关 接收缓冲器时,器件会在INT引脚产生中断请求信号.在接收到EOF 字段后,该中断立即 被激活.CANINTF.RXNIF接收中断标志位将被置位以显示中断源.MCU通过将RXNIF位复 位来清除中断. 12.3 报文错误中断 如果报文发送和接收过程中出现错误,报文出错标志(CANINTF.MERRF)将被置1, 此时若相应的CANINTE.MERRE中断使能位也被置1, 器件将在INT引脚产生中断请求信号. 该中断功能在与只听模式联用时被用来加快波特率的确定. 12.4 中断确认 中断与CANINTF寄存器中的一个或多个状态标志直接相关. 只要其中一个标志位置位, 所有中断就将保持等待发送状态.一旦器件设置了中断标志,在中断条件消除之前MCU将 不能将其复位. 12.5 错误中断 在错误中断使能时(CANINTE.ERRIE = 1),如果发生溢出或发送/ 接收节点的状态 发生改变,器件将在INT引脚产生中断请求.错误标志寄存器(EFLG)将会显示以下错误 中断状况之一. (1) 接收缓冲器溢出 (2) 接收节点警告 (3) 发送节点警告 (4) 接收节点错误消极模式 (5) 发送节点错误消极模式 (6) 总线关闭模式 12.6 中断寄存器 华恒 ARM9 嵌入式教学实验指导书 第25 页,共25 页图12.1 中断使能寄存器 华恒 ARM9 嵌入式教学实验指导书 第26 页,共26 页图12.2 中断标志寄存器 13. 时钟振荡器 MCP2510设计使用晶体振荡器或陶瓷振荡器作为时钟振荡器,它们应连接在OSC1和OSC2引脚上.MCP2510的振荡器设计要求选用并联切割晶体振荡器.若使用串联晶振, 其产生的时钟频率可能超出厂商规定值.图13.1显示了一个典型时钟振荡器电路. 图13.1 振荡电路图 14. 工作模式 MCP2510 具有 5 种工作模式,分别为: (1) 配置模式 (2) 正常模式 (3) 睡眠模式 (4) 监听模式 (5) 环回模式 通过设定CANCTRL寄存器的REQOP位,可选择工作模式.改变工作模式时,新的工 作模式需等到所有报文传输完毕之后才能生效. 因此在运行另一种模式之前, 用户在进行下 一步操作时应先确认器件是否已进入该工作模式.通过读取CANSTAT寄存器的OPMODE 位可以查验当前工作模式. (1) 配置模式 正常运行之前,必须对MCP2510 进行初始化.只有在配置模式下,才能对器件进行初 始化.在初始上电或复位时,器件自动进入配置模式.将CANTRL寄存器的REQOP 设置 为'100' 也可以使器件进入配置模式.当进入配置模式时,所有错误计数器将被清零.只有 在配置模式下,才能对下列的寄存器进行修改. (a) CNF1, CNF2, CNF3 (b) TXRTSCTRL (c) 接收滤波寄存器 (d) 接收屏蔽寄存器 只有当CANSTAT寄存器OPMODE读数为'100' 时,才能进行初始化操作,并对配置寄 存器,接收过滤寄存器以及接收屏蔽寄存器进行写操作.配置完成之后,可以通过设定 CANCTRL寄存器的REQOP位以使器件进入正常工作模式(或其他工作模式). (2) 正常模式 该模式为MCP2510标准工作模式.该模式下,器件主动监视总线上的所有报文,并产 生确认位和错误帧等.只有在正常工作模式下,MCP2510才能在CAN 总线上进行报文的 华恒 ARM9 嵌入式教学实验指导书 第27 页,共27 页 传输. (3) 睡眠模式(略) (4) 监听模式(略) (5) 回环模式 该模式可使器件内部发送缓冲器和接收缓冲器之间进行报文自发自收,而无须通过 CAN 总线.该模式可用于系统研发和测试.回环模式下应答位ACK无效,器件接收自己发 送的报文就如同接收来自其它节点的报文. 回环模式是一个静音模式, 即器件不能通过总线 发送包括错误标志或确认信号在内的任何报文.在该模式下,器件的TXCAN引脚处于隐性 状态. 可通过设定滤波器和屏蔽器以接收特定的报文. 也可以将滤波屏蔽位全部置零来接收 所有的报文.通过设定CANCTRL寄存器中的模式请求位可激活回环模式. 图14.1 CANCTRL CAN 控制寄存器 华恒 ARM9 嵌入式教学实验指导书 第28 页,共28 页图14.2 CANSTAT CAN 状态寄存器 15. 寄存器映射表 图15.1 寄存器映射表 从该表可以看出,第一列、第二列主要是验收滤波寄存器;第三列前 8 个寄存器是验 收滤波屏蔽寄存器;第四、五、六列分别是发送缓冲区 0、1、2;第七、八列分别是接收缓 冲区 0、1.该表可以很清晰的看出 MCP2510 的全部寄存器的分布情况. 16. MCP2510 的SPI 接口 MCP2510设计可与许多微控制器的串行外设接口(SPI)直接相连,支持0,0 和1,1 运 行模式. 外部数据和命令通过SI引脚传送到器件中, 而数据在SCK时钟信号的上升沿传送进 去.MCP2510在SCK下降沿通过SO引脚发送.表列出了所有操作的指令字节. 华恒 ARM9 嵌入式教学实验指导书 第29 页,共29 页表16.1 SPI指令集 (1) 读指令 在读操作开始时,CS引脚将被置为低电平.随后读指令和8位地址码(A7至A0)将被 依次送入MCP2510.在接收到读指令和地址码之后,MCP2510指定地址寄存器中的数据将 被移出通过SO引脚进行发送. 每一数据字节移出后, 器件内部的地址指针将自动加1以指向 下一地址. 因此可以对下一个连续地址寄存器进行读操作. 通过该方法可以顺序读取任意个 连续地址寄存器中的数据.通过拉高CS引脚电平可以结束读操作,见图16.1. (2) 字节写指令 置CS引脚为低电平启动写操作.启动写指令后,地址码以及至少一个字节的数据被依 次发送到MCP2510. 只要CS保持低电平, 就可以对连续地址寄存器进行顺序写操作. 在SCK 引线上的上升沿,数据字节将从D0位开始依次被写入.如果CS引脚在字节的8位数据尚未 发送完之前跳变到高电平,该字节的写操作将被中止,而之前发送的字节已经写入.有关详 细的字节写操作时序请参见图16.2. 图16.1 读指令 图16.2 字节写指令 (3) 请求发送指令 使用RTS命令可以启动一个或多个发送缓冲器的报文发送.置某器件的CS为低电平选 华恒 ARM9 嵌入式教学实验指导书 第30 页,共30 页 择该器件,之后RTS命令字节会被发送给MCP2510.如图15.3 所示,该命令的最后3位显 示了被使能发送的缓冲器编号.执行该命令后相应缓冲器的TxBnCTRL寄存器的TXREQ位 被置1.用一条RTS命令即可对这三位中的一位或全部三位进行设定.如果发送的RTS命令 中nnn = 000,该命令将被视为无效. 图16.3 请求发送指令 (4) 状态读指令 状态读指令允许单条指令对一些常用的报文接收和发送状态位进行访问. 置某器件的CS为低电平选择该器件, 如图15.4所示, 状态读命令字节将被发送给MCP2510. 命令字节发出后, MCP2510将发回一个包含状态信息的8位数据. 在发送完最初8位数据之后,如果还有时钟信号发出,只要CS引脚保持低电平并且时钟信号 是通过SCK引脚提供的,MCP2510将继续发送状态位.该命令中发回 的每个位的状态也可通过带相应寄存器地址的标准读命令读取. 图16.4 状态读指令 (5) 位修改指令 位修改命令提供了一种对特定控制和状态寄存器中单独的位进行设定和清除的方法. 该 命令并非对所有寄存器都有效.允许进行位修改的寄存器(寄置某器件的CS为低电平选择 该器件,之后位修改命令字节会被发送给MCP2510.命令字节发送后,寄存器地址,屏蔽 字节以及数据字节被依次发出.屏蔽字节决定寄存器中的哪一位将被修改.屏蔽字节中的1 表示允许对寄存器相应的位进行修改,0则禁止修改.数据字节确定寄存器位修改后的最终 结果.如果屏蔽字节相应位设置为1,数据字节中的1表示将对寄存器对应位置1,而0则将 华恒 ARM9 嵌入式教学实验指导书 第31 页,共31 页 对该位清零. 图16.5 位修改指令\ (6) 复位指令 图16.6 复位指令 17. 一些注意事项 (1) MCP2510 只支持 SPI 0,0 和1,1 模式; (2) 片选接在 GPG14 处,中断接在 GPG13 引脚,对应的是中断 21; (3) 我们在下面的实验里,发送用发送寄存器 0,接收用接收寄存器 1; (4) 下面我们将详细介绍三个实验,前一个实验是后一个实验的基础,也是我们进行调试 CAN 的一个最基本的过程.第一个实验是关于 SPI 驱动的,我们在这个实验中通 过SPI 驱动对 MCP2510 进行读写操作, 以检测 SPI 驱动是否编写正确; 第二个实验是 用MCP2510 的回环模式对编写的程序进行检测,以检测发送、接收程序是否正确;第 三个实验是两个板子之间进行通讯. (5) 这三个实验的文件有 mcp2510.c 和mcp2510.h, 在该头文件里, 定义了所有 MCP2510 的寄存器的地址,下面我们将只介绍 mcp2510.c 文件. 18. 程序解读(实验一) 我们介绍该实验的主要函数: (1) address_map 函数,把寄存器的物理地址映射到内核空间地址; (2) spi_poll_done 函数,判断 SPI 传输是否结束; (3) spi_tx_data 函数,进行 SPI 数据传输; (4) Write_2510 函数,通过 SPI 对CAN 的一个寄存器进行写操作; (5) Read_2510 函数,通过 SPI 对CAN 的一个寄存器进行读操作; 华恒 ARM9 嵌入式教学实验指导书 第32 页,共32 页(6) Reset_2510 函数,通过 SPI 对CAN 进行复位操作; (7) Modify_2510 函数,通过 SPI 对CAN 的一个寄存器进行位修改操作; (8) Init_MCP2510 函数,驱动初始化程序; (9) Exit_MCP2510 函数,驱动结束程序; (10) Init_SPI 函数,初始化 SPI; (11) Test 函数,实验一要实现的程序; 下面我们分别对上面的函数进行介绍: (1) address_map 函数: // SPI 寄存器 r_SPCON0 = ioremap(0x59000000,4); r_SPSTA0 = ioremap(0x59000004,4); r_SPPIN0 = ioremap(0x59000008,4); r_SPPRE0 = ioremap(0x5900000C,4); r_SPTDAT0 = ioremap(0x59000010,4); r_SPRDAT0 = ioremap(0x59000014,4); //I/O 寄存器充当 SPI 引脚 r_GPECON = ioremap(0x56000040,4); r_GPEUP = ioremap(0x56000048,4); //片选寄存器 r_GPGCON = ioremap(0x56000060,4); r_GPGUP = ioremap(0x56000068,4); r_GPGDAT = ioremap(0x56000064,4); (2) spi_poll_done 函数: int nCount = 0; while(!(rSPSTA0 & 0x01) ) //判断 SPI 发送寄存器是否准备好 { nCount++; if(nCount>=5000) { printk("SPI state poll failed\n"); break; } }//endwhile (3) spi_tx_data 函数: spi_poll_done(); rSPTDAT0 = data; // 通过 SPI,发送数据 spi_poll_done(); (4) Read_2510 函数: 华恒 ARM9 嵌入式教学实验指导书 第33 页,共33 页unsigned char buffer; rGPGDAT &=(~0x4000); //选中该芯片 udelay(100000); //进行延迟,以确保确实选中,这是必须的 spi_tx_data(CMD_READ); //参见 16 节图 1 spi_tx_data(R_ADD); //所读寄存器的地址 spi_tx_data(0xff); //发送 0xff 读该寄存器数据 buffer = rSPRDAT0; rGPGDAT |=0x4000; //不选中该芯片 return buffer; (5) Init_SPI 函数: int i; rSPPRE0 = 0xff; //设置 SPI 波特率 rSPCON0 = 0x18; //设置为查询方式 for(i = 0 ; i < 10 ; i++) { rSPTDAT0 = 0xff; }//初始化设备 rGPECON |= 0x0a800000; //设置 SPI 的三个引脚 rGPECON &= (~0x05400000); rGPEUP |= 0x3800; rGPGCON |= 0x10000000;//设置 GPG14 引脚为输出 rGPGCON &= (~0x20000000); rGPGUP &= (~0x4000); rGPGDAT |=0x4000; //不选中该芯片 (6) Init_MCP2510 函数: //设置中断 //Set Interrupt set_external_irq(IRQ_EINT21, EXT_FALLING_EDGE, GPIO_PULLUP_DIS); gpfup = ioremap(0x56000068,4); (*(volatile unsigned long *)gpfup) = 0; disable_irq(IRQ_EINT21); enable_irq(IRQ_EINT21); result = request_irq(IRQ_EINT21,&can_interrupt,SA_INTERRUPT,"can",NULL); if (result) { 华恒 ARM9 嵌入式教学实验指导书 第34 页,共34 页printk("Can't get assigned irq %d,result=%d\n",IRQ_EINT21,result); return result; } //注册设备 mcp2510_devfs_dir = devfs_mk_dir(NULL,"CAN",NULL); devfs_register(mcp2510_devfs_dir,DEVICE_NAME,DEVFS_FL_AUTO_DEVNUM,0,0,S_ IFCHR|S_IRUGO|S_IWUGO,&mcp2510_fops,NULL); printk ("MCP2510 driver installed OK\n"); printk(1\n"); printk("Initialize SPI\n"); address_map(); //寄存器地址映射 Init_SPI(); //初始化 SPI spi_tx_data(0xff);//初始化该芯片 spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); #ifdef DEBUG_SPI1 //因为这是实验一,所以写 DEBUG_SPI1,不进行编译 printk(2\n"); printk("Initialize MCP2510\n"); Init_MCP2510(); #endif #ifdef DEBUG_SPI //在前面定义了 DEBUG_SPI,所以下面的代码有效 printk(2\n"); printk("Test Funciton 1\n"); Test(); #endif (7) mcp2510_exit 函数: //Disable Interrupt disable_irq(IRQ_EINT21); free_irq(IRQ_EINT21, NULL); 华恒 ARM9 嵌入式教学实验指导书 第35 页,共35 页devfs_unregister(mcp2510_devfs_dir); printk ("MCP2510 driver uninstalled OK\n"); (8) Test 函数: unsigned char buffer[5]; //Reset MCP2510 Reset_2510(); //设置系统为配置模式 Modify_2510(CANCTRL, 0xe0, 0x80); Modify_2510(CANCTRL, 0x07, 0x00); //设置 CNF 寄存器 Write_2510(CNF1,0x07); Write_2510(CNF2,0x10); Write_2510(CNF3,0x02); Write_2510(RXB0CTRL,0x60); //读寄存器 buffer[0] = Read_2510(CANSTAT); buffer[1] = Read_2510(CNF1); buffer[2] = Read_2510(CNF2); buffer[3] = Read_2510(CNF3); buffer[4] = Read_2510(RXB0CTRL); printk("The CANSTAT register is %x\n",buffer[0]); printk("The CNF1 register is %x\n",buffer[1]); printk("The CNF2 register is %x\n",buffer[2]); printk("The CNF3 register is %x\n",buffer[3]); printk("The RXB0CTRL register is %x\n",buffer[4]); 19. 程序解读(实验二) 上面已经介绍的函数我们这里将省略, 这里只介绍该实验中用到的并且和上面的实验不 同的函数. (1) Test_can_bus 函数,测试在回环模式下的收发; (2) send_test_frame 函数,发送样本数据,调用 can_data_send 函数; (3) can_data_send 函数,发送数据到总线; (4) can_data_receive 函数,接收总线上的数据; (5) can_interrupt 函数,中断处理函数; (6) Init_MCP2510 函数,初始化 MCP2510; 下面对这些函数分别进行说明: (1) Test_can_bus 函数: unsigned char buffer; 华恒 ARM9 嵌入式教学实验指导书 第36 页,共36 页int i; //设置进入回环模式 Modify_2510(CANCTRL,0xe0,0x40); //Read the Mode buffer = Read_2510(CANSTAT); printk("The CANSTAT register is %x\n",buffer); //发送样本数据 printk("Transmit the sample data\n"); send_test_frame(); //等待进入中断,读取接收到的数据 while(1) { if(flag == 0xff) //判断是否接收到数据 { for(i = 0;i < 8;i++) printk("Rxdata[%d] is %c\n",i,RXdata[i]); break; } }//endwhile (2) send_test_frame 函数: TXdata[0] = 0xa0; //这个是发送数据的标志符 TXdata[1] = 0x00; TXdata[2] = 0x08; //发送数据的长度 TXdata[3] = 'A' ; TXdata[4] = 'B' ; TXdata[5] = 'C' ; TXdata[6] = 'D' ; TXdata[7] = 'E' ; TXdata[8] = 'F' ; TXdata[9] = 'G' ; TXdata[10]= 'H' ; can_data_send(); //发送数据到总线 (3) can_data_send 函数: unsigned char length,i; length = TXdata[2]; Write_2510(TXB0SIDH,TXdata[0]); Write_2510(TXB0SIDL,TXdata[1]); 华恒 ARM9 嵌入式教学实验指导书 第37 页,共37 页Write_2510(TXB0DLC, TXdata[2]); rGPGDAT &=(~0x4000); //选中该芯片 udelay(100000); spi_tx_data(CMD_WRITE); spi_tx_data(TXB0D0); for(i = 0; i
-
spi总线速率 总线的传输速率计算 can总线传输速率 spi总线 spi总线协议 spi总线协议详解 spi总线协议规范 spi总线时序图 spi总线程序下载 spi总线接口