你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32驱动SPI接口EEPROM,AT25010、AT25020、AT25040

[复制链接]
STMCU小助手 发布时间:2022-4-23 16:44
一、源代码

  1. void eeprom_init()
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;
  4.          SPI_InitTypeDef  SPI_InitStructure;
  5.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能

  6.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;  // PB12 推挽
  7.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
  8.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  10.         GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_12);



  11.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
  12.         RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能         

  13.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

  17.          GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

  18.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  19.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
  20.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
  21.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
  22.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
  23.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  24.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
  25.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  26.         SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
  27.         SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

  28.         SPI_Cmd(SPI2, ENABLE); //使能SPI外设
  29.         
  30.         eeprom_read_write_byte(0xff);//启动传输               
  31. }
  32. //SPI 速度设置函数
  33. //SpeedSet:
  34. //SPI_BaudRatePrescaler_2   2分频   
  35. //SPI_BaudRatePrescaler_8   8分频   
  36. //SPI_BaudRatePrescaler_16  16分频  
  37. //SPI_BaudRatePrescaler_256 256分频

  38. void eeprom_set_speed(u8 SPI_BaudRatePrescaler)
  39. {
  40.   assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
  41.         SPI2->CR1&=0XFFC7;
  42.         SPI2->CR1|=SPI_BaudRatePrescaler;        //设置SPI2速度
  43.         SPI_Cmd(SPI2,ENABLE);

  44. }
复制代码
  1. //SPIx 读写一个字节
  2. //TxData:要写入的字节
  3. //返回值:读取到的字节
  4. u8 eeprom_read_write_byte(u8 TxData)
  5. {               
  6.         u8 retry=0;                                         
  7.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
  8.                 {
  9.                 retry++;
  10.                 if(retry>200)return 0;
  11.                 }                          
  12.         SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
  13.         retry=0;

  14.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
  15.                 {
  16.                 retry++;
  17.                 if(retry>200)return 0;
  18.                 }                                                              
  19.         return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据                                            
  20. }
复制代码
  1. //==============================================================================
  2. // 描述: 在AT25读状态寄存器
  3. // 输入: 无
  4. // 返回: unsigned char dat 状态寄存器数据
  5. //==============================================================================


  6. u8 eeprom_read_sr(void)
  7. {
  8.         u8 dat;
  9.         eeprom_cs=0;
  10.         eeprom_read_write_byte(RDSR);        //  定入指令0x05
  11.         dat = eeprom_read_write_byte(0xff);       //  读回数据
  12.         eeprom_cs=1;
  13.         return  dat;
  14. }

  15. //==============================================================================
  16. // 描述: 向AT25写入一个数据
  17. // 输入: unsigned char Dat 字符数据
  18. //       unsigned int addr 写入的地址
  19. // 返回: 无
  20. //==============================================================================
  21. void eeprom_write_byte(u16 addr,u8 Dat)
  22. {
  23.         unsigned char Add;
  24.         while(eeprom_read_sr()&RDY);                   // 读状态寄存器
  25.         
  26.         eeprom_cs=0;
  27.         eeprom_read_write_byte(WREN);                           // 写使能锁存
  28.         eeprom_cs=1;
  29.         
  30.         eeprom_cs=0;                                  // 芯片使能
  31.         // 写入写操作指令
  32.         if(addr>0x00ff)
  33.                 eeprom_read_write_byte((WRITE|0x08));           // 地址大于255
  34.         else
  35.                 eeprom_read_write_byte(WRITE);                  // 地址小于255

  36.         // 写入地址
  37.         Add = (unsigned char)(addr & 0xff);             // 将地址换成8位
  38.         eeprom_read_write_byte(Add);

  39.         // 写入数据
  40.         eeprom_read_write_byte(Dat);
  41.         eeprom_cs=1;                                // 芯片关闭   
  42. }
  43. //==============================================================================
  44. // 描述: 在AT25读一个字节操作
  45. // 输入: 无
  46. // 返回: unsigned char dat 读出一个字符数据
  47. //==============================================================================
  48. u8 eeprom_read_byte(u16 addr)
  49. {
  50.         u8 dat,add;
  51.         while(eeprom_read_sr()&RDY);                   // 读状态寄存器  
  52.         eeprom_cs=0;
  53.         // 写入写操作指令
  54.         if(addr>0x00ff)
  55.                 eeprom_read_write_byte((READ | 0x08));         // 地址大于255
  56.         else
  57.                 eeprom_read_write_byte(READ);                  // 地址小于255

  58.         // 写入地址
  59.         add = (unsigned char)(addr & 0xff);             // 将地址换成8位
  60.         eeprom_read_write_byte(add);

  61.         // 读出一个数据
  62.         dat=eeprom_read_write_byte(0xff);
  63.         eeprom_cs=1;
  64.         return dat;
  65. }
  66. //==============================================================================
  67. // 描述: 向AT25连续写入数据
  68. // 输入: unsigned char *PC 写入数据指针
  69. //       unsigned int count 写入数量计数  
  70. //       unsigned int SatAddr 写入起始地址
  71. // 返回: 无
  72. //==============================================================================
  73. void eeprom_write_buf(u16 startAddr,u8 *buf,u16 count)
  74. {
  75.         u8 Add;
  76.         u16 i;
  77.         while(eeprom_read_sr()&RDY);                   // 读状态寄存器

  78.         eeprom_cs=0;
  79.         eeprom_read_write_byte(WREN);                           // 写使能锁存
  80.         eeprom_cs=1;
  81.         eeprom_cs=0;
  82.         // 写入写操作指令
  83.         if(startAddr>0x00ff)
  84.                 eeprom_read_write_byte((WRITE|0x08));           // 地址大于255
  85.         else
  86.                 eeprom_read_write_byte(WRITE);                  // 地址小于255

  87.         // 写入地址
  88.         Add = (unsigned char)(startAddr & 0xff);             // 将地址换成8位
  89.         eeprom_read_write_byte(Add);

  90.         for(i=0;i<count;i++)// 写入数据
  91.         {
  92.                 eeprom_read_write_byte(*buf++);
  93.         }
  94.         eeprom_cs=1;                                 // 芯片关闭   
  95. }
  96. //==============================================================================
  97. // 描述: 在AT25连续读数据
  98. // 输入: unsigned char *PC 读出数据指针
  99. //       unsigned int count 读出数量计数  
  100. //       unsigned int SatAddr 读出起始地址
  101. // 返回: 无
  102. //==============================================================================
  103. void eeprom_read_buf(u16 startAddr,u8 *buf,u16 count)
  104. {
  105.         unsigned char Add;
  106.         unsigned int i;
  107.         while(eeprom_read_sr()&RDY);                   // 读状态寄存器  
  108.         eeprom_cs=0;
  109.         // 写入写操作指令
  110.         if(startAddr>0x00ff)
  111.                 eeprom_read_write_byte((READ | 0x08));         // 地址大于255
  112.         else
  113.                 eeprom_read_write_byte(READ);                  // 地址小于255

  114.         // 写入地址
  115.         Add = (unsigned char)(startAddr & 0xff);             // 将地址换成8位
  116.         eeprom_read_write_byte(Add);

  117.         // 读出n个数据
  118.         for(i=0;i<count;i++)
  119.         {
  120.                 *buf++ = eeprom_read_write_byte(0xff);
  121.         }
  122.         eeprom_cs=1;
  123. }
复制代码

二、测试

  1. int main(void)
  2. {        
  3.         u8 buf[5]={0x01,0x02,0x03,0x04,0x05},i;
  4.         uart_init(115200);
  5.         delay_init();        
  6.         program_led_init();        
  7.         
  8.         eeprom_wp=1;
  9.         eeprom_init();
  10.         eeprom_write_buf(0x0000,buf,sizeof(buf));
  11. //        eeprom_write_byte(0x0000,0x08);
  12.         memset(buf,0x00,sizeof(buf));
  13.         eeprom_wp=0;
  14.         while(1)
  15.         {        
  16.                
  17.                 eeprom_read_buf(0x0000,buf,sizeof(buf));
  18.         //        buf[0]=eeprom_read_byte(0x0001);
  19.                 for(i=0;i<sizeof(buf);i++)
  20.                         printf("0x%02x ",buf<i>);
  21.                 printf("\r\n");
  22.                 memset(buf,0x00,sizeof(buf));
  23.                
  24.                 program_led_data(0x10,0x10,0x10);
  25.                 delay_ms(500);

  26.                 program_led_data(0x00,0x00,0x00);
  27.                 delay_ms(500);        
  28.                
  29.                
  30.         }
  31. }


  32. </i>
复制代码

收藏 评论0 发布时间:2022-4-23 16:44

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版