找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4813|回复: 1
打印 上一主题 下一主题
收起左侧

【Kinetis经验分享】KL系列SPI主从通信之单线双向通信

[复制链接]
跳转到指定楼层
楼主
本文主要讲解kinetis L系列中SPI通信的单线双向通信功能,并使用KL25为例讲解如何配置,代码实现,硬件连接以及实验结果。所谓单线双向通信,并不是指整个SPI通信只使用一根线,而是不同于通常的SPI通信四根线,使用SCK(时钟信号),PCS(片选信号),MOSI(数据信号主出从入),MISO(数据信号主入从出)。单线通信不使用两根数据线,只使用一根数据线,对于主机MOMI;对于从机SISO。所以,这里的单线应该理解为单数据线。


                                                    图 1 正常模式以及双向模式
由上图可以知道,单线模式是通过置位 SPI 控制寄存器 2 中的 SPC0 位 :SPIx_C2[SPC0] =1 实现。 此时,对于主机,不再同时使用 MOSI 以及 MISO 两个引脚,这时 MOSI 充当了 MOMI 主机数据线;对于从机,同样不再使用 MOSI 以及MISO 两个引脚,这时 MISO 引脚充当了 SISO 从机数据线。要实现 SPI 的单线双向通信,只要把主机的 MOMI 以及 SISO 引脚相连,实现数据的通信,其余的 SCK 以及 PCS 信号和正常模式一样。另外,如果要实现单线通信的输出功能,需要通过置位 SPIx_C2[BIDIROE]位实现,输入则无需配置。同一时刻,对于主从机,只有一个输入一个输出,不可以同时配置为输出,即把主从机的 SPIx_C2[BIDIROE]位都置上。

二,硬件连接
本文使用 FRDM-KL25 开发板的 SPI0 以及 SPI1 两个 SPI 模块实现相互的单线双向通信。具体的硬件连接如下图所示:

2 实验硬件连接


三、代码实现
1、端口配置
实现 SPI0,SPI1 相关引脚的定义,以及模块时钟开启,代码如下:
  1.     void spi_port_init(void)
  2.     {
  3.     SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTE_MASK;
  4.     SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK | SIM_SCGC4_SPI1_MASK;
  5.     PORTA_PCR16 &= ~PORT_PCR_MUX_MASK;
  6.     PORTA_PCR16 |= PORT_PCR_MUX(5)|PORT_PCR_DSE_MASK;                 //Use PTA16 as SPI0_MISO
  7.     PORTA_PCR17 &= ~PORT_PCR_MUX_MASK;
  8.     PORTA_PCR17 |= PORT_PCR_MUX(5)|PORT_PCR_DSE_MASK;                 //Use PTA17 as SPI0_MOSI
  9.     PORTC_PCR5 &= ~PORT_PCR_MUX_MASK;
  10.     PORTC_PCR5 |= PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                  //Use PTC5 as SPI0_sck
  11.     PORTC_PCR4 &= ~PORT_PCR_MUX_MASK;
  12.     PORTC_PCR4 = PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                   //Use PTC4 as SPI0_pcs
  13.     PORTE_PCR1 &= ~PORT_PCR_MUX_MASK;
  14.     PORTE_PCR1 |= PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                  //Use PTE1 as SPI1_MOSI
  15.     PORTE_PCR3 &= ~PORT_PCR_MUX_MASK;
  16.     PORTE_PCR3 |= PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                  //Use PTE3 as SPI1_MISO
  17.     PORTE_PCR2 &= ~PORT_PCR_MUX_MASK;
  18.     PORTE_PCR2 |= PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                  //Use PTE2 as SPI1_SCK
  19.     PORTE_PCR4 &= ~PORT_PCR_MUX_MASK;
  20.     PORTE_PCR4 = PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK;                   //Use PTE4 as SPI1_SS_b
  21.     }
复制代码

2:模块单线双向配置
配置 SPI0 为主机,SPI1 为从机,两个模块均为单线双向功能,初始配置为MOMI 引脚为主机输出,SISO 引脚为从机输入。模块初始化代码配置如下:
  1.     void spi_module_init(void)
  2.     {
  3.     // ================SPI0 init master ==============
  4.     SPI0_C1 &= ~SPI_C1_SPE_MASK ;
  5.     SPI0_C1 = SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK ;    //SPI0 主机
  6.     SPI0_C1 &= (~SPI_C1_CPHA_MASK) & (~SPI_C1_CPOL_MASK) & (~SPI_C1_SPIE_MASK) & (~SPI_C1_SPTIE_MASK);
  7.     SPI0_BR = (SPI_BR_SPPR(0x02) | SPI_BR_SPR(0x05)); // Set baud rate register 125Khz 波特率
  8.     SPI0_C2 |= SPI_C2_MODFEN_MASK | SPI_C2_BIDIROE_MASK | SPI_C2_SPC0_MASK ;    // 单线双向模式,输出
  9.     //==================SPI1 init slave==============
  10.     SPI1_C1 &= ~SPI_C1_SPE_MASK;
  11.     SPI1_C1 |= SPI_C1_SSOE_MASK;// 从机
  12.     SPI1_C1 &= (~SPI_C1_CPHA_MASK) & (~SPI_C1_CPOL_MASK) & (~SPI_C1_SPIE_MASK) & (~SPI_C1_SPTIE_MASK);
  13.     SPI1_C2 |= SPI_C2_MODFEN_MASK | SPI_C2_SPC0_MASK;
  14.     SPI1_C2 &= ~SPI_C2_BIDIROE_MASK; //从机单线输入
  15.     //==================Enable SPI0 and SPI1============
  16.     SPI0_C1 |= SPI_C1_SPE_MASK ;    // Enable SPI module
  17.     SPI1_C1 |= SPI_C1_SPE_MASK;    /* Enable device */
  18.     }
复制代码
3:主控程序
  1.     spi_port_init();   //相关引脚初始化
  2.     spi_module_init(); // SPI 模块初始化
  3.     spi0_send8(0x0E);        //主机发送 0X0E
  4.     rd = spi0_get8();
  5.     rd1 = spi1_get8();        //从机接收
  6.     printf("SPI0_rd: %02x", rd&0xFF);  //打印结果
  7.     printf("SPI1_rd: %02x", rd1&0xFF);
  8.     spi0_send8(0x1E);       //主机发送 0X1E
  9.     rd = spi0_get8();
  10.     rd1 = spi1_get8();        //从机接收
  11.     printf("SPI0_rd: %02x", rd&0xFF);
  12.     printf("SPI1_rd: %02x", rd1&0xFF);
  13.     global_pass_count = 0;
  14.     //从机发送,主机接收
  15.     SPI1_C2 |= SPI_C2_BIDIROE_MASK;    //MISO is used in slave mode as I/O---output
  16.     //set MOSI input
  17.     SPI0_C2 &= ~SPI_C2_BIDIROE_MASK;  //MOSI is used in master mode as input
  18.     //从机发送从 1 开始递加数据给主机,主机接收
  19.     while(1)
  20.     {
  21.     global_pass_count++;
  22.     while ((SPI1_S & SPI_S_SPTEF_MASK) == 0);
  23.     SPI1_D = global_pass_count;
  24.     rd=spi0_send_read(0xaa);
  25.     printf("SPI0_rd: %02x", rd&0xFF);
  26.     }
复制代码

四,实验结果
1,SPI 波形
波形见图 3,其中 MOSI 即为 MOMI 以及 SISO 单数据线上面的波形。Clock 即为时钟线,Enable 即为 PCS 片选信号线。从图中可以看到,主从机之间的通信数据均在单数据线上。0X0E 及 0X1E 是 SPI0 作为主机发出的,后面的 0X01 开始的递增数据均为 SPI1 作为从机发出的。

图 3 SPI 通信波形
2,通信数据打印信息

图 4 打印结果信息

从上图中可以看到,SPI0 作为主机发出的 0X0E以及 0X1E 都能被 SPI1 从机接收到。 而 SPI1 作为从机发出的从 0X01 递增的数据也均被 SPI0 作为主机接收到。

综上,可以看到,SPI0 以及 SPI1 可以实现单线双向功能的通信。


【经验分享】KL系列SPI主从通信之单线双向通信.pdf

365.5 KB, 下载次数: 6, 下载积分: 黑币 -5

KL_SPI_bidirectional_doc.rar

816.25 KB, 下载次数: 3, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:447246 发表于 2018-12-16 14:51 | 只看该作者
支持一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表