做网站都是需要什么备案 个人网站建设方案书
web/
2025/10/5 1:21:31/
文章来源:
做网站都是需要什么,备案 个人网站建设方案书,wordpress 插件 慢,马克·扎克伯格大学做的网站SPI概述Serial Peripheral interface 通用串行外围设备接口是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM#xff0c;FLASH#xff0c;实时时钟#xff0c;AD转换器#xff0c;还有数字信号处理器和数字信号解码器之间。SPI#xff0c;是一种高…SPI概述Serial Peripheral interface 通用串行外围设备接口是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROMFLASH实时时钟AD转换器还有数字信号处理器和数字信号解码器之间。SPI是一种高速的全双工同步的通信总线并且在芯片的管脚上只占用四根线节约了芯片的管脚同时为PCB的布局上节省空间。SPI特点采用主-从模式(Master-Slave) 的控制方式SPI 规定了两个 SPI 设备之间通信必须由主设备 (Master) 来控制次设备 (Slave). 一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备, SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作。而这里的SPI中的时钟和相位指的就是SCLk时钟的特性即保证主从设备两者的时钟的特性一致了以保证两者可以正常实现SPI通讯。采用同步方式(Synchronous)传输数据Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) , 时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的. 工作机制概述首先看下SPI Data Transfer模块图。 上图只是对 SPI 设备间通信的一个简单的描述, 下面详细解释一下图中所示的几个组件(Module):SSPBUFSynchronous Serial Port Buffer, 泛指 SPI 设备里面的内部缓冲区, 一般在物理上是以 FIFO 的形式, 保存传输过程中的临时数据;我们知道, 在每个时钟周期内, Master 与 Slave 之间交换的数据其实都是 SPI 内部移位寄存器从 SSPBUF 里面拷贝的. 我们可以通过往 SSPBUF 对应的寄存器 (Tx-Data / Rx-Data register) 里读写数据, 间接地操控 SPI 设备内部的 SSPBUF。例如, 在发送数据之前, 我们应该先往 Master 的 Tx-Data 寄存器写入将要发送出去的数据, 这些数据会被 Master-SSPSR 移位寄存器根据 Bus-Width 自动移入 Master-SSPBUF 里, 然后这些数据又会被 Master-SSPSR 根据 Channel-Width 从 Master-SSPBUF 中移出, 通过 Master-SDO 管脚传给 Slave-SDI 管脚, Slave-SSPSR 则把从 Slave-SDI 接收到的数据移入 Slave-SSPBUF 里. 与此同时, Slave-SSPBUF 里面的数据根据每次接收数据的大小(Channel-Width), 通过 Slave-SDO 发往 Master-SDI, Master-SSPSR 再把从 Master-SDI 接收的数据移入 Master-SSPBUF.在单次数据传输完成之后, 用户程序可以通过从 Master 设备的 Rx-Data 寄存器读取 Master 设备数据交换得到的数据。SSPSRSynchronous Serial Port Register, 泛指 SPI 设备里面的移位寄存器(Shift Regitser), 它的作用是根据设置好的数据位宽(bit-width) 把数据移入或者移出 SSPBUF;SSPSR 是 SPI 设备内部的移位寄存器(Shift Register). 它的主要作用是根据 SPI 时钟信号状态, 往 SSPBUF 里移入或者移出数据, 每次移动的数据大小由 Bus-Width 以及 Channel-Width 所决定。 Bus-Width 的作用是指定地址总线到 Master 设备之间数据传输的单位. 例如, 我们想要往 Master 设备里面的 SSPBUF 写入 16 Byte 大小的数据: 首先, 给 Master 设备的配置寄存器设置 Bus-Width 为 Byte; 然后往 Master 设备的 Tx-Data 移位寄存器在地址总线的入口写入数据, 每次写入 1 Byte 大小的数据(使用 writeb 函数); 写完 1 Byte 数据之后, Master 设备里面的 Tx-Data 移位寄存器会自动把从地址总线传来的1 Byte 数据移入 SSPBUF 里; 上述动作一共需要重复执行 16 次。Channel-Width 的作用是指定 Master 设备与 Slave 设备之间数据传输的单位. 与 Bus-Width 相似, Master 设备内部的移位寄存器会依据 Channel-Width 自动地把数据从 Master-SSPBUF 里通过 Master-SDO 管脚搬运到 Slave 设备里的 Slave-SDI 引脚, SlaveSSPSR 再把每次接收的数据移入 Slave-SSPBUF里.通常情况下, Bus-Width 总是会大于或等于 Channel-Width, 这样能保证不会出现因 Master 与 Slave 之间数据交换的频率比地址总线与 Master 之间的数据交换频率要快, 导致 SSPBUF 里面存放的数据为无效数据这样的情况Controller泛指 SPI 设备里面的控制寄存器, 可以通过配置它们来设置 SPI 总线的传输模式。 通常情况下, 我们只需要对上图所描述的四个管脚(pin) 进行编程即可控制整个 SPI 设备之间的数据通信。 Master 设备里面的 Controller 主要通过时钟信号(Clock Signal)以及片选信号(Slave Select Signal)来控制 Slave 设备. Slave 设备会一直等待, 直到接收到 Master 设备发过来的片选信号, 然后根据时钟信号来工作。Master 设备的片选操作必须由程序所实现. 例如: 由程序把 SS/CS 管脚的时钟信号拉低电平, 完成 SPI 设备数据通信的前期工作; 当程序想让 SPI 设备结束数据通信时, 再把 SS/CS 管脚上的时钟信号拉高电平.SCKSerial Clock, 主要的作用是 Master 设备往 Slave 设备传输时钟信号, 控制数据交换的时机以及速率;SS/CSSlave Select/Chip Select, 用于 Master 设备片选 Slave 设备, 使被选中的 Slave 设备能够被 Master 设备所访问。SDO/MOSISerial Data Output/Master Out Slave In, 在 Master 上面也被称为 Tx-Channel, 作为数据的出口, 主要用于 SPI 设备发送数据。SDI/MISOSerial Data Input/Master In Slave Out, 在 Master 上面也被称为 Rx-Channel, 作为数据的入口, 主要用于SPI 设备接收数据。SPI 设备在进行通信的过程中, Master 设备和 Slave 设备之间会产生一个数据链路回环(Data Loop), 就像上图所画的那样, 通过 SDO 和 SDI 管脚, SSPSR 控制数据移入移出 SSPBUF, Controller 确定 SPI 总线的通信模式, SCK 传输时钟信号。极性和相位要想搞清楚SPI的数据传输首先要搞清楚相位和极性的概念即SPI的极性Polarity和相位Phase。最常见的写法是CPOL和CPHA不过也有一些其他写法简单总结如下(1) CKPOL (Clock Polarity) CPOL POL Polarity 时钟极性(2) CKPHA (Clock Phase) CPHA PHA Phase 时钟相位(3) SCKSCLKSPI的时钟(4) Edge边沿即时钟电平变化的时刻即上升沿(rising edge)或者下降沿(falling edge)对于一个时钟周期内有两个edge分别称为(1)Leading edge前一个边沿第一个边沿对于开始电压是1 那么就是1变成0的时候对于开始电压是0那么就是0变成1的时候(2)Trailing edge后一个边沿第二个边沿对于开始电压是1 那么就是0变成1的时候即在第一次1变成0之后才可能有后面的0变成1 对于开始电压是0那么就是1变成0的时候本博文采用如下用法极性CPOL相位CPHASCLK时钟第一个边沿和第二个边沿CPOL和CPHA分别都可以是0或时1对应的四种组合就是ble data-draft-nodeblock data-draft-typetable data-sizenormal data-row-stylenormalCPOL0,CPHA0脉冲传输前和完成后都保持在低电平状态所以 CPOL0,即低电平是空闲时的电平。在第一个边沿上升沿采样数据第二个边沿下降沿输出数据对应着CPHA0。 CPOL0,CPHA1脉冲传输前和完成后都保持在低电平状态所以 CPOL0,即低电平是空闲时的电平。在第二个边沿下降沿采样数据第一个边沿上升沿输出数据对应着CPHA1。 CPOL1,CPHA0脉冲传输前和完成后都保持在高电平状态所以 CPOL1,即高电平是空闲时的电平。在第一个边沿下降沿采样数据第二个边沿上升沿输出数据对应着CPHA0。 CPOL1,CPHA1脉冲传输前和完成后都保持在高电平状态所以 CPOL1,即高电平是空闲时的电平。在第二个边沿上升沿采样数据第一个边沿下降沿输出数据对应着CPHA1。软件中如何设置SPI的极性和相位SPI分主设备和从设备两者通过SPI协议通讯。 而设置SPI的模式是从设备的模式决定了主设备的模式。 所以要先去搞懂从设备的SPI是何种模式然后再将主设备的SPI的模式设置和从设备相同的模式即可正常通讯。对于从设备的SPI是什么模式有两种1固定的有SPI从设备硬件决定的 SPI从设备具体是什么模式相关的datasheet中会有描述需要自己去datasheet中找到相关的描述即 关于SPI从设备在空闲的时候是高电平还是低电平即决定了CPOL是0还是1 然后再找到关于设备是在上升沿还是下降沿去采样数据这样就是在定了CPOL的值的前提下对应着可以推算出CPHA是0还是1了。2可配置的由软件自己设定 从设备也是一个SPI控制器4种模式都支持此时只要自己设置为某种模式即可。 然后知道了从设备的模式后再去将SPI主设备的模式设置为和从设备模式一样即可。 对于如何配置SPI的CPOL和CPHA的话不多细说多数都是直接去写对应的SPI控制器中对应寄存器中的CPOL和CPHA那两位写0或写1即可。数据交换(Data Exchanges)SPI只有主模式和从模式之分没有读和写的说法因为实质上每次SPI是主从设备在交换数据。也就是说你发一个数据必然会收到一个数据你要收一个数据必须也要先发一个数据。SPI 设备间的数据传输之所以又被称为数据交换, 是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 发送者(Transmitter) 或者 接收者(Receiver)。 在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据, 相当于该设备有一个 bit 大小的数据被交换了。一个 Slave 设备要想能够接收到 Master 发过来的控制信号, 必须在此之前能够被 Master 设备进行访问 (Access)。 所以, Master 设备必须首先通过 SS/CS pin 对 Slave 设备进行片选, 把想要访问的 Slave 设备选上。 在数据传输的过程中, 每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃, 导致 SPI 物理模块最终失效。因此, 在程序中一般都会在 SPI 传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的。SPI举例下面举一个例子帮助大家理解。SPI是一个环形总线结构由sscs、sck、sdi、sdo构成其时序其实很简单主要是在sck的控制下两个双向移位寄存器进行数据交换。假设下面的8位寄存器装的是待发送的数据10101010上升沿发送、下降沿接收、高位先发送。 那么第一个上升沿来的时候 数据将会是sdo1寄存器0101010x。下降沿到来的时候sdi上的电平将所存到寄存器中去那么这时寄存器0101010sdi这样在 8个时钟脉冲以后两个寄存器的内容互相交换一次。这样就完成里一个spi时序。举例 假设主机和从机初始化就绪并且主机的sbuff0xaa从机的sbuff0x55下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据 这样就完成了两个寄存器8位的交换上面的上表示上升沿、下表示下降沿sdi、sdo相对于主机而言的。下一步就是把 上面的过程转为动画 请仔细比较下交换后的bit顺序。了解了SPI协议说明之后下面我们基于Cortex-A9架构的exynos-4412,讲解SPI控制器的使用。Cortex-A9 SPI控制器硬件设计本例是基于FS4412开发板SPI控制器外接了MCP2515MCP2515与exynos-4412的硬件连接图如下图所示。管脚连接说明由上图可知SPI个引脚与SOC的pin连接关系CS --------- BUF_BK_LED --------- GPC1_2SO --------- BUF_I2C_SDA6 --------- GPC1_3SI --------- BUF_I2C_SCL6 --------- GPC1_4SCK --------- BUF_GPC1_1 --------- GPC1_1INT ------------------------------------------- BUF_GPX0_0MCP2515芯片连接在4412芯片的SPI2上。中断连接在GPX0_0上 CS、SO、SI、SCK复用了GPIO引脚GPC1的引脚。MCP2515输出连接SN65HVD230 CAN总线收发器SN65HVD230是德州仪器公司生产的3.3V CAN收发器。为了节省功耗缩小电路体积MCP2515 CAN总线控制器的逻辑电平采用LVTTLSN65HVD230就是与其配套的收发器。Cortex-A9 SPI控制器exynos4412 scp中的串行外设接口SPI通过各种外设来传输串行数据。SPI包括两个8、16和32位移位寄存器用于传输和接收数据。在SPI传输过程中它同时传输串行移出和接收串行移位数据。特性全双工用于Tx/Rx的8/16/32位移位寄存器支持8位/16位/32位总线接口支持摩托罗拉SPI协议和National Semiconductor Microwire两个独立的32位宽的发送和接收FIFO端口0的深度为64端口1和2中的深度为16主模式和从模式接收而不发送操作发送/接收最高频率为50 MHzSPI的操作SPI在Exynos 4412 SCP和外部设备之间传输1位串行数据。 Exynos 4412 SCP中的SPI支持CPU或DMA分别同时发送或接收FIFO和双向传输数据。 SPI有两个信道即Tx信道和Rx信道。Tx信道有来自Tx的路径FIFO到外部设备。Rx通道有从外部设备到Rx FIFO的路径。CPU或DMA必须将数据写入寄存器SPI_TX_DATA才能将数据写入FIFO。寄存器上的数据会自动移动到Tx FIFO。要从Rx FIFO读取数据CPU或DMA必须访问寄存器SPI_RX_DATA数据会自动发送到SPI_RX_DATA寄存器。CMU寄存器可以控制SPI的工作频率。操作模式SPI有两种模式即主模式和从模式。 在主模式下生成SPICLK并将其传输到外部设备。XspiCS#是选择从机的信号它指示在设置XspiCS时数据有效低水平。在发送或接收数据包之前必须将XspiCS设置为低。FIFO存取SPI支持对fifo的CPU访问和DMA访问。 对fifo的CPU访问和DMA访问的数据大小从8位、16位或32位数据中选择。当它选择8位数据大小时有效位是0到7比特。用户可以定义触发阈值来引发CPU中断。端口0中每个FIFO的触发电平由从0到252字节的步进为4个字节端口1中每个FIFO的字节从0到63字节按1个字节的步长设置。 SPI_MODE_CFG寄存器的TxDMAOn或RxDMAOn位必须设置为使用DMA访问。DMA访问支持只有单次传输和4突发传输。在Tx FIFO中DMA请求信号是高的直到Tx FIFO满为止。在Rx FIFO中如果FIFO不为空DMA请求信号高。片选控制芯片选择XspiCS是激活的低信号。换句话说当XspiCS输入为0时选择芯片。 您可以自动或手动控制XspiCS。不需要改变。 手动模式 当您使用手动控制模式时您应清除AUTO_N_MANUAL默认值为0。NSSOUT位控制XspiCS级别。 自动模式 使用自动控制模式时必须将AUTO_N_MANUAL设置为1。XspiCS在数据包和自动打包。NCS_TIME_COUNT 控制XspiCS的非激活期。NSSOUT在此时不可用。SPI寄存器说明配置寄存器CH_CFGn【bit:5】 软件复位的时候必须先将此位设置为1给一个延时后再设置为0 【bit:4】 设置SPI端口是主机还是从机0主机1从机 【bit:2-3】设置相位和极性 【bit:1】接收数据的通道使能位 【bit:0】发送数据的通道使能位。数据宽度寄存器MODE_CFGn设置总线数据宽度一般设置为1个字节。 片选寄存器CS_REGn只有NSSOUT 拉低才会进行数据的传输 移位寄存器状态寄存器SPI_STATUSn发送操作开始如果移位寄存器空了该值置1通过该值判断数据是否发送出去。 发送缓冲寄存器SPI_TX_DATA接收缓冲寄存器SPI_RX_DATASPI初始化流程设置GPIO引脚为SPI模式设置clock软件复位设置CPOL CPHA 为 00 模式并设置为主机模式设置数据位片选。1. 设置GPIO引脚为SPI模式因为CS、SO、SI、SCK复用了GPIO引脚GPC1的引脚。首先需要设置GPIO引脚为SPI模式。 如上所示该寄存器设置方式如下GPC1.CON (GPC1.CON ~0xffff0) | 0x55550;//设置IO引脚为SPI模式
Step 1 设置CPOL CPHA 为 00 模式SPI2.CH_CFG~((0x1 4)|(0x13)|(0x1 2)|0x3);//master mode, CPOL 0, CPHA 0 (Format A)2 设置clock时钟的设置需要依赖锁相环(PLL)时钟产生器。 从30.2.1节可知时钟配置需要参考CMU这一章。 由上图可知SPI 的clock源是SCLK_SPI。搜索SCLK_SPI 从第七章搜所有的SPI 继续搜索 由此可知SPI0~2的之中受CLKMPLL_USER_T 控制继续搜索。 而此时钟位于寄存器CLK_SRC_PERIL1的bit[27:24]。 继续搜索SPI2。 搜索到CLK_SRC_MASK_PERIL1、CLK_DIV_PERIL2。 可知寄存器CLK_SRC_MASK_PERIL1默认是打开的所以不用设置。 CLK_DIV_PERIL2用来设置SPI2分频的于是寄存器设置如下CLK_SRC_PERIL1 (CLK_SRC_PERIL1 ~(0xF24)) | 624;
// 0x6: 0110 SCLKMPLL_USER_T 800Mhz
CLK_DIV_PERIL2 19 8 | 3;//SPI_CLK 800/(191)/(31)
3. 软件复位void soft_reset(void)
{ SPI2.CH_CFG | 0x1 5;delay(1); //延时SPI2.CH_CFG ~(0x1 5);
}
4. 设置CPOL CPHA 为 00 模式并设置为主机模式SPI2.CH_CFG ~( (0x1 4) | (0x1 3) | (0x1 2) | 0x3);
5. 设置数据位MODE_CFGSPI2.MODE_CFG ~((0x3 17) | (0x3 29));//BUS_WIDTH8bit,CH_WIDTH8bit
6. 片选SPI2.CS_REG ~(0x1 1); //选择手动选择芯片
初始化搞定后下面我们来看如何利用SPI收发数据。收发数据流程收发数据流程如下spi复位片选从机收发数据取消片选【注意】一下代码为设置每次只读写1个byte数据每次读写1个byte数据都要按照上述步骤操作。1 spi复位void soft_reset(void)
{ SPI2.CH_CFG | 0x1 5;delay(1); //延时SPI2.CH_CFG ~(0x1 5);
}
2 片选从机void slave_enable(void)
{SPI2.CS_REG ~0x1; //enable salvedelay(3);
}
3.1 发送数据void send_byte(unsigned char data)
{SPI2.CH_CFG | 0x1; // enable Tx Channeldelay(1);SPI2.SPI_TX_DATA data;while( !(SPI2.SPI_STATUS (0x1 25)) );SPI2.CH_CFG ~0x1; // disable Tx Channel
}
3.2 接收数据unsigned char recv_byte()
{unsigned char data;SPI2.CH_CFG | 0x1 1; // enable Rx Channeldelay(1);data SPI2.SPI_RX_DATA;delay(1);SPI2.CH_CFG ~(0x1 1); //disable Rx Channelreturn data;
}
取消片选void slave_disable(void)
{SPI2.CS_REG | 0x1; //disable salvedelay(1);
}
OK到底为止如何通过SPI收发数据我们已经可以实现了但是SPI往往外部回接各种各样的从设备。下面我们来看SPI如何操作从设备。上面我们说了fs4412开发板的SPI2外设外接了MCP2515现在我们来分析一下MCP2515。MCP2515MCP2515详细资料大家自行搜索 MCP2515 datasheet 《带有 SPI 接口的独立 CAN 控制器》。简介MCP2515是一种独立的CAN总线通信控制器是Microchip公司首批独立CAN解决方案的升级器件其传输能力较Microchip公司原有CAN控制器MCP2510高两倍高通信速率可达到1Mbps。MCP2515能够接收和发送标准数据帧和扩展数据帧以及远程帧通过两个接收屏蔽寄存器和六个接收过滤寄存器滤除无关报文从而减轻CPU负担。特性MCP2515主要功能参数及电气特性如下1支持CAN技术规范2.0A/B, 高传输速率达到1Mbps2支持标准数据帧、扩展数据帧和远程帧每帧数据域长度可为0~8个字节3内含两个的接收缓冲器和三个发送缓冲器并且可编程设定优先级4内含六个29位bit的接收过滤寄存器和两个29位bit的接收屏蔽寄存器5高速SPI接口支持SPI 0,0和1,1模式6一次性模式可确保报文被一次性传输7具有可编程时钟脉冲输出引脚可作为其他芯片时钟信号源8 帧起始SOF信号输出功能可被用于在确定的系统中如时间触发CAN-TTCAN执行时隙功能或在CAN总线诊断中决定早期总线出级9 采用低功耗CMOS技术工作电压2.7V~5.5V, 工作电流5mA待机状态1μA10工作温度范围I-40℃到85℃E-40℃到125℃。结构框图CAN模块MCP2515 是一款独立 CAN 控制器 可简化需要与 CAN总线连接的应用。如上图 简要显示了 MCP2515 的结构框图。该器件主要由三个部分组成CAN 模块包括 CAN 协议引擎、验收滤波寄存 器、验收屏蔽寄存器、发送和接收缓冲器。用于配置该器件及其运行的控制逻辑和寄存器。SPI 协议模块。CAN 模块的功能是处理所有 CAN 总线上的报文接收和发送。报文发送时首先将报文装载到正确的报文缓冲器和控制寄存器中。通过 SPI 接口设置控制寄存器中的相应位或使用发送使能引脚均可启动发送操作。通过读取相应的寄存器可以检查通讯状态和错误。 会对在 CAN总线上检测到的任何报文进行错误检查然后与用户定义的滤波器进行匹配以确定是否将报文移到两个接收缓冲器中的一个。SPI 协议模块MCU通过SPI接口与该器件连接。使用标准的SPI读/写指令以及专门的 SPI 命令来读 / 写所有的寄存器。 MCP2515 设计可与许多单片机的串行外设接口 SPI直接相连支持 0,0 和 1,1 运行模式。外部数据和命令通过 SI 引脚传送到器件中且数据在 SCK 时钟信号的上升沿传送进去。 MCP2515 在 SCK 的下降沿通过 SO引脚传送出去。在进行任何操作时 CS 引脚都必须保持为低电平。与MCP2515通信SPI指令集我们要想操作MCP2515只能用过SPI总线向MCP2515发送一些数据根据规定发送不同的数据就代表不同的操作于是就形成了对应的指令集。 如上图所示比如我们要执行复位操作那么我只需要通过SPI总线写入11000000即0xC0即可。下面我们来详细分析如何向MCP2515发送复位命令如何读写数据。复位因为复位只需要发送0XC0即可并不需要其他额外操作所以我们只需要根据我们之前章节所讲的SPI发送数据流程操作接口。void reset_2515()
{soft_reset(); //复位spi控制器slave_enable() ; //片选从机send_byte(0xc0); //发送复位命令slave_disable() ; //取消片选}
读取数据由上图可知读取数据流程如下片选从机通过SPI发送指令0x03发送地址读取数据取消片选unsigned char read_byte_2515(unsigned char Addr)
{unsigned char ret;slave_enable();send_byte(0x03);send_byte(Addr);ret recv_byte();slave_disable();return(ret);
}
发送数据由上图可知发送数据流程如下片选从机通过SPI发送指令0x02发送地址发送数据取消片选void write_byte_2515(unsigned char addr,unsigned char data)
{slave_enable();send_byte(0x02);send_byte(addr);send_byte(data);slave_disable();
}
读RX缓冲器装载TX缓冲器请求发送RTS指令位修改指令有些寄存器要修改对应的bit必须先发送该指令发送屏蔽字节然后才可以修改屏蔽字节中对应位为1的值后面会有例子给出。CAN知道该如何和CAN通信下面我们来看如何初始化CAN。CAN初始化CAN的初始化步骤如下MCP2515复位设置MCP2515为配置模式位定时配置有配置寄存器CNF1CNF2,CNF3控制中断使能接收缓冲器配置引脚控制寄存器和状态寄存器此外为方便测试我们再加一步 7. 回环模式用于测试1. MCP2515复位上一节已经实现。void reset_2515()
2. 设置MCP2515为配置模式 由上图所示只需要向地址0X0F写入数据0x80即可。 write_byte_2515(0x0f, 0x80); //CANCTRL寄存器进入配置模式 中文DATASHEET 58页
3. 位定时配置有配置寄存器CNF1CNF2,CNF3控制CAN总线上的所有节点都必须具有相同的标称比特率。CAN 协议采用不归零 Non Return to Zero NRZ编码方式在数据流中不对时钟信号进行编码。因此接收时钟信号必须由接收节点恢复并与发送器的时钟同步。由于不同节点的振荡器频率和传输时间不同接收器应具有某种能与数据传输边沿同步的锁相环 Phase Lock Loop PLL来同步时钟并保持这种同步。鉴于数据采用 NRZ 编码有必要进行位填充以确保至少每 6 位时间发生一次边沿使数字锁相环 Digital Phase LockLoop DPLL同步。MCP2515 通过 DPLL 实现位定时。 DPLL 被配置成同输入数据同步并为发送数据提供标称定时。 DPLL 将每一 个 位 时 间 分 割 为 由 最 小 单 位 为 时 间 份 额 Time Quanta TQ所组成的多个时间段。在位时间帧中执行的总线定时功能例如与本地振荡器同步、网络传输延迟补偿和采样点定位等都是由DPLL 的可编程位定时逻辑来规定的。CNF1 BRP5:0 控制波特率预分频比的设置。这些位根据OSC1 输入频率设置 TQ 的时间长度。当 BRP5:0 ‘b000000’ TQ 最小值取 2 TOSC。通过 SJW1:0 选择以 TQ 计的同步跳转宽度。CNF2 PRSEG2:0 位设定以 TQ 计的传播段时间长度。PHSEG12:0位设定以TQ计的相位缓冲段PS1的时间长度。CNF3 如果 CNF2.BTLMODE 位为 1则相位缓冲段 PS2 的时间长度将由 PHSEG22:0 位设定以 TQ 计。如果BTLMODE 位为 0则 PHSEG22:0 位不起作用。MCP2515 波特率配置以16M晶振为例 SJW 段数(1PRSEGPRSEG1PRSEG2)#define CNF1_20K 0xd3 //4 20(1487)
#define CNF2_20K 0xfb
#define CNF3_20K 0x46 //可以设置的波特率 5K 10K 15K 20K 25K 40K 50K 80K 100K 125K 200K 400K 500K 667K 800K 1M
write_byte_2515(0x2A, CNF1_20K); //CNF1位定时配置寄器
write_byte_2515(0x29, CNF2_20K); //CNF2位定时配置寄器
write_byte_2515(0x28, CNF3_20K); //CNF3位定时配置寄器
4. 中断使能MCP2515 有八个中断源。 CANINTE 寄存器包含了使能各中断源的中断使能位。 CANINTF 寄存器包含了各中断源的中断标志位。当发生中断时 INT 引脚将被MCP2515 拉为低电平 并保持低电平状态直至 MCU 清除中断。中断只有在引起相应中断的条件消失后才会被清除。 建议在对 CANINTF 寄存器中的标志位进行复位操作时采用位修改命令而不要使用一般的写操作。这是为了避免在写命令执行过程中无意间修改了标志位进而导致中断丢失。 应该注意的是 CANINTF 中的中断标志位是可读写位因此在相关 CANINTE 中断使能位置 1 的前提下对上述任一位置 1 均可使 MCU 产生中断请求。 write_byte_2515(0x2B, 0x1f); //CANINTE中断使能寄存器
5. 接收缓冲器配置MCP2515 具有两个全接收缓冲器。每个接收缓冲器配备 有多 个 验 收滤 波 器。除 上述 专 用 接收 缓 冲 器外MCP2515 还具有单独的报文集成缓冲器 Message Assembly Buffer MAB 可作为第三个接收缓冲器。 bit5:6设置为1其余位暂时不用设置为0. write_byte_2515(0x60, 0x60); //RXB0CTRL接收缓冲器0 控制寄存器
6. 引脚控制寄存器和状态寄存器当引脚配置为数字输出引脚时相应的接收缓冲器中的BFPCTRL.BxBFM位应被清零 而BFPCTRL.BnBFE位应被置 1。在这种工作模式下引脚的状态由 BFPCTRL.BnBFS位控制。 BnBFS位写入1时将使相应的缓冲器满中断引脚输出高电平写入 0 将使该引脚输出低电平。当引脚处于这种模式时该引脚的状态只应通过位修改 SPI 命令来修改以避免任何缓冲器满中断引脚出现干扰。void bit_modify_2515(unsigned char addr, unsigned char mask, unsigned char data)
{
// CS_SPI 0 ;slave_enable() ;send_byte(0x05) ;send_byte(addr) ;send_byte(mask) ;send_byte(data) ;slave_disable() ;
// CS_SPI 1 ;
}
bit_modify_2515(0x0C, 0x0f, 0x0f); //BFPCTRL_RXnBF 引脚控制寄存器和状态寄存器 中文DATASHEET 29 页
7. 回环模式用于测试write_byte_2515(0x0f, 0x40); //CAN控制寄存器回环模式,用于测试
can缓冲区数据收发MCP2515 采用三个发送缓冲器。每个发送缓冲器占用14 字节的 SRAM并映射到器件存储器中。 其中第一个字节 TXBnCTRL 是与报文缓冲器相关的控制寄存器。该寄存器中的信息决定了报文在何种条件下发送并在报文发送时指示其状态 。用 5 个字节来装载标准和扩展标识符以及其他报文仲裁信息见寄存器 3-3 到寄存器 3-7 。最后 8 个字节用于装载等待发送报文的 8 个可能的数据字节 。至少须将 TXBnSIDH、 TXBnSIDL 和 TXBnDLC 寄存器装载数据。如果报文包含数据字节还需要对 TXBnDm寄存器进行装载。若报文采用扩展标识符应对 TXBnEIDm 寄存器进行装载并将 TXBnSIDL.EXIDE 位置1。下面我们看如何向CAN的缓冲区0发送和接收数据。数据发送can缓冲区0数据发送流程如下设置为发送最高优先级设置发送缓冲器0标准标识符高位设置发送缓冲器0标准标识符低位设置发送缓冲器0数据长度码8字节向缓冲区写入数据地址从0x36起发送请求命令0x81发送数据1. 设置为发送最高优先级write_byte_2515(0x30, 0x03); //设置为发送最高优先级
2. 设置发送缓冲器0标准标识符高位write_byte_2515(0x31, 0xff); //发送缓冲器0标准标识符高位
3. 设置发送缓冲器0标准标识符低位write_byte_2515(0x32, 0x00); //发送缓冲器0标准标识符低位
4. 设置发送缓冲器0数据长度码8字节write_byte_2515(0x35, 0x08); //发送缓冲器0数据长度码8字节
5. 向缓冲区写入数据地址从0x36起write_byte_2515(0x36i ,tx_buff[i]); //向txb缓冲器中写入8个字节
6. 发送请求命令0x81发送数据void send_req_2515()
{// CS_SPI 0; //复位soft_reset(); //复位spi控制器slave_enable() ; //片选从机send_byte(0x81); //发送请求命令slave_disable() ; //取消片选
// CS_SPI1;
}
Can数据的接收从CAN缓冲区读取数据流程如下读取中断标志寄存器0x2c的value判断bit0是否为1从接收缓冲区读走数据地址从0X66开始软复位向中断标志寄存器0x2c写入位掩码向中断标志寄存器0x2c写入数据0清终端1. 读取中断标志寄存器0x2c的value判断bit0是否为1当报文传送至某一接收缓冲器时与该接收缓冲器对应的 CANINTF.RXnIF 位将置 1。一旦缓冲器中的报文处理完毕 MCU 就必须将该位清零以接收下一条报文。该控制位提供的锁定功能确保 MCU 尚未处理完上一条报文前 MCP2515 不会将新的报文载入接收缓冲器。如果 CANINTE.RXnIE 位被置 1器件会在 INT 引脚产生一个中断显示接收到报文有效。另外如果被配置为接收缓冲器满中断引脚与之相应的 RXnBF 引脚会被拉低。MCP2515 有八个中断源。 CANINTE 寄存器包含了使能各中断源的中断使能位。 CANINTF 寄存器包含了各中断源的中断标志位。当发生中断时 INT 引脚将被MCP2515 拉为低电平 并保持低电平状态直至 MCU 清除中断。中断只有在引起相应中断的条件消失后才会被清除。建议在对 CANINTF 寄存器中的标志位进行复位操作时采用位修改命令而不要使用一般的写操作。这是为了避免在写命令执行过程中无意间修改了标志位进而导致中断丢失。应该注意的是 CANINTF 中的中断标志位是可读写位因此在相关 CANINTE 中断使能位置 1 的前提下对上述任一位置 1 均可使 MCU 产生中断请求。2. 从接收缓冲区读走数据rx_buff[i] read_byte_2515(0x66i);
3. 软复位soft_reset();
4. 向中断标志寄存器0x2c写入位掩码bit_modify_2515(0x2c,0x01,0x00);//修改bit 0
5.清中断write_byte_2515(0x2c, 0x00);
最终操作代码如下节省篇幅重复函数不贴了。#define CNF1_20K 0xd3 //4 20(1487)
#define CNF2_20K 0xfb
#define CNF3_20K 0x46 void Init_can(void)
{reset_2515(); //复位write_byte_2515(0x0f, 0x80); //CANCTRL寄存器进入配置模式 中文DATASHEET 58页//可以设置的波特率 5K 10K 15K 20K 25K 40K 50K 80K 100K 125K 200K 400K 500K 667K 800K 1Mwrite_byte_2515(0x2A, CNF1_20K); //CNF1位定时配置寄器 中文DATASHEET 41-42页write_byte_2515(0x29, CNF2_20K); //CNF2位定时配置寄器 中文DATASHEET 41-42页write_byte_2515(0x28, CNF3_20K); //CNF3位定时配置寄器 中文DATASHEET 41-43页write_byte_2515(0x2B, 0x1f); //CANINTE中断使能寄存器 中文DATASHEET 50 页write_byte_2515(0x60, 0x60); //RXB0CTRL接收缓冲器0 控制寄存器 中文DATASHEET 27 页//write_byte_2515(0x70, 0x20); //接收缓冲器1控制寄存器bit_modify_2515(0x0C, 0x0f, 0x0f); //BFPCTRL_RXnBF 引脚控制寄存器和状态寄存器 中文DATASHEET 29 页write_byte_2515(0x0f, 0x40); //CAN控制寄存器回环模式,用于测试
}
void send_byte(unsigned char data)
{SPI2.CH_CFG | 0x1; // enable Tx Channeldelay(1);SPI2.SPI_TX_DATA data;while( !(SPI2.SPI_STATUS (0x1 25)) );SPI2.CH_CFG ~0x1; // disable Tx Channel
}
unsigned char recv_byte()
{unsigned char data;SPI2.CH_CFG | 0x1 1; // enable Rx Channeldelay(1);data SPI2.SPI_RX_DATA;delay(1);SPI2.CH_CFG ~(0x1 1); //disable Rx Channelreturn data;
}
void bit_modify_2515(unsigned char addr, unsigned char mask, unsigned char data)
{
// CS_SPI 0 ;slave_enable() ;send_byte(0x05) ;send_byte(addr) ;send_byte(mask) ;send_byte(data) ;slave_disable() ;
// CS_SPI 1 ;
}
void Can_send(unsigned char *tx_buff)
{unsigned char i;write_byte_2515(0x30, 0x03); //设置为发送最高优先级write_byte_2515(0x31, 0xff); //发送缓冲器0标准标识符高位write_byte_2515(0x32, 0x00); //发送缓冲器0标准标识符低位write_byte_2515(0x35, 0x08); //发送缓冲器0数据长度码8字节for(i 0; i 8; i){write_byte_2515(0x36i ,tx_buff[i]); //向txb缓冲器中写入8个字节
// printf(%x ,tx_buff[i]);}send_req_2515();}unsigned char Can_receive(unsigned char *rx_buff)
{unsigned char i,flag;flag read_byte_2515(0x2c); //CANINTF——中断标志寄存器printf(flag%xn,flag);// printf( SPI2.SPI_STATUS %xn, SPI2.SPI_STATUS );// soft_reset();if (flag0x1) //接收缓冲器0满中断标志位{for(i 0; i 16; i){rx_buff[i] read_byte_2515(0x66i);// printf(%x ,rx_buff[i]);// printf( SPI2.SPI_STATUS %xn, SPI2.SPI_STATUS );soft_reset();}bit_modify_2515(0x2c,0x01,0x00);write_byte_2515(0x2c, 0x00);if (!(rx_buff[1]0x08)) return(1); //接收标准数据帧}return(0);
}
int main(void)
{GPX2.CON 0x1 28;uart_init();unsigned char ID[4],buff[8]; //状态字unsigned char key;unsigned char ret;//,j,k,ret0,ret1,ret2,ret3,ret4,ret5,ret6,ret7,ret8,ret9;unsigned int rx_counter;volatile int i0;GPC1.CON (GPC1.CON ~0xffff0) | 0x55550;//设置IO引脚为SPI模式/*spi clock config*/CLK_SRC_PERIL1 (CLK_SRC_PERIL1 ~(0xF24)) | 624;// 0x6: 0110 SCLKMPLL_USER_T 800MhzCLK_DIV_PERIL2 19 8 | 3;//SPI_CLK 800/(191)/(31)soft_reset(); // 软复位SPI控制器SPI2.CH_CFG ~( (0x1 4) | (0x1 3) | (0x1 2) | 0x3);//master mode, CPOL 0, CPHA 0 (Format A)SPI2.MODE_CFG ~((0x3 17) | (0x3 29)); //BUS_WIDTH8bit,CH_WIDTH8bitSPI2.CS_REG ~(0x1 1); //选择手动选择芯片mydelay_ms(10); //延时Init_can(); //初始化MCP2515printf(n************ SPI CAN test!! ************n);while(1){//Turn on ledGPX2.DAT GPX2.DAT | 0x1 7;mydelay_ms(50);printf(nplease input 8 bytesn);for(i0;i8;i){src[i] getchar();putc(src[i]);}printf(n);Can_send(src); //发送标准帧mydelay_ms(100);ret Can_receive(dst); //接收CAN总线数据printf(ret%xn,ret);printf(src);for(i0;i8;i) printf( %x, src[i]);//将CAN总线上收到的数据发到串行口printf(n);printf(dst);for(i0;i8;i) printf( %x,dst[6i]); //将CAN总线上收到的数据发到串行口printf(n);//Turn offGPX2.DAT GPX2.DAT ~(0x1 7);mydelay_ms(100);} //while(1)return 0;
} //main问题1 什么是feddback 时钟2 Can的缓冲寄存器组 原理 更多信息请关注 公号 一口Linux
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87077.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!