最近有个项目用到了STM32H743IIT6 ,调试SPI4和Flash通讯。一个是SPI4的时钟是50MHZ的,分频用SPI_BAUDRATEPRESCALER_8,低于SPI_BAUDRATEPRESCALER_8发现读取不成功,高于就CLK时钟频率稍微低。其次是作为主机模式必须配置MasterKeepIOState=SPI_MASTER_KEEP_IO_STATE_ENABLE; /* SPI主模式IO状态保持使能 */,不然发送完成后,CLK和MOSI还都有信号,以下是详细配置:
static SPI_HandleTypeDef SPI4_Handler; //SPI4句柄
void SPI_GPIOConfig(void)
{
GPIO_InitTypeDef gpio_init_struct;
RCC_PeriphCLKInitTypeDef spi4_clk_init;
__HAL_RCC_GPIOE_CLK_ENABLE(); //GPIOE
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14);
gpio_init_struct.Pin = GPIO_PIN_11;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_NOPULL;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
gpio_init_struct.Mode = GPIO_MODE_AF_PP;
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
gpio_init_struct.Alternate=GPIO_AF5_SPI4; //复用SPI4
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_11, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14, GPIO_PIN_SET);
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI4_ReadWriteByte(u8 TxData)
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&SPI4_Handler,&TxData,&Rxdata,1, 1000);
return Rxdata;
}
void SPI_Config(void)
{
SPI_GPIOConfig();
__HAL_RCC_SPI4_CLK_ENABLE(); //使能SPI4时钟
__HAL_SPI_DISABLE(&SPI4_Handler); /* 先关闭SPI4 */
SPI4_Handler.Instance = SPI4; /* SPI4 */
SPI4_Handler.Init.Mode = SPI_MODE_MASTER; /* 设置SPI工作模式,设置为主模式 */
SPI4_Handler.Init.Direction = SPI_DIRECTION_2LINES; /* 设置SPI单向或者双向的数据模式:SPI设置为双线模式 */
SPI4_Handler.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置SPI的数据大小:SPI发送接收8位帧结构 */
SPI4_Handler.Init.CLKPolarity = SPI_POLARITY_HIGH; /* 串行同步时钟的空闲状态为高电平 */
SPI4_Handler.Init.CLKPhase = SPI_PHASE_2EDGE; /* 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 */
SPI4_Handler.Init.NSS = SPI_NSS_SOFT; /* NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 */
SPI4_Handler.Init.NSSPMode=SPI_NSS_PULSE_DISABLE; /* NSS信号脉冲失能 */
SPI4_Handler.Init.MasterKeepIOState=SPI_MASTER_KEEP_IO_STATE_ENABLE; /* SPI主模式IO状态保持使能 */
SPI4_Handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; /* 定义波特率预分频的值:波特率预分频值为8 */
SPI4_Handler.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 */
SPI4_Handler.Init.TIMode = SPI_TIMODE_DISABLE; /* 关闭TI模式 */
SPI4_Handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 关闭硬件CRC校验 */
SPI4_Handler.Init.CRCPolynomial = 7; /* CRC值计算的多项式 */
HAL_SPI_Init(&SPI4_Handler); /* 初始化 */
__HAL_SPI_ENABLE(&SPI4_Handler); /* 使能SPI4 */
SPI4_ReadWriteByte(0Xff); /* 启动传输 */
}
//SPI4速度设置函数
void SPI4_SetSpeed(unsigned long SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(speed)); /* 判断有效性 */
__HAL_SPI_DISABLE(&SPI4_Handler); /* 关闭SPI */
SPI4_Handler.Instance->CR1 &= 0XFFC7; /* 位3-5清零,用来设置波特率 */
SPI4_Handler.Instance->CR1 |= SPI_BaudRatePrescaler; /* 设置SPI速度 */
__HAL_SPI_ENABLE(&SPI4_Handler); /* 使能SPI */
}
void Spi::Begin(void)
{
SPI_Config();
SPI4_SetSpeed(SPI_BAUDRATEPRESCALER_2);//设置为21M时钟,高速模式
W25QXX_TYPE = W25Q128; //默认是W25Q128
W25QXX_TYPE = W25QXX_ReadID(); //读取FLASH ID.
}
//读取芯片ID
//返回值如下:
//0XEF13,表示芯片型号为W25Q80
//0XEF14,表示芯片型号为W25Q16
//0XEF15,表示芯片型号为W25Q32
//0XEF16,表示芯片型号为W25Q64
//0XEF17,表示芯片型号为W25Q128
u16 Spi::W25QXX_ReadID(void)
{
u16 Temp = 0;
W25QXX_CS(0);
SPI4_ReadWriteByte(0x90);//发送读取ID命令
SPI4_ReadWriteByte(0x00);
SPI4_ReadWriteByte(0x00);
SPI4_ReadWriteByte(0x00);
Temp|=SPI4_ReadWriteByte(0xFF)<<8;
Temp|=SPI4_ReadWriteByte(0xFF);
W25QXX_CS(1);
return Temp;
}