教你玩转W600/W800之SPI篇
时间:2020年07月09日 人气:...

很多人只知道w600有spi,但是往往搞不清楚如何使用,所以本文就对w600的spi功能进行一番扫盲。

在官方datasheet中可以看到其有主/从SPI控制器高速SPI设备控制器,所以就对这两类SPI区分为低速spi高速spi两类。

  1. 高速SPI,之所以叫高速,是因为时钟频率最高为50MHZ。使用这种spi时,w600只能当作从设备来使用,在连接上,除了cs、ck、di、do这4个之外,还多了一个中断io,用于w600向主设备通知进行数据交互(低电平表示)。在官方SDK中,其驱动实现如wm_hspi.c。其官方SDK中为了方便做透传模块,还用这高速spi实现了一套类似串口AT指令的东西,叫做精简指令,其代码如wm_cmdp_hostif.c。

  2. 主/从SPI,也就是低速SPI,之所以叫低速SPI,是因为时钟频率最高只能到20MHZ。顾名思义,使用这类spi的时候,w600可以作为主设备来使用,也可以作为从设备来用,在连接上,也就是只需要cs、ck、di、do这4个。在官方SDK中,其驱动实现如wm_hostspi.c,一般人只需要调用wm_hostspi.h中声明的接口即可。一般而言w600做从设备的话用高速spi就行了,所以低速spi更多的是用来w600做主设备来使用的,如spi flash,spi屏等等。

  1. 一、低速spi实战指导

w600的cs可以使用硬件模式,也可以软件模式。这里我推荐使用软件cs,因为硬件cs只能是固定那几个io,而软件cs可以随便选择io使用更加灵活。官方SDK的gd spi flash驱动是以硬件cs模型写的,我测试时发现这种写法似乎就对w25qxx系列的spi flash无法正常交互,反而使用软件cs就能正常交互,所以我更加认为使用软件cs可能兼容性更好。

好了,现在以官方SDK开始说说使用步骤:

1.使用wm_spi_ck_config、wm_spi_di_config、wm_spi_do_config配置io,可选的io可以点开这三个接口,其可选的io一目了然。

2.使用tls_gpio_cfg(io, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH)配置一个io使用普通的gpio功能作为cs脚。

3.使用tls_gpio_write(io, 1) 拉高cs脚,即取消片选的意思。

4.使用tls_spi_init、tls_spi_trans_type、tls_spi_setup这个初始化和配置spi。传输模式一般就选SPI_DMA_TRANSFER(除非你把dma内存干做他用),spi的cpol和cpha模式可由TLS_SPI_MODE_0-TLS_SPI_MODE_3选一个,时钟频率最大20MHZ(TLS_SPI_FCLK_MAX)最小1000HZ(TLS_SPI_FCLK_MIN),cs_active一般使用TLS_SPI_CS_LOW即可。

以上就完成了spi的配置,下面继续说读写:

先使用tls_gpio_write(io, 0) 拉低cs脚,然后使用tls_spi_write发送数据,使用tls_spi_read接收数据,最后tls_gpio_write(io, 1) 拉高cs脚结束交互。

点此可以直接看个w25qxx的示例代码。是不是发现操作非常简单?是的,你没有看错,就是这么简单的,毕竟直接拿官方SDK现成的驱动用起来就是很简单。使用dma方式读写spi的时候,需要注意数据长度受SPI_DMA_BUF_MAX_SIZE宏的定义限制(默认是8160)。

  1. 二、高速spi实战指导

不得不说,w600的高速spi一般人直接就上手就干的话,十有八九是干不通的。我看过很多人的反馈,似乎直接拿杜邦线接的大概率不通......通信的连线上不串个33Ω电阻就不通......

其实我说了这么多的目的,只是想告诉你,有条件的话最好用直接飞线的方式连接spi,如果调试的时候不通,再在线上加个电阻。好了,下面直接写写使用步骤:

1.参考wm_hspi_gpio_config配置一组io,官方SDK共分了两组,其实不一定非要用这两组,只要有高速spi功能的io都可以配了来用的,可自由搭配。

2.使用tls_slave_spi_init()、tls_set_high_speed_interface_type(HSPI_INTERFACE_SP、tls_set_hspi_user_mode(1)配置一下;

3.使用tls_hspi_rx_data_callback_register和tls_hspi_rx_cmd_callback_register注册个接收回调函数。至于何为data何为cmd,这个纯属个软件上的数据分类了,我估计光看完这步骤大多数小白还是不懂,所以到时候直接去看代码就好了。

4.发送就是使用tls_hspi_tx_data了,同样,数据长度注意不要超过HSPI_TXBUF_SIZE * HSPI_TX_DESC_NUM就好。

上面是w600的步骤,至于上位机上的操作就更简单了,w600操作通知上位机的时候,会用中断io低电平来通知上位机读数据。上位机启动交互就是标准的spi了,这就不在扯了。

两个官方提供例子:基于uocs的stm32和w600的简单通信例子一个stm32做网卡和w600深度改进的例子

  1. 三、普通io模拟spi指导

这里以w600普通gpio模拟spi功能简单说说用法,先拿tls_gpio_cfg(io, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING)这样配下所要用的io,用tls_gpio_write(io, 1)拉高该io,用tls_gpio_write(io, 0)拉低该io。因为spi传输是个移位操作,所以

static void spi_delay(void)
{
    int i;
    for (i = 0;i < 100; i++);
}

void soft_spi_write(unsigned char data)
{	
    unsigned char i;  
  
    for(i = 0; i < 8; i++)
    {  
        tls_gpio_write(ckio, 0);

        if(data & 0x80)
            tls_gpio_write(diio, 1);
        else 
            tls_gpio_write(diio, 0);

        tls_gpio_write(ckio, 1);

        data <<= 1;   
    }	

    spi_delay();

    tls_gpio_write(ckio, 0);
}
  1. 四、一些可以优化改进的地方

    像使用tls_gpio_write的效率是比较低的,可以使用位带来提升效率,如tls_bitband_write......

热门评论