#include "spi.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI1 GPIO Configuration
PB3 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PB3 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
uint8_t spi1_read_write_byte(uint8_t txdata)
{
uint8_t rxdata;
HAL_SPI_TransmitReceive(&hspi1, &txdata, &rxdata, 1, 1000);
return rxdata; /* ·µ»ØÊÕµ½µÄÊý¾Ý */
}
void spi1_set_speed(uint8_t speed)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(speed)); /* ÅжÏÓÐЧÐÔ */
__HAL_SPI_DISABLE(&hspi1); /* ¹Ø±ÕSPI */
hspi1.Instance->CR1 &= 0XFFC7; /* λ3-5ÇåÁ㣬ÓÃÀ´ÉèÖò¨ÌØÂÊ */
hspi1.Instance->CR1 |= speed << 3; /* ÉèÖÃSPIËÙ¶È */
__HAL_SPI_ENABLE(&hspi1); /* ʹÄÜSPI */
}
/* USER CODE END 1 */
上面是spi.c文件是stm32cubmx生成的
下面是w245q128的驱动文件
#include "spi.h"
#include "norflash.h"
uint16_t g_norflash_type = W25Q128;
void norflash_init(void)
{
uint8_t temp;
NORFLASH_CS_GPIO_CLK_ENABLE();
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.Pin = NORFLASH_CS_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(NORFLASH_CS_GPIO_PORT, &gpio_init_struct);
NORFLASH_CS(1);
MX_SPI1_Init();
if (g_norflash_type == W25Q256)
{
temp = norflash_read_sr(3);
if ((temp & 0X01) == 0)
{
norflash_write_enable();
temp |= 1 << 1;
norflash_write_sr(3, temp);
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_Enable4ByteAddr);
NORFLASH_CS(1);
}
}
}
static void norflash_wait_busy(void)
{
while ((norflash_read_sr(1) & 0x01) == 0x01); /* µÈ´ýBUSYλÇå¿Õ */
}
void norflash_write_enable(void)
{
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_WriteEnable);
NORFLASH_CS(1);
}
static void norflash_send_address(uint32_t address)
{
if (g_norflash_type == W25Q256)
{
spi1_read_write_byte((uint8_t)((address)>>24));
}
spi1_read_write_byte((uint8_t)((address)>>16));
spi1_read_write_byte((uint8_t)((address)>>8));
spi1_read_write_byte((uint8_t)address);
}
uint8_t norflash_read_sr(uint8_t regno)
{
uint8_t byte = 0, command = 0;
switch (regno)
{
case 1:
command = FLASH_ReadStatusReg1;
break;
case 2:
command = FLASH_ReadStatusReg2;
break;
case 3:
command = FLASH_ReadStatusReg3;
break;
default:
command = FLASH_ReadStatusReg1;
break;
}
NORFLASH_CS(0);
spi1_read_write_byte(command);
byte = spi1_read_write_byte(0Xff);
NORFLASH_CS(1);
return command;
}
void norflash_write_sr(uint8_t regno, uint8_t sr)
{
uint8_t command = 0;
switch (regno)
{
case 1:
command = FLASH_WriteStatusReg1;
break;
case 2:
command = FLASH_WriteStatusReg2;
break;
case 3:
command = FLASH_WriteStatusReg3;
break;
default:
command = FLASH_WriteStatusReg1;
break;
}
NORFLASH_CS(0);
spi1_read_write_byte(command);
spi1_read_write_byte(sr);
NORFLASH_CS(1);
}
uint16_t norflash_read_id(void)
{
uint16_t deviceid;
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_ManufactDeviceID);
spi1_read_write_byte(0);
spi1_read_write_byte(0);
spi1_read_write_byte(0);
deviceid = spi1_read_write_byte(0xFF) << 8;
deviceid |= spi1_read_write_byte(0xFF);
NORFLASH_CS(1);
return deviceid;
}
void norflash_read(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
uint16_t i;
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_ReadData);
norflash_send_address(addr);
for (i = 0; i < datalen; i++)
{
pbuf[i] = spi1_read_write_byte(0XFF);
}
NORFLASH_CS(1);
}
void norflash_write_page(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
uint16_t i;
norflash_write_enable();
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_PageProgram);
norflash_send_address(addr);
for (i = 0; i < datalen; i++)
{
spi1_read_write_byte(pbuf[i]);
}
NORFLASH_CS(1);
norflash_wait_busy();
}
static void norflash_write_nocheck(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
uint16_t pageremain;
pageremain = 256 - addr % 256;
if (datalen <= pageremain)
{
pageremain = datalen;
}
while (1)
{
norflash_write_page(pbuf, addr, pageremain);
if (datalen == pageremain) /* дÈë½áÊøÁË */
{
break;
}
else
{
pbuf += pageremain;
addr += pageremain;
datalen -= pageremain;
if (datalen > 256)
{
pageremain = 256;
}
else
{
pageremain = datalen;
}
}
}
}
uint8_t g_norflash_buf[4096];
void norflash_write(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
uint8_t *norflash_buf;
norflash_buf = g_norflash_buf;
secpos = addr / 4096;
secoff = addr % 4096;
secremain = 4096 - secoff;
if (datalen <= secremain)
{
secremain = datalen;
}
while (1)
{
norflash_read(norflash_buf, secpos * 4096, 4096);
for (i = 0; i < secremain; i++)
{
if (norflash_buf[secoff + i] != 0XFF)
{
break;
}
}
if (i < secremain)
{
norflash_erase_sector(secpos);
for (i = 0; i < secremain; i++)
{
norflash_buf[i + secoff] = pbuf[i];
}
norflash_write_nocheck(norflash_buf, secpos * 4096, 4096);
}
else
{
norflash_write_nocheck(pbuf, addr, secremain);
}
if (datalen == secremain)
{
break;
}
else
{
secpos++;
secoff = 0;
pbuf += secremain;
addr += secremain;
datalen -= secremain;
if (datalen > 4096)
{
secremain = 4096;
}
else
{
secremain = datalen;
}
}
}
}
void norflash_erase_chip(void)
{
norflash_write_enable();
norflash_wait_busy();
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_ChipErase);
NORFLASH_CS(1);
norflash_wait_busy();
}
void norflash_erase_sector(uint32_t saddr)
{
saddr *= 4096;
norflash_write_enable();
norflash_wait_busy();
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_SectorErase);
norflash_send_address(saddr);
NORFLASH_CS(1);
norflash_wait_busy();
}
在main函数中为什么按下KEY_left后按下key_right没有任何反应,而删除掉 norflash_write(writePage0,0x00,256);norflash_write(writePage1,0xff,256);后,就是key_right和key_left可以按下互相有反应,难道是因为spi与flash通信失败吗,但是单片机又可以读到flash的型号,恳求指教。
uint8_t writePage0[256]={"Hello for begining"};
uint8_t writePage1[256]={"Hello in Page"};
uint8_t readPage0[256];
uint8_t readPage1[256];
if(key==KEY_left)
{
lcd_fill(0,180,strlen("Write in page 0= Hello for begining")*6,260,WHITE);
lcd_show_str(60,200,16,"Write is ok!",RED);
lcd_show_str(0,220,12,"Write in page 0:",RED);
lcd_show_str(strlen("Write in page 0=")*6, 220, 12, (char *)writePage0, BLUE);
lcd_show_str(0,240,12,"Write in page 1:",RED);
lcd_show_str(strlen("Write in page 1=:")*6, 240, 12, (char *)writePage1, BLUE);
norflash_write(writePage0,0x00,256);
norflash_write(writePage1,0xff,256);
}
if(key==KEY_right)
{
lcd_fill(0,200,strlen("Write in page 0= Hello for begining")*6,260,WHITE);
norflash_read(readPage0,0x00,256);
norflash_read(readPage1,0xff,256);
lcd_show_str(0,220,12,"Read page 0:",RED);
lcd_show_str(strlen("Read page 0:")*6, 220, 12, (char *)readPage0, BLUE);
lcd_show_str(0,240,12,"Read page 1:",RED);
lcd_show_str(strlen("Read page 1:")*6, 240, 12, (char *)readPage1, BLUE);
}
说明SPI接口写入norflash卡死在write函数里了,到之后的程序没法执行。