943|4

4

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

GD32F103硬件SPI与EEPROM(M95)实现数据读写 [复制链接]

本帖最后由 nine_e 于 2024-4-24 20:28 编辑

各位大佬帮我看看这个EEPROM读出为什么没有数据!!!!!!!!!!!!
//////////--------------------------------------初始化------------------------------------------//////////////
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
// NSS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_8 | GPIO_Pin_10;// GPIO_Pin_1--imu1 GPIO_Pin_4--imu2 GPIO_Pin_8--eeprom
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
CS_L_HIGH;
CS_R_HIGH;
CS_eeprom_HIGH;
GPIO_SetBits(GPIOA , GPIO_Pin_10);
}

 

void eepromIOConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    /* Enable GPIOC and GPIOB clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

      /* Configure PB.09 as Input pull-up */
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //上拉输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
      GPIO_SetBits(GPIOB , GPIO_Pin_0);

}

 

//这里针是对SPI1的初始化
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );//PORTA时钟使能
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA 5/6/7复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7); //PA567 上拉
SPI_Cmd(SPI1, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第1个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 10; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
//SPI1_ReadWriteByte(0xff);//启动传输
}
//////////--------------------------------------EEPROM------------------------------------------//////////////
EepromOperations_t EEPROM_Read(uint8_t* RxData, uint16_t ReadAddr, uint16_t NumByteToRead)
{
/* We gonna send all commands in one packet of 3 bytes */
uint8_t header[3];

header[0] = EEPROM_READ; // Send "Read from Memory" instruction
header[1] = ReadAddr >> 8; // Send 16-bit address
header[2] = ReadAddr;

// Select the EEPROM: Chip Select low
EEPROM_CS_LOW();

/* Send WriteAddr address byte to read from */
EEPROM_SendInstruction(header, 3);

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); // 读取接收数据
RxData = SPI_I2S_ReceiveData(SPI1);
printf("out RxData=%x\r\n",
RxData);

// Deselect the EEPROM: Chip Select high
EEPROM_CS_HIGH();

return EEPROM_STATUS_COMPLETE;
}

 

EepromOperations_t EEPROM_Write(uint8_t* TxData, uint16_t WriteAddr, uint16_t NumByteToWrite) 
{
  uint16_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
  uint16_t sEE_DataNum = 0;
 
  EepromOperations_t pageWriteStatus = EEPROM_STATUS_PENDING;
 
  Addr = WriteAddr % EEPROM_PAGE_SIZE;
  count = EEPROM_PAGE_SIZE - Addr;
  NumOfPage =  NumByteToWrite / EEPROM_PAGE_SIZE;
  NumOfSingle = NumByteToWrite % EEPROM_PAGE_SIZE;
 
  if (Addr == 0) { /* WriteAddr is EEPROM_PAGESIZE aligned  */
    if (NumOfPage == 0) { /* NumByteToWrite < EEPROM_PAGESIZE */
            sEE_DataNum = NumByteToWrite;
      pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
      if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
        return pageWriteStatus;
      }
    } else { /* NumByteToWrite > EEPROM_PAGESIZE */
      while (NumOfPage--) {
        sEE_DataNum = EEPROM_PAGE_SIZE;
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
        if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
          return pageWriteStatus;
        }
 
        WriteAddr +=  EEPROM_PAGE_SIZE;
        TxData += EEPROM_PAGE_SIZE;
      }
 
      sEE_DataNum = NumOfSingle;
      pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
      if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
        return pageWriteStatus;
      }
    }
  } else { /* WriteAddr is not EEPROM_PAGESIZE aligned  */
    if (NumOfPage == 0) { /* NumByteToWrite < EEPROM_PAGESIZE */
      if (NumOfSingle > count) { /* (NumByteToWrite + WriteAddr) > EEPROM_PAGESIZE */
        temp = NumOfSingle - count;
        sEE_DataNum = count;
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
        if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
          return pageWriteStatus;
        }
 
        WriteAddr +=  count;
        TxData += count;
 
        sEE_DataNum = temp;
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
      } else {
        sEE_DataNum = NumByteToWrite;
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
      }
 
      if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
                return pageWriteStatus;
      }
    } else { /* NumByteToWrite > EEPROM_PAGESIZE */
      NumByteToWrite -= count;
      NumOfPage =  NumByteToWrite / EEPROM_PAGE_SIZE;
      NumOfSingle = NumByteToWrite % EEPROM_PAGE_SIZE;
 
      sEE_DataNum = count;
 
      pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
      if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
        return pageWriteStatus;
      }
 
      WriteAddr +=  count;
      TxData += count;
 
      while (NumOfPage--) {
        sEE_DataNum = EEPROM_PAGE_SIZE;
 
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
        if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
          return pageWriteStatus;
        }
 
        WriteAddr +=  EEPROM_PAGE_SIZE;
        TxData += EEPROM_PAGE_SIZE;
      }
 
      if (NumOfSingle != 0) {
        sEE_DataNum = NumOfSingle;
 
        pageWriteStatus = EEPROM_WritePage(TxData, WriteAddr, sEE_DataNum);
 
        if (pageWriteStatus != EEPROM_STATUS_COMPLETE) {
          return pageWriteStatus;
        }
      }
    }
  }
 
  return EEPROM_STATUS_COMPLETE;
}

 

 

 

 

 

 

 

此帖出自GD32 MCU论坛

最新回复

看看是不是硬件的写保护那个引脚电平设置错误了,3脚和7脚,需要接VCC,才是关闭数据保持和写保护。   详情 回复 发表于 2024-4-28 10:32
点赞 关注
 

回复
举报

4

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
本帖最后由 nine_e 于 2024-4-25 15:33 编辑

大佬们,帮帮

此帖出自GD32 MCU论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
本帖最后由 nine_e 于 2024-4-26 16:41 编辑

大佬们,走过路过看一看,读可以读了,就是写不进去(呜呜呜呜呜)

EepromOperations_t eeprom_WritePage(uint8_t* TxData, uint16_t WriteAddr, uint16_t NumByteToWrite){
      /* We gonna send commands in one packet of 3 bytes */
  uint8_t header[3];
    u8 i;
 
  header[0] = EEPROM_WRITE;   // Send "Write to Memory" instruction
  header[1] = WriteAddr >> 8; // Send 16-bit address
  header[2] = WriteAddr;
    GPIO_SetBits(GPIOA , GPIO_Pin_10);
    sEE_WriteEnable();
//    sEE_WriteStatusRegister(NULL);
//    sEE_WriteEnable();
    // Select the EEPROM: Chip Select low
  EEPROM_CS_LOW();
    for(i=0;i<3;i++){
    SPI1_ReadWriteByte(header[ i ]);
    }
    for(i=0;i<NumByteToWrite;i++){
  SPI1_ReadWriteByte(*(TxData+i));
    }
    // Deselect the EEPROM: Chip Select high
  
    M95xx_DelayMs(1);
    EEPROM_CS_HIGH();
    M95xx_DelayMs(10);
  // Wait the end of EEPROM writing
  EEPROM_WaitStandbyState();
 
  // Disable the write access to the EEPROM
  sEE_WriteDisable();
    M95xx_DelayMs(10);
}

这是写入的新函数

此帖出自GD32 MCU论坛
 
 
 

回复

351

帖子

3

TA的资源

纯净的硅(初级)

4
 

看看是不是硬件的写保护那个引脚电平设置错误了,3脚和7脚,需要接VCC,才是关闭数据保持和写保护。

此帖出自GD32 MCU论坛

点评

дЩ   ед   лл  详情 回复 发表于 2024-4-30 09:52
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

5
 
本帖最后由 nine_e 于 2024-4-30 09:54 编辑
hjl2832 2024-4-28 10:32 谢谢楼上的大佬   已经解决了  不是写保护的问题  那些我之前全测过了都没有问题
此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
数字原理(全美经典学习指导系列)

39828 内容简介:   本书为大学工科电子技术类基础课教学参考书。本书主要内容有数制与编码、逻辑门、逻辑电路的化简、TT ...

DIY五路独立输出可调电源

经常用到各种用电设备的你,是不是总是为各种特殊规格的输出电源而头疼?今天DIYer就教你制作一款整合电源,不仅可以同时输出五 ...

我的Beaglebone学习历程-2

整理一下前面发的帖子,搞个总帖,方便大家交流。 1. BeagleBone 硬件性能测试 _周计划 https://bbs.eeworld.com.cn/thread-324 ...

省到极致的电吹风

本帖最后由 huaiqiao 于 2016-4-23 14:26 编辑 *背景:买了个电吹风,用了有两年了吧。但是今天洗完澡出来的时候,准备用一下 ...

为啥米数码管一直只现实0呢,按键没有反应

ORG 0000H LJMP MAIN ORG 0030H MAIN: ACALL KEYSCAN MOV A,30H MOV DPTR,#TABLE MOVC A,@A+DPTR MOV ...

dcdc电源模块高温失效原因分析

1、dcdc电源模块是一种运用功率半导体开关器件实现dcdc功率变换的开关电源。它广泛应用于远程及数据通信、计算机、办公自动化设 ...

38“万里”树莓派小车——ROS学习(ROS基本概念介绍,以小乌龟节点为例)

ROS是一个分布式框架,这个框架把原本松散的零部件耦合在了一起,为他们提供了通信架构。ROS官方中文教程。 ROS概念关系图 ...

【STM32MP135F-DK】4-舵机应用代码编写分享

本帖最后由 qiao--- 于 2023-12-7 20:19 编辑 在上一期我们成功驱动了舵机,不过我们是利用命令行的方式是让这舵机运行的,这 ...

【2024 DigiKey 创意大赛】物料开箱

德捷官网购买的东西到了,不得不说包装是真厚实。 834258 树莓派5 4G 834257 ESP32-S3开发板 834256 ESP3 ...

ATL431扩流电路接上负载之后,输出电压被拉低

本帖最后由 xiaxingxing 于 2024-10-25 21:21 编辑 如下图ATL431扩流电路+过流保护电路,实际物料,U1用的ATL431,Q2用的SI230 ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表