SPI操作eeprom(CAT25160) chipon

发布于:2025-06-18 ⋅ 阅读:(15) ⋅ 点赞:(0)
SPI1_IO_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_Struct_Init(&GPIO_InitStructure);
	/* Configure PE9 SPI1_SS */
	GPIO_Struct_Init(&GPIO_InitStructure);
	GPIO_InitStructure.m_Mode = GPIO_MODE_OUT;
	GPIO_InitStructure.m_OpenDrain = GPIO_POD_PP;
	GPIO_InitStructure.m_PullDown = GPIO_NOPULL;
	GPIO_InitStructure.m_PullUp = GPIO_NOPULL;
	GPIO_InitStructure.m_Speed = GPIO_HIGH_SPEED;
	GPIO_InitStructure.m_Pin = GPIO_PIN_MASK_9;
	GPIO_Configuration(GPIOE_SFR, &GPIO_InitStructure);
	GPIO_Set_Output_Data_Bits(GPIOE_SFR, GPIO_PIN_MASK_9, Bit_SET);
	
	    /* Configure SPI1 IO */
	    /*
	     * SPI1_SCK = PF1
	     * SPI1_SDI = PF0
	     * SPI1_SDO = PB15
	     */
	GPIO_Write_Mode_Bits(GPIOF_SFR, GPIO_PIN_MASK_0 | GPIO_PIN_MASK_1, GPIO_MODE_RMP);
	GPIO_Write_Mode_Bits(GPIOB_SFR, GPIO_PIN_MASK_15, GPIO_MODE_RMP);
	
	GPIO_Pin_RMP_Config(GPIOF_SFR, GPIO_Pin_Num_0, GPIO_RMP_AF8);
	GPIO_Pin_RMP_Config(GPIOF_SFR, GPIO_Pin_Num_1, GPIO_RMP_AF8);
	GPIO_Pin_RMP_Config(GPIOB_SFR, GPIO_Pin_Num_15, GPIO_RMP_AF8);
}

SPI_Config(SPI_SFRmap *SPIx)
{
	 SPI_InitTypeDef Spi_ConfigPtr;

    /* SPI mode */
    Spi_ConfigPtr.m_Mode = SPI_MODE_MASTER_CLKDIV4;
    /* SPI clock */
    Spi_ConfigPtr.m_Clock = SPI_CLK_SCLK;
    /* Data transfer start control */
    Spi_ConfigPtr.m_FirstBit = SPI_FIRSTBIT_MSB;//高位优先
    /* Spi idle state */
    Spi_ConfigPtr.m_CKP = SPI_CKP_HIGH;
    /* Spi clock phase(Data shift edge) */
    Spi_ConfigPtr.m_CKE = SPI_CKE_2EDGE;//代表上升沿
    /* Data width */
    Spi_ConfigPtr.m_DataSize = SPI_DATASIZE_8BITS;
    /* Baud rate :Fck_spi=Fck/2(m_BaudRate+1)*/
    //120M/4/(2*150)=100k
    Spi_ConfigPtr.m_BaudRate = 0x95;//0x95

    /* Spi reset */
    SPI_Reset(SPIx);
    /* Configure SPI module */
    SPI_Configuration(SPIx, &Spi_ConfigPtr);
    /* Enable SPI module */
    SPI_Cmd(SPIx, TRUE);
}


void CS_Enable()
{
	//如果有其他从设备,记得把其他从设备的片选拉高,看情况而定,是否加些延时
	GPIO_Set_Output_Data_Bits(GPIOE_SFR, GPIO_PIN_MASK_9, reset);
}

void CS_Disable()
{
	//如果有其他从设备,记得把其他从设备的片选拉高
	GPIO_Set_Output_Data_Bits(GPIOE_SFR, GPIO_PIN_MASK_9, set);
}


void CAT25160_WriteEnable()
{
    CS_Enable();

    SPI_TransferByte(0x06);//写使能

    CS_Disable();
}



#define SPI_TIMEOUT 2048;

//基础SPI传输函数
uint8_t SPI_TransferByte(uint8_t data)
{
	uint32_t timeout = SPI_TIMEOUT;
	while ((SPI_Get_Transmit_Buf_Flag(SPI1_SFR) == SET)&& (timeout-- > 0));
	if(timeout == 0) return 0xFF;

	timeout = SPI_TIMEOUT;
	SPI_I2S_SendData32(SPI1_SFR, data);
	while((SPI_Get_Receive_Buf_Flag(SPI1_SFR) == RESET)&&(timeout-- > 0));
	if(timeout == 0) return 0xFF;

	return SPI_I2S_ReceiveData(SPI1_SFR);
}

uint8_t CAT25160_ReadStatus()
{
	uint8_t status;
    uint8_t cmd = 0x05; // RDSR指令
    CS_Enable();
    SPI_TransferByte(cmd);
    status = SPI_TransferByte(0xFF);
    CS_Disable();
    return status;
}

// 检查是否忙(RDY位)
uint8_t CAT25160_IsBusy()
{
    return (CAT25160_ReadStatus() & 0x01); // RDY在bit 0
}

void CAT25160_WriteDisable()
{
	 CS_Enable();
	 SPI_TransferByte(0x04); //WRDI 写禁用
	 CS_Disable();
}


void CAT25160_WriteByte(uint16_t addr, uint8_t data)//地址是16位的,高8位+低8位。地址范围(16Kb:0x0-0x07ff)
{
	CAT25160_WriteEnable();

	CS_Enable();

	SPI_TransferByte(0X02);//写memery
	SPI_TransferByte(addr>>8);
	SPI_TransferByte(addr & 0xFF);
	SPI_TransferByte(data);

	CS_Disable();
	while(CAT25160_ReadStatus() & 0x01);//1代表忙碌
}
#define PAGE_SIZE 32
void CAT25160_PageWrite(uint16_t addr, uint8_t *data, uint16_t len)//地址是16位的,高8位+低8位。地址范围(16Kb:0x0-0x07ff)
{
	while(len > 0)
	{
		// 计算当前页剩余空间
		uint8_t remaining = PAGE_SIZE - (addr % PAGE_SIZE);
		uint8_t chunk_len = (len > remaining) ? remaining : len;//remainning说明跨页,len说明不跨页。

		CAT25160_WriteEnable();//写使能,WREN指令后必须跟CS拉高才能激活写使能锁存器

		// 执行页写入
		CS_Enable();
		SPI_TransferByte(0X02);//写memery
		SPI_TransferByte(addr>>8);
		SPI_TransferByte(addr & 0xFF);
		for(uint8_t i=0; i<chunk_len; i++)
		{
			SPI_TransferByte(data[i]);
		}

		CS_Disable();


		// 等待写入完成
		while(CAT25160_ReadStatus() & 0x01); // RDSR

		// 更新指针
		addr += chunk_len;
		data += chunk_len;
		len -= chunk_len;
	 }
}


/* 读取数据 */
void CAT25160_ReadData(uint16_t addr, uint8_t *buf, uint16_t len)
{
	CS_Enable();

    SPI_TransferByte(0x03);
    SPI_TransferByte((addr >> 8)& 0xFF);
    SPI_TransferByte(addr & 0xFF);
    while(len--)
    	*buf++ = SPI_TransferByte(0xFF);

    CS_Disable();
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到