更新时间:2025-04-27 09:56:50下载pdf
SPI(Serial Peripheral Interface)是一种高速、全双工、同步的通信总线。SPI 以主从方式工作,通常有一个主设备和一个或多个从设备。
SPI 控制器的信号线描述如下:
SPI 典型接线方式如下:
SPI 总线支持的四种工作方式,取决于串行同步时钟极性 CPOL 和串行同步时钟相位 CPHA 的组合。
四种工作方式时序描述如下:
模式 0:CPOL = 0,CPHA = 0。SCK 串行时钟线空闲是为低电平,数据在 SCK 时钟的上升沿被采样,数据在 SCK 时钟的下降沿切换。
模式 1:CPOL = 0,CPHA = 1。SCK 串行时钟线空闲是为低电平,数据在 SCK 时钟的下降沿被采样,数据在 SCK 时钟的上升沿切换。
模式 2:CPOL = 1,CPHA = 0。SCK 串行时钟线空闲是为高电平,数据在 SCK 时钟的下降沿被采样,数据在 SCK 时钟的上升沿切换。
模式 3:CPOL= 1,CPHA=1。SCK 串行时钟线空闲是为高电平,数据在 SCK 时钟的上升沿被采样,数据在 SCK 时钟的下降沿切换。
OPERATE_RET tkl_spi_init(TUYA_SPI_NUM_E port, CONST TUYA_SPI_BASE_CFG_T *cfg);
功能描述:
参数:
port
:端口号。cfg
:SPI 基础配置。typedef struct {
TUYA_SPI_ROLE_E role;
TUYA_SPI_MODE_E mode;
TUYA_SPI_TYPE_E type;
TUYA_SPI_DATABITS_E databits;
TUYA_SPI_BIT_ORDER_E bitorder;
UINT_T freq_hz;
UINT_T spi_dma_flags; /*!< SPI dma format , 1 use dma */
} TUYA_SPI_BASE_CFG_T;
名字 | 定义 |
---|---|
TUYA_SPI_ROLE_INACTIVE | SPI 闲置 |
TUYA_SPI_ROLE_MASTER | SPI 全双工主模式 |
TUYA_SPI_ROLE_SLAVE | SPI 全双工从模式 |
TUYA_SPI_ROLE_MASTER_SIMPLEX | SPI 半双工主模式 |
TUYA_SPI_ROLE_SLAVE_SIMPLEX | SPI 半双工从模式 |
名字 | 定义 |
---|---|
TUYA_SPI_MODE0 | CPOL = 0, CPHA = 0 |
TUYA_SPI_MODE1 | CPOL = 0, CPHA = 1 |
TUYA_SPI_MODE2 | CPOL = 1, CPHA = 0 |
TUYA_SPI_MODE3 | CPOL = 1, CPHA = 1 |
名字 | 定义 | 备注 |
---|---|---|
TUYA_SPI_AUTO_TYPE | SS 管脚模式,硬件自动配置 | SS:slave select,对应 CS 片选管脚 |
TUYA_SPI_SOFT_TYPE | SS 管脚模式,软件手动配置 | - |
TUYA_SPI_SOFT_ONE_WIRE_TYPE | 三线模式,SS 管脚无效 | - |
名字 | 定义 |
---|---|
TUYA_SPI_DATA_BIT8 | 8 位数据位模式 |
TUYA_SPI_DATA_BIT16 | 16 位数据位模式 |
名字 | 定义 |
---|---|
TUYA_SPI_ORDER_MSB2LSB | 高位(MSB)在前,低位(LSB)在后 |
TUYA_SPI_ORDER_LSB2MSB | 低位(LSB)在前,高位(MSB)在后 |
返回值:
OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_deinit(TUYA_SPI_NUM_E port);
port
:端口号。OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_send(TUYA_SPI_NUM_E port, VOID_T *data, UINT16_T size);
port
:端口号。data
:待发送数据的缓冲区地址。size
:待发送数据的长度。OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_recv(TUYA_SPI_NUM_E port, VOID_T *data, UINT16_T size);
port
:端口号。data
:待接收数据的缓冲区地址。size
:待接收数据的长度。OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_transfer(TUYA_SPI_NUM_E port, VOID_T* send_buf, VOID_T* receive_buf, UINT32_T length);
port
:端口号。send_buf
:待发送数据的缓冲区地址。receive_buf
:待接收数据的缓冲区地址。length
:长度。OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_abort_transfer(TUYA_SPI_NUM_E port);
port
:端口号。OPRT_OK
:成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_get_status(TUYA_SPI_NUM_E port, TUYA_SPI_STATUS_T *status);
port
:端口号。TUYA_SPI_STATUS_T
的定义。名字 | 定义 | 备注 |
---|---|---|
busy: 1 | 传输/收发忙状态位 | 1:有效 |
data_lost: 1 | 数据丢失 | 1:有效 |
mode_fault: 1 | 模式错误 | 1:有效 |
OPERATE_RET tkl_spi_irq_init(TUYA_SPI_NUM_E port, TUYA_SPI_IRQ_CB cb);
port
:端口号。cb
:中断回调函数。OPRT_OK
成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_irq_enable(TUYA_SPI_NUM_E port);
port
:端口号。OPRT_OK
成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。OPERATE_RET tkl_spi_irq_disable(TUYA_SPI_NUM_E port);
port
:端口号。OPRT_OK
成功,其他请参考文件 tuya_error_code.h
> OS_ADAPTER_SPI
定义部分。INT32_T tkl_spi_get_data_count(TUYA_SPI_NUM_E port);
port
:端口号。< 0
:error≥ 0
:上次传输的字节长度tkl_spi_send
、tkl_spi_recv
和 tkl_spi_transfer
任一个的操作。void tuya_spi_test1(void)
{
OPERATE_RET ret;
TUYA_SPI_BASE_CFG_T cfg;
TUYA_SPI_STATUS_T status;
//receive buffer
char rcv_buf[8];
//data to send
char send_buf[8] = {0,1,2,3,4,5,6,7};
tkl_io_pinmux_config(TUYA_IO_PIN_0, TUYA_SPI0_MISO);
tkl_io_pinmux_config(TUYA_IO_PIN_1, TUYA_SPI0_MOSI);
tkl_io_pinmux_config(TUYA_IO_PIN_2, TUYA_SPI0_CS);
tkl_io_pinmux_config(TUYA_IO_PIN_3, TUYA_SPI0_CLK);
cfg.role = TUYA_SPI_ROLE_MASTER;
cfg.mode = TUYA_SPI_MODE0;
cfg.type = TUYA_SPI_AUTO_TYPE;
cfg.databits = TUYA_SPI_DATA_BIT8;
cfg.bitorder = TUYA_SPI_ORDER_MSB2LSB;
cfg.freq_hz = 1000000;
ret = tkl_spi_init(TUYA_SPI_NUM_0, &cfg);
if (ret != OPRT_OK) {
//fail
return;
}
ret = tkl_spi_send(TUYA_SPI_NUM_0, send_buf, 8);
if (ret < 0) {
//failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
ret = tkl_spi_recv(TUYA_SPI_NUM_0, rcv_buf, 8);
if (ret < 0) {
//failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
ret = tkl_spi_transfer(TUYA_SPI_NUM_0, send_buf,rcv_buf, 6);
if (ret < 0) {
//failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
//uninitialize iic
ret = tkl_spi_deinit(TUYA_SPI_NUM_0);
if (ret != 0) {
//failed
}
}
int event_flag = -1;
static void spi_event_cb(TUYA_SPI_NUM_E port, TUYA_SPI_IRQ_EVT_E event)
{
//printf("\nspi_event_cb_fun:%d\n",event);
event_flag = event;
}
void tuya_spi_test2(void)
{
OPERATE_RET ret;
TUYA_SPI_BASE_CFG_T cfg;
TUYA_SPI_STATUS_T status;
//receive buffer
char rcv_buf[6];
//data to send
char send_buf[6] = {0x90,0x0,0x0,0x0,0x0,0x0};
tkl_io_pinmux_config(TUYA_IO_PIN_0, TUYA_SPI0_MISO);
tkl_io_pinmux_config(TUYA_IO_PIN_1, TUYA_SPI0_MOSI);
tkl_io_pinmux_config(TUYA_IO_PIN_2, TUYA_SPI0_CS);
tkl_io_pinmux_config(TUYA_IO_PIN_3, TUYA_SPI0_CLK);
cfg.role = TUYA_SPI_ROLE_MASTER;
cfg.mode = TUYA_SPI_MODE0;
cfg.type = TUYA_SPI_AUTO_TYPE;
cfg.databits = TUYA_SPI_DATA_BIT8;
cfg.bitorder = TUYA_SPI_ORDER_MSB2LSB;
cfg.freq_hz = 1000000;
ret = tkl_spi_init(TUYA_SPI_NUM_0, &cfg);
if (ret != OPRT_OK) {
//fail
return;
}
tkl_spi_irq_init(TUYA_SPI_NUM_0 , spi_event_cb);
tkl_spi_irq_enable(TUYA_SPI_NUM_0);
event_flag = -1;
ret = tkl_spi_transfer(TUYA_SPI_NUM_0, send_buf,rcv_buf, 6);
if (ret < 0) {
//failed
}
while (TUYA_SPI_EVENT_TRANSFER_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
//up Transfer Complete
event_flag = -1;
ret = tkl_spi_send(TUYA_SPI_NUM_0, send_buf, 6);
if (ret < 0) {
//failed
}
while (TUYA_SPI_EVENT_TX_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
// up send Complete,
event_flag = -1;
ret = tkl_spi_recv(TUYA_SPI_NUM_0, rcv_buf, 6);
if (ret < 0) {
//failed
}
while (TUYA_SPI_EVENT_RX_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
// up recv Complete,
tkl_spi_irq_disable(TUYA_SPI_NUM_0);
//uninitialize iic
ret = tkl_spi_deinit(TUYA_SPI_NUM_0);
if (ret != 0) {
//failed
}
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈