当前位置: 首页 > article >正文

STM32 模拟SPI 模式0

SPI 模式 0 的时钟极性(CPOL)为 0,时钟相位(CPHA)为 0。CPOL = 0 意味着时钟信号空闲时为低电平,CPHA = 0 表示在时钟信号的第一个跳变沿(上升沿)进行数据采样。

#include "stm32f10x.h"

// 定义SPI引脚
#define SPI_SCK_PIN GPIO_Pin_5
#define SPI_MISO_PIN GPIO_Pin_6
#define SPI_MOSI_PIN GPIO_Pin_7
#define SPI_CS_PIN GPIO_Pin_4
#define SPI_GPIO_PORT GPIOA

// 初始化SPI引脚
void SoftwareSPI_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置SCK和MOSI为推挽输出
    GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN | SPI_MOSI_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure);

    // 配置MISO为浮空输入
    GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure);

    // 配置CS为推挽输出
    GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure);

    // 使能CS
    GPIO_SetBits(SPI_GPIO_PORT, SPI_CS_PIN);
    // 空闲时SCK为低电平
    GPIO_ResetBits(SPI_GPIO_PORT, SPI_SCK_PIN);
}

// 发送一个字节数据
uint8_t SoftwareSPI_SendByte(uint8_t byte) {
    uint8_t i;
    uint8_t receivedByte = 0;

    for (i = 0; i < 8; i++) {
        // 设置MOSI引脚状态
        if (byte & 0x80) {
            GPIO_SetBits(SPI_GPIO_PORT, SPI_MOSI_PIN);
        } else {
            GPIO_ResetBits(SPI_GPIO_PORT, SPI_MOSI_PIN);
        }

        // 拉高时钟信号,产生上升沿
        GPIO_SetBits(SPI_GPIO_PORT, SPI_SCK_PIN);

        // 读取MISO引脚状态(上升沿采样)
        receivedByte <<= 1;
        if (GPIO_ReadInputDataBit(SPI_GPIO_PORT, SPI_MISO_PIN)) {
            receivedByte |= 0x01;
        }

        // 拉低时钟信号
        GPIO_ResetBits(SPI_GPIO_PORT, SPI_SCK_PIN);

        // 移动到下一位
        byte <<= 1;
    }

    return receivedByte;
}

// 主函数示例
int main(void) {
    SoftwareSPI_Init();

    // 使能CS
    GPIO_ResetBits(SPI_GPIO_PORT, SPI_CS_PIN);

    // 发送一个字节数据
    uint8_t sentByte = 0xAA;
    uint8_t receivedByte = SoftwareSPI_SendByte(sentByte);

    // 禁用CS
    GPIO_SetBits(SPI_GPIO_PORT, SPI_CS_PIN);

    while (1) {
        // 主循环
    }
}   

http://www.kler.cn/a/594339.html

相关文章:

  • 【数据结构】单源最短路径dijkstra算法描述及模板
  • 【Linux】信号:产生信号
  • Unity 接入抖音小游戏
  • 低代码与在线教育系统源码:企业内训平台开发的新思路
  • 智慧社区、智慧消防物联网解决方案PPT(68页)
  • 标准化欧氏距离公式
  • 移动端医疗AI诊断系统的设计思路与技术展望——多模态生理数据分析的理论框架探讨
  • uniapp配置代理解决跨域问题
  • C#入门学习记录(五)轻松掌握条件分支与循环语句
  • uniapp 实现的下拉菜单组件
  • 第四课:Python数组与链表(动态数据结构的深度探索)
  • 单台openEuler24.03 LTS下的开源大数据环境搭建
  • Spring 如何创建 Bean 实例的?
  • 智慧楼宇:科技编织的未来生活图景
  • 服务器数据恢复—服务器raid故障导致上层分区不可用的数据恢复案例
  • 下一代代币技术白皮书:合规化智能合约与零知识证明隐私协议
  • Android 和 Linux 之间关联和区别
  • FPGA 以太网通信(一)
  • AI鸟类识别技术革新生态监测:快瞳科技如何用“智慧之眼”守护自然?
  • 自定义Spark启动的metastore_db和derby.log生成路径