Files
DTU-LCD/Drivers/BSP/SPI/spi.c
2026-01-24 20:03:14 +08:00

129 lines
4.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @文件 spi.c
* @作者 阜阳师范大学物电学院
* @版本 V0.1
* @日期 2025-03-28
* @简介 硬件 SPI 驱动程序
*******
**/
#include "spi.h"
// 定义一个SPI句柄结构体变量用于存储SPI的初始化参数和状态信息
SPI_HandleTypeDef SPI2_Handle;
/**
* @brief 初始化SPI2外设
*
* 该函数用于初始化SPI2外设配置SPI的工作模式、数据大小、时钟极性等参数
* 并使能SPI2外设。
*/
void SPI_Init(void)
{
// 使能SPI2的时钟确保SPI2外设能够正常工作
SPI2_SPI_CLK_ENABLE();
// 指定SPI实例为SPI2
SPI2_Handle.Instance = SPI2;
// 设置SPI工作模式为主机模式由该SPI设备控制通信过程
SPI2_Handle.Init.Mode = SPI_MODE_MASTER;
// 设置SPI通信方向为单线模式即只使用一条数据线进行通信
SPI2_Handle.Init.Direction = SPI_DIRECTION_1LINE;
// 设置SPI数据大小为8位每次传输8位数据
SPI2_Handle.Init.DataSize = SPI_DATASIZE_8BIT;
// 设置SPI时钟极性为高电平即空闲状态下时钟信号为高电平
SPI2_Handle.Init.CLKPolarity = SPI_POLARITY_HIGH;
// 设置SPI时钟相位为第二个边沿采样数据
SPI2_Handle.Init.CLKPhase = SPI_PHASE_2EDGE; /*上升沿采样数据*/
// 设置SPI片选信号为软件控制
SPI2_Handle.Init.NSS = SPI_NSS_SOFT;
// 设置SPI波特率预分频器为256降低SPI通信速率
SPI2_Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
// 设置SPI数据传输的起始位为高位在前
SPI2_Handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
// 禁用SPI的TI模式
SPI2_Handle.Init.TIMode = SPI_TIMODE_DISABLE;
// 禁用SPI的CRC计算功能
SPI2_Handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
// 设置CRC多项式为7虽然已禁用CRC计算但仍需设置该参数
SPI2_Handle.Init.CRCPolynomial = 7;
// 根据上述配置初始化SPI2外设
HAL_SPI_Init(&SPI2_Handle);
// 使能SPI2外设开始工作
__HAL_SPI_ENABLE(&SPI2_Handle);
}
/**
* @brief SPI外设的底层硬件初始化函数
*
* 该函数用于初始化SPI外设所使用的GPIO引脚包括时钟线、数据线等。
*
* @param hspi 指向SPI句柄结构体的指针用于指定要初始化的SPI实例
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
// 定义一个GPIO初始化结构体变量用于配置GPIO引脚的参数
GPIO_InitTypeDef gpio_init_struct;
// 判断要初始化的SPI实例是否为SPI2
if (hspi->Instance == SPI2)
{
// 使能SPI2的MOSI引脚的时钟
SPI_MOSI_GPIO_CLK_ENABLE();
// 注释掉的代码原本可能用于使能SPI2的MISO引脚的时钟
// SPI_MISO_GPIO_CLK_ENABLE();
// 使能SPI2的时钟线引脚的时钟
SPI_CLK_GPIO_CLK_ENABLE();
// 配置SPI2的时钟线引脚
gpio_init_struct.Pin = SPI_CLK_GPIO_PIN;
// 设置引脚模式为复用推挽输出用于连接SPI时钟信号
gpio_init_struct.Mode = GPIO_MODE_AF_PP;
// 设置引脚速度为高频
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
// 根据上述配置初始化SPI2的时钟线引脚
HAL_GPIO_Init(SPI_CLK_GPIO_PORT, &gpio_init_struct);
// 注释掉的代码原本可能用于配置SPI2的MISO引脚
// MISO引脚模式设置(复用输出)
// gpio_init_struct.Pin = SPI_MISO_GPIO_PIN;
// HAL_GPIO_Init(SPI_MISO_GPIO_PORT, &gpio_init_struct);
// 配置SPI2的MOSI引脚
gpio_init_struct.Pin = SPI_MOSI_GPIO_PIN;
// 设置引脚模式为复用推挽输出用于连接SPI数据输出信号
gpio_init_struct.Mode = GPIO_MODE_AF_PP;
// 设置引脚速度为高频
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
// 根据上述配置初始化SPI2的MOSI引脚
HAL_GPIO_Init(SPI_MOSI_GPIO_PORT, &gpio_init_struct);
}
}
/**
* @简介 SPI 写入一个字节8位
* @输入参数 pData要写入的数据指针
* @输入参数 Size要写入的数据大小
* @输入参数 dir1 数据从后面往前发送 0数据从前往后发送
* @注意事项 此函数是高位优先写入
* @返回值 无
*/
void Hard_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint8_t dir)
{
uint16_t i = 0;
dir ? pData += (Size-1): pData;
for(i =0; i < Size; i++)
{
HAL_SPI_Transmit(hspi, pData, 1, 1000);
dir ? pData--: pData++;
}
}