• STM32 - SPI硬件外设


    配合我的上一篇SPI ​​​​​​通信 协议-CSDN博客一起理解更佳,本文后看

           SPI 是由摩托罗拉(Motorola)公司开发的全双工同步串行总线,是 MCU 和外围设备之间进行通信的同步串行端口。主要应用在EEPROM、Flash、RTC、ADC、网络控制器、MCU、DSP以及数字信号解码器之间。SPI 系统可直接与各个厂家生产的多种标准外围器件直接接口,一般使用4 条线:SCK、MISO、MOSI 、SS

    STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担

    • 可配置8位/16位数据帧、高位先行/低位先行
    • 时钟频率: fPCLK / (2, 4, 8, 16, 32, 64, 128, 256) 支持多主机模型、主或从操作
    • 可精简为半双工/单工通信
    • 支持DMA 兼容I2S协议

    STM32F103C8T6 硬件SPI资源:SPI1(APB2)、SPI2(APB1

    SPI基本图 

    NSS :从设备选择。这是一个可选的引脚,用来选择主 / 从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。
    LSBFIRST是低位先行 。如果是MSBFIRST,那么就是高位先行,
    此时MISO和MOSI需要换,如图的另一种指法。

    SPI基本结构 

    注意:该图是高位先行 

    主模式传输 

    主模式、全双工模式下
    连续传输(BIDIMODE=0并且RXONLY=0)时
    TXE/RXNE/BSY 的变化示意图

     

    本质上来说:第一个字节数据发送,发送时下一个字节就已经到发送缓冲器等待,当第一个字节发送成功,立马发送第二个,第三个字节进入发送缓冲器等待 。

    非连续传输发送(BIDIMODE=0并且RXONLY=0)

    TXE/BSY变化示意图 

    非连续传输发送来说:第一个字节数据发送,发送成功后,下一个字节才到发送缓冲器,再发送第二个,等发送成功后,第三个字节再进入发送缓冲器

    代码 

    1. /**
    2. * 函 数:SPI初始化
    3. * 参 数:无
    4. * 返 回 值:无
    5. */
    6. void MySPI_Init(void)
    7. {
    8. /*开启时钟*/
    9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
    10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //开启SPI1的时钟
    11. /*GPIO初始化*/
    12. GPIO_InitTypeDef GPIO_InitStructure;
    13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    14. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    15. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    16. GPIO_Init(GPIOA, &GPIO_InitStructure);
    17. //将PA4引脚初始化为推挽输出
    18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    19. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    21. GPIO_Init(GPIOA, &GPIO_InitStructure);
    22. //将PA5和PA7引脚初始化为复用推挽输出
    23. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    24. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    25. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    26. GPIO_Init(GPIOA, &GPIO_InitStructure);
    27. //将PA6引脚初始化为上拉输入
    28. /*SPI初始化*/
    29. SPI_InitTypeDef SPI_InitStructure; //定义结构体变量
    30. SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //模式,选择为SPI主模式
    31. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    32. //方向,选择2线全双工
    33. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据宽度,选择为8位
    34. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //先行位,选择高位先行
    35. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
    36. //波特率分频,选择128分频
    37. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //SPI极性,选择低极性
    38. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    39. //SPI相位,选择第一个时钟边沿采样,极性和相位决定选择SPI模式0
    40. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS,选择由软件控制
    41. SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多项式,暂时用不到,给默认值7
    42. SPI_Init(SPI1, &SPI_InitStructure);
    43. //将结构体变量交给SPI_Init,配置SPI1
    44. /*SPI使能*/
    45. SPI_Cmd(SPI1, ENABLE); //使能SPI1,开始运行
    46. /*设置默认电平*/
    47. MySPI_W_SS(1); //SS默认高电平
    48. }
    SPI起始 
    1. void MySPI_W_SS(uint8_t BitValue)
    2. {
    3. GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
    4. //根据BitValue,设置SS引脚的电平
    5. }
    6. /**
    7. * 函 数:SPI起始
    8. * 参 数:无
    9. * 返 回 值:无
    10. */
    11. void MySPI_Start(void)
    12. {
    13. MySPI_W_SS(0); //拉低SS,开始时序
    14. }
    SPI终止 
    1. /**
    2. * 函 数:SPI终止
    3. * 参 数:无
    4. * 返 回 值:无
    5. */
    6. void MySPI_Stop(void)
    7. {
    8. MySPI_W_SS(1); //拉高SS,终止时序
    9. }
    交换一个字节 
    1. /**
    2. * 函 数:SPI交换传输一个字节,使用SPI模式0
    3. * 参 数:ByteSend 要发送的一个字节
    4. * 返 回 值:接收的一个字节
    5. */
    6. uint8_t MySPI_SwapByte(uint8_t ByteSend)
    7. {
    8. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
    9. //等待发送数据寄存器空
    10. SPI_I2S_SendData(SPI1, ByteSend);
    11. //写入数据到发送数据寄存器,开始产生时序
    12. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);
    13. //等待接收数据寄存器非空
    14. return SPI_I2S_ReceiveData(SPI1);
    15. //读取接收到的数据并返回
    16. }

  • 相关阅读:
    SpringBoot篇之集成Mybatis-plus
    HTML5期末大作业:基于HTML+CSS+JavaScript茶文化中国水墨风格绿色茶叶销售(5页) 学生网页设计作业源码
    赋安消防主机FS5050,波特率20k,单模单芯SC接头,9-36V直流供电的光纤联网方式之一
    谷粒商城----缓存与分布式锁
    技术分享 | TiUP工具 - TiDB集群滚动升级核心流程解析
    【解决】openeuler22部署k8s提示/opt/cni/bin缺少资源问题
    socket编程常用API
    UDP报文结构
    加固数据安全:Java助力保护Excel文件,让数据无懈可击
    工业检测 ocr
  • 原文地址:https://blog.csdn.net/weixin_51738481/article/details/140273165