Files
stm32-cnn/HARDWARE/SPI/spi.c
2024-12-19 14:06:05 +08:00

165 lines
6.4 KiB
C
Raw 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驱动程序
// 作 者: 凌智电子
// 开始日期: 2018-08-04
// 完成日期: 2018-08-04
// 修改日期:
// 当前版本: V1.0
// 历史版本:
// - V1.0: (2018-08-04)LED IO 配置
// 调试工具: 凌智STM32F429+CycloneIV电子系统设计开发板、LZE_ST_LINK2
// 说 明:
//
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 头文件包含
//-----------------------------------------------------------------
#include "spi.h"
//-----------------------------------------------------------------
SPI_HandleTypeDef SPI_Handler; // SPI句柄
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
//-----------------------------------------------------------------
// void SPI_Init(void)
//-----------------------------------------------------------------
//
// 函数功能: SPI驱动程序配置成主机模式
// 入口参数: 无
// 返 回 值: 无
// 注意事项: 无
//
//-----------------------------------------------------------------
void SPI_Init(void)
{
SPI_Handler.Instance=SPIx; // SP4
SPI_Handler.Init.Mode=SPI_MODE_MASTER; // 设置SPI工作模式设置为主模式
SPI_Handler.Init.Direction=SPI_DIRECTION_2LINES; // 设置SPI单向或者双向的数据模式:SPI设置为双线模式
SPI_Handler.Init.DataSize=SPI_DATASIZE_8BIT; // 设置SPI的数据大小:SPI发送接收16位帧结构
SPI_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH; // 串行同步时钟的空闲状态为高电平
SPI_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; // 串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_Handler.Init.NSS=SPI_NSS_SOFT; // NSS信号由硬件NSS管脚还是软件使用SSI位管理:内部NSS信号有SSI位控制
SPI_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4;//定义波特率预分频的值:波特率预分频值为2,设置为45M时钟,高速模式
SPI_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; // 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_Handler.Init.TIMode=SPI_TIMODE_DISABLE; // 关闭TI模式
SPI_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;// 关闭硬件CRC校验
SPI_Handler.Init.CRCPolynomial=7; // CRC值计算的多项式
if (HAL_SPI_Init(&SPI_Handler) != HAL_OK) //初始化
{
Error_Handler();
}
__HAL_SPI_ENABLE(&SPI_Handler); // 使能SPI4
}
//-----------------------------------------------------------------
// void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
//-----------------------------------------------------------------
//
// 函数功能: SPI底层驱动时钟使能引脚配置
// 入口参数: SPI_HandleTypeDef *hspiSPI句柄
// 返 回 值: 无
// 注意事项: 此函数会被HAL_SPI_Init()调用
//
//-----------------------------------------------------------------
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_Initure;
SPI_MISO_GPIO_CLK_ENABLE(); // 使能SPI_MISO的GPIO时钟
SPI_MOSI_GPIO_CLK_ENABLE(); // 使能SPI_MOSI的GPIO时钟
SPI_CLK_GPIO_CLK_ENABLE(); // 使能SPI_CLK的GPIO时钟
SPI_CS_GPIO_CLK_ENABLE(); // 使能SPI_CS的GPIO时钟
__HAL_RCC_GPIOD_CLK_ENABLE(); // 使能PD11
SPI_CLK_ENABLE(); // 使能SPI4时钟
GPIO_Initure.Pin = SPI_CS_PIN; //PE4 -> SPI4_CS
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull = GPIO_NOPULL; //无上下拉
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; //高速模式
HAL_GPIO_Init(SPI_CS_GPIO_PORT, &GPIO_Initure);
GPIO_Initure.Pin = GPIO_PIN_11; //PD11 -> SPI使能信号与fpga端的约定
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull = GPIO_PULLUP; //上拉模式
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; //高速模式
HAL_GPIO_Init(GPIOD, &GPIO_Initure);
GPIO_Initure.Pin=SPI_MISO_PIN; // PE5 -> SPI4_MISO
GPIO_Initure.Mode=GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; // 上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; // 高速
GPIO_Initure.Alternate=SPI_MISO_AF; // 复用为SPI4
HAL_GPIO_Init(SPI_MISO_GPIO_PORT,&GPIO_Initure);
GPIO_Initure.Pin=SPI_MOSI_PIN; // PE6 -> SPI4_MOSI
GPIO_Initure.Mode=GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; // 上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; // 高速
GPIO_Initure.Alternate=SPI_MOSI_AF; // 复用为SPI4
HAL_GPIO_Init(SPI_MOSI_GPIO_PORT,&GPIO_Initure);
GPIO_Initure.Pin=SPI_CLK_PIN; // PE2 -> SPI4_SCK
GPIO_Initure.Mode=GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; // 上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; // 高速
GPIO_Initure.Alternate=SPI_CLK_AF; // 复用为SPI4
HAL_GPIO_Init(SPI_CLK_GPIO_PORT,&GPIO_Initure);
//初始高电平
HAL_GPIO_WritePin(SPI_CS_GPIO_PORT, SPI_CS_PIN, GPIO_PIN_SET);
}
//-----------------------------------------------------------------
// void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
//-----------------------------------------------------------------
//
// 函数功能: SPI速度设置函数
// 入口参数: u8 SPI_BaudRatePrescalerSPI_BAUDRATEPRESCALER_2~SPI_BAUDRATEPRESCALER_2 256
// 返 回 值: 无
// 注意事项: SPI速度=fAPB1/分频系数fAPB1时钟一般为45Mhz
//
//-----------------------------------------------------------------
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); // 判断有效性
__HAL_SPI_DISABLE(&SPI_Handler); // 关闭SPI
SPI_Handler.Instance->CR1&=0XFFC7; // 位3-5清零用来设置波特率
SPI_Handler.Instance->CR1|=SPI_BaudRatePrescaler; // 设置SPI速度
__HAL_SPI_ENABLE(&SPI_Handler); // 使能SPI
}
//-----------------------------------------------------------------
// u8 SPI1_ReadWriteByte(u8 TxData)
//-----------------------------------------------------------------
//
// 函数功能: SPI1读写一个字节
// 入口参数: u8 TxData 要写入的字节
// 返 回 值: u8 Rxdata读取到的字节
// 注意事项: 无
//
//-----------------------------------------------------------------
uint16_t SPI1_ReadWriteByte(uint16_t TxData)
{
u8 rx_data[2];
u8 tx_data[2];
u16 Rxdata;
tx_data[0] = (TxData >> 8) & 0xFF;
tx_data[1] = TxData & 0xFF;
HAL_SPI_TransmitReceive(&SPI_Handler,tx_data,rx_data,2, 1000);
Rxdata = (rx_data[0] << 8) | rx_data[1];
return Rxdata; // 返回收到的数据
}
//-----------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------