1# SPI概述 2 3## 简介 4 5- SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。 6- SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信,常用于与闪存、实时时钟、传感器以及模数转换器等进行通信。 7- SPI以主从方式工作,通常有一个主设备和一个或者多个从设备。主设备和从设备之间一般用4根线相连,它们分别是: 8 9 - SCLK – 时钟信号,由主设备产生; 10 - MOSI – 主设备数据输出,从设备数据输入; 11 - MISO – 主设备数据输入,从设备数据输出; 12 - CS – 片选,从设备使能信号,由主设备控制; 13- SPI通信通常由主设备发起,通过以下步骤完成一次通信: 14 15 - 通过CS选中要通信的从设备,在任意时刻,一个主设备上最多只能有一个从设备被选中。 16 - 通过SCLK给选中的从设备提供时钟信号。 17 - 基于SCLK时钟信号,主设备数据通过MOSI发送给从设备,同时通过MISO接收从设备发送的数据,完成通信。 18 19## 接口说明 20 21### 包含头文件: 22 23```c 24#include "lz_hardware.h" 25``` 26 27#### 1. SPI设备初始化接口 28 29```c 30unsigned int SpiIoInit(SpiBusIo io); 311) 参数说明: 32 io: SPI设备IO管脚配置 332) 返回值: 34 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 35``` 36 37#### 2. SPI设备初始化接口 38 39```c 40unsigned int LzSpiInit(unsigned int id, LzSpiConfig conf); 411) 参数说明: 42 id: SPI总线id 43 conf:SPI配置信息 442) 返回值: 45 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 46``` 47 48#### 3. SPI设备释放接口: 49 50```c 51unsigned int LzSpiDeinit(unsigned int id); 521) 参数说明: 53 id:SPI总线id 542) 返回值: 55 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 56``` 57 58#### 4. SPI设备转发数据: 59 60```c 61unsigned int LzSpiTransfer(unsigned int id, LzSpiMsg *msg); 621) 参数说明: 63 id: SPI总线id 64 msg: SPI转发数据 652) 返回值: 66 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 67``` 68 69#### 5. SPI写数据: 70 71```c 72static inline unsigned int LzSpiWrite(unsigned int id, unsigned int chn, const void *buf, unsigned int len); 731) 参数说明: 74 id: SPI总线id 75 chn: SPI通道id 76 buf: 写入数据 77 len: 写入数据长度 782) 返回值: 79 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 80``` 81 82#### 6. SPI读数据: 83 84```c 85static inline unsigned int LzSpiRead(unsigned int id, unsigned int chn, void *buf, unsigned int len) 861) 参数说明: 87 id: SPI总线id 88 chn: SPI通道id 89 buf: 写入数据 90 len: 写入数据长度 912) 返回值: 92 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 93``` 94 95#### 7. SPI设备修改配置: 96 97```c 98unsigned int LzSpiSetConfig(unsigned int id, LzSpiConfig conf); 991) 参数说明: 100 id: SPI总线id 101 conf:SPI配置信息 1022) 返回值: 103 成功返回LZ_HARDWARE_SUCCESS, 出错返回错误码 104``` 105 106## 使用实例 107 108```c 109#include "lz_hardware.h" 110#define SPI_BUS 1 111SpiBusIo g_spi1m1 = { 112 .cs = {.gpio = GPIO0_PB0, .func = MUX_FUNC4, .type = PULL_UP, .drv = DRIVE_KEEP, .dir = GPIO_DIR_KEEP, .val = LZGPIO_LEVEL_KEEP}, 113 .clk = {.gpio = GPIO0_PB1, .func = MUX_FUNC4, .type = PULL_UP, .drv = DRIVE_KEEP, .dir = GPIO_DIR_KEEP, .val = LZGPIO_LEVEL_KEEP}, 114 .mosi = {.gpio = GPIO0_PB2, .func = MUX_FUNC4, .type = PULL_UP, .drv = DRIVE_KEEP, .dir = GPIO_DIR_KEEP, .val = LZGPIO_LEVEL_KEEP}, 115 //.miso = {.gpio = GPIO0_PB3, .func = MUX_FUNC4, .type = PULL_UP, .drv = DRIVE_KEEP, .dir = GPIO_DIR_KEEP, .val = LZGPIO_LEVEL_KEEP}, 116 .miso = {.gpio = INVALID_GPIO, .func = MUX_FUNC4, .type = PULL_UP, .drv = DRIVE_KEEP, .dir = GPIO_DIR_KEEP, .val = LZGPIO_LEVEL_KEEP}, 117 .id = FUNC_ID_SPI1, 118 .mode = FUNC_MODE_M1, 119}; 120 121LzSpiConfig g_spi1Conf = {.bitsPerWord = SPI_PERWORD_8BITS, 122 .firstBit = SPI_MSB, 123 .mode = SPI_MODE_0, 124 .csm = SPI_CMS_ONE_CYCLES, 125 .speed = 5000000, 126 .isSlave = false}; 127 128unsigned int spi_sample() 129{ 130 unsigned int ret = LZ_HARDWARE_SUCCESS; 131 unsigned char buf[1]; 132 //初始化spi 133 if (SpiIoInit(g_spi1m1) != LZ_HARDWARE_SUCCESS) 134 return LZ_HARDWARE_FAILURE; 135 if (LzSpiInit(SPI_BUS, g_spi1Conf) != LZ_HARDWARE_SUCCESS) 136 return LZ_HARDWARE_FAILURE; 137 138 buf[0] = 'c'; 139 //spi写入一个字符 140 ret = LzSpiWrite(SPI_BUS, 0, buf, 1); 141 if (ret != LZ_HARDWARE_SUCCESS){ 142 LZ_HARDWARE_LOGE(OLED_TAG, "%s:spi write error ret = %d", __func__, ret); 143 } 144 145 if (LzSpiDeinit(SPI_BUS) != LZ_HARDWARE_SUCCESS) 146 return LZ_HARDWARE_FAILURE; 147 148 return LZ_HARDWARE_SUCCESS; 149} 150``` 151