香港特别行政区网站建设_网站建设公司_Windows Server_seo优化
2026/1/18 0:58:34 网站建设 项目流程
#ifndef __SPI_H
#define __SPI_H#ifdef __cplusplus
extern "C" {
#endif#include <stm32f10x_spi.h>#include <stdint.h>void SPI1_SendRecvData(const uint8_t *send_data, uint8_t *recv_data, uint16_t len);
void SPI1_SendData(const uint8_t *data, uint16_t len);
void SPI1_RecvData(uint8_t *data, uint16_t len);#ifdef __cplusplus
}
#endif#endif /* __SPI_H */
#include "spi.h"#include <stm32f10x_gpio.h>
#include <stm32f10x_spi.h>#include <stdint.h>/*** @brief SPI1 时序开始**/
static inline void SPI1_Start(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 拉低NSS
}/*** @brief SPI1 时序结束**/
static inline void SPI1_Stop(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_4); // 拉高NSS
}/*** @brief SPI1 交换一个字节** @param byte 待交换的字节* @return uint8_t 交换后的字节*/
static uint8_t SPI1_SwapByte(uint8_t byte)
{// 1. 等待 TXEwhile (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);// 2. 发送数据SPI_I2S_SendData(SPI1, byte);// 3. 等待 RXNEwhile (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);// 4. 读取 DRreturn SPI_I2S_ReceiveData(SPI1);
}/*** @brief SPI1 发送一个字节** @param byte 待发送的字节*/
static void SPI1_SendByte(uint8_t byte)
{SPI1_SwapByte(byte);
}/*** @brief SPI1 接收一个字节** @return uint8_t 接收到的字节*/
static uint8_t SPI1_RecvByte(void)
{return SPI1_SwapByte(0xFF);
}/*** @brief SPI1 发送和接收数据** @param send_data 待发送的数据* @param recv_data 接收到的数据* @param len 发送和接收的字节数*/
void SPI1_SendRecvData(const uint8_t *send_data, uint8_t *recv_data, uint16_t len)
{SPI1_Start();for (uint16_t i = 0; i < len; i++) {recv_data[i] = SPI1_SwapByte(send_data[i]);}SPI1_Stop();
}/*** @brief SPI1 发送数据** @param data 待发送的数据* @param len 发送的字节数*/
void SPI1_SendData(const uint8_t *data, uint16_t len)
{SPI1_Start();for (uint16_t i = 0; i < len; i++) {SPI1_SendByte(data[i]);}SPI1_Stop();
}/*** @brief SPI1 接收数据** @param data 接收到的数据* @param len 接收的字节数*/
void SPI1_RecvData(uint8_t *data, uint16_t len)
{SPI1_Start();for (uint16_t i = 0; i < len; i++) {data[i] = SPI1_RecvByte();}SPI1_Stop();
}
enum class Status {Ok,Error,Busy,Timeout,
};
#pragma once#include <stm32f10x.h>#include <cstddef>
#include <cstdint>
#include <span>#include "main.hpp"class SPI_Handle
{
public:static constexpr uint32_t DefaultTimeout = 1000;SPI_Handle(SPI_TypeDef *spi_x = nullptr);operator bool() const;void set_spi_handle(SPI_TypeDef *spi_x);void set_cs_pin(GPIO_TypeDef *port, uint16_t pin);void set_timeout(uint32_t Timeout);auto spi_handle() const;auto timeout() const;auto cs_port() const;auto cs_pin() const;void Start();void Stop();Status SPI_TransmitReceive(uint8_t send_byte, uint8_t &receive_byte);Status Transmit(uint8_t send_byte);Status Receive(uint8_t &receive_byte);Status SPI_TransmitReceive(std::span<const uint8_t> transmit_data, std::span<uint8_t> receive_buffer);Status Transmit(std::span<const uint8_t> transmit_data);Status Receive(std::span<uint8_t> receive_buffer);protected:SPI_TypeDef *spi_x_;GPIO_TypeDef *cs_port_;uint16_t      cs_pin_;uint32_t timeout_;Status SPI_WaitFlagStatus(uint16_t SPI_I2S_FLAG);Status SPI_SwapByte(uint8_t send_byte, uint8_t &receive_byte);
};
#include "spi_handle.hpp"#include <stm32f10x.h>#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <ranges>
#include <span>#include "main.hpp"SPI_Handle::SPI_Handle(SPI_TypeDef *spi_x): spi_x_(spi_x),cs_port_(nullptr), cs_pin_(0),timeout_(Defaulttimeout)
{
}SPI_Handle::operator bool() const
{return this->spi_x_ != nullptr andthis->cs_port_ != nullptr andthis->cs_pin_ != 0;
}void SPI_Handle::set_spi_handle(SPI_TypeDef *spi_x) { this->spi_x_ = spi_x; }void SPI_Handle::set_cs_pin(GPIO_TypeDef *port, uint16_t pin)
{this->cs_port_ = port;this->cs_pin_  = pin;
}void SPI_Handle::set_timeout(uint32_t timeout) { this->timeout_ = timeout; }auto SPI_Handle::spi_handle() const { return this->spi_x_; }auto SPI_Handle::timeout() const { return this->timeout_; }auto SPI_Handle::cs_port() const { return this->cs_port_; }auto SPI_Handle::cs_pin() const { return this->cs_pin_; }void SPI_Handle::Start()
{if (this->cs_port_ != nullptr and this->cs_pin_ != 0) {GPIO_ResetBits(this->cs_port_, this->cs_pin_);}
}void SPI_Handle::Stop()
{if (this->cs_port_ != nullptr and this->cs_pin_ != 0) {GPIO_SetBits(this->cs_port_, this->cs_pin_);}
}Status SPI_Handle::SPI_TransmitReceive(uint8_t send_byte, uint8_t &receive_byte)
{return this->SPI_TransmitReceive(std::span<const uint8_t>{&send_byte, 1},std::span<uint8_t>{&receive_byte, 1});
}Status SPI_Handle::Transmit(uint8_t send_byte)
{return this->Transmit(std::span<const uint8_t>{&send_byte, 1});
}Status SPI_Handle::Receive(uint8_t &receive_byte)
{return this->Receive(std::span<uint8_t>{&receive_byte, 1});
}Status SPI_Handle::SPI_TransmitReceive(std::span<const uint8_t> transmit_data, std::span<uint8_t> receive_buffer)
{if (transmit_data.size() != receive_buffer.size()) {return Status::Error;}for (auto [send, receive] : std::ranges::views::zip(transmit_data, receive_buffer)) {auto ret = this->SPI_SwapByte(send, receive);if (ret != Status::Ok) {return ret;}}return Status::Ok;
}Status SPI_Handle::Transmit(std::span<const uint8_t> transmit_data)
{static uint8_t dummy = 0xFF;for (auto transmit_byte : transmit_data) {auto ret = this->SPI_SwapByte(transmit_byte, dummy);if (ret != Status::Ok) {return ret;}}return Status::Ok;
}Status SPI_Handle::Receive(std::span<uint8_t> receive_buffer)
{for (auto &receive_byte : receive_buffer) {auto ret = this->SPI_SwapByte(0xFF, receive_byte);if (ret != Status::Ok) {return ret;}}return Status::Ok;
}Status SPI_Handle::SPI_WaitFlagStatus(uint16_t SPI_I2S_FLAG)
{for (uint32_t i = 0; i < this->timeout_; i++) {if (SPI_I2S_GetFlagStatus(this->spi_x_, SPI_I2S_FLAG) == SET) {return Status::Ok;}}return Status::timeout;
}Status SPI_Handle::SPI_SwapByte(uint8_t send_byte, uint8_t &receive_byte)
{auto ret = Status::Ok;// 1. 等待 TXEret = this->SPI_WaitFlagStatus(SPI_I2S_FLAG_TXE);if (ret != Status::Ok) {return ret;}// 2. 发送数据SPI_I2S_SendData(this->spi_x_, send_byte);// 3. 等待 RXNEret = this->SPI_WaitFlagStatus(SPI_I2S_FLAG_RXNE);if (ret != Status::Ok) {return ret;}// 4. 读取 DRreceive_byte = SPI_I2S_ReceiveData(this->spi_x_);return ret;
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询