关于STM32标准库硬件SPI,HAL库硬件SPI和软件SPI中空读语句和发送哑数据的问题

先说下结论:标准库硬件SPI在读写SPI混用时,需要在写后读前添加空读语句,主要是把上一条写语句时,从设备发送过来的数据读取掉,以便不影响后续读数据      

/*******************************************************************************
* 函数名  : Read_W5500_SOCK_2Byte
* 描述    : 读W5500指定端口寄存器的2个字节数据
* 输入    : s:端口号,reg:16位寄存器地址
* 输出    : 无
* 返回值  : 读取到寄存器的2个字节数据(16位)
* 说明    : 无
*******************************************************************************/
unsigned short Read_W5500_SOCK_2Byte(SOCKET s, unsigned short reg)
{
    unsigned short i;

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM2|RWB_READ|(s*0x20+0x08));//通过SPI1写控制字节,2个字节数据长度,读数据,选择端口s的寄存器

    i=SPI_I2S_ReceiveData(SPI1);//添加 空读语句,主要是把上一条写语句时,从设备发送过来的数据读取掉,以便不影响后续读数据


    SPI1_Send_Byte(0x00);//发送一个哑数据//添加 哑数据,为读取有效数据提供时钟信号(因为spi是全双工的,只有在发送数据的时候才会产生时钟,让从机返回数据)
    i=SPI_I2S_ReceiveData(SPI1);//读取高位数据


    SPI1_Send_Byte(0x00);//发送一个哑数据//添加 哑数据,为读取有效数据提供时钟信号(因为spi是全双工的,只有在发送数据的时候才会产生时钟,让从机返回数据)
    i*=256;
    i+=SPI_I2S_ReceiveData(SPI1);//读取低位数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为高电平
    return i;//返回读取到的寄存器数据
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,配置STM32G030的SPI1和SPI2通过DMA发送两个数组的数据,可以参考以下步骤: 1. 首先,需要在STM32CubeMX中配置SPI1和SPI2的基本参数,如时钟源、工作模式、数据位数、NSS模式等。 2. 然后,需要配置DMA通道,将SPI发送缓冲区与DMA传输相关联。对于SPI1和SPI2,可以使用不同的DMA通道。 3. 接下来,需要编写代码实现数据发送。在使用DMA发送数据时,需要按照以下步骤进行操作: (1) 配置DMA通道和缓冲区:设置DMA通道的配置参数,包括传输方向、传输数据大小、内存地址和外设地址等。同时设置缓冲区地址。 (2) 启动DMA传输:使能DMA传输,并开启SPI发送中断。 (3) 等待传输完成:在中断服务程序中等待DMA传输完成,并进行相应的处理。 4. 最后,可以根据具体需要进行数据接收和处理等操作。 下面是一个简单的代码示例,以SPI1为例: ```c #include "stm32g0xx_hal.h" #define TX_SIZE 10 // 发送缓冲区大小 uint8_t tx_buf[TX_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}; // 发送缓冲区 /* DMA传输完成回调函数 */ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { /* DMA传输完成处理 */ } int main(void) { /* 初始化HAL库 */ HAL_Init(); /* 配置SPI1 */ SPI_HandleTypeDef hspi1; hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; HAL_SPI_Init(&hspi1); /* 配置SPI1 DMA通道 */ DMA_HandleTypeDef hdma_spi1_tx; hdma_spi1_tx.Instance = DMA1_Channel3; hdma_spi1_tx.Init.Request = DMA_REQUEST_2; hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_spi1_tx.Init.Mode = DMA_NORMAL; hdma_spi1_tx.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_spi1_tx); /* 将SPI1发送缓冲区与DMA通道相关联 */ __HAL_LINKDMA(&hspi1, hdmatx, hdma_spi1_tx); /* 启动SPI1 DMA传输 */ HAL_SPI_Transmit_DMA(&hspi1, tx_buf, TX_SIZE); while (1) { /* 其他操作 */ } } ``` 关于SPI2和数据接收处理部分的代码,请参考STM32G030的相关文档和参考手册进行详细学习和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值