OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3967|回复: 8

AT45DB161E+stm32f103c8t6

[复制链接]

7

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2019-10-7
在线时间
17 小时
发表于 2019-11-26 19:16:37 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 123HHY 于 2019-11-26 19:59 编辑

采用SPI1口,NSS口就是用他本来的SPI_CS口,没用其他的作为连接,串口那部分是好的,可以正常输出。
读写函数我写了两种,
第一种是注释掉的,传输数据数组——芯片缓冲区——芯片主存储区——芯片片缓冲区——接收数据数组读写一起读出来的是乱的,单独读出来是的是0,

第二种是,传输数据数组——芯片——接收数据数组,我就用0页定死了
读写一起读出来的字节全是0,但是我单独用读函数又可以读出0xff。第一页(0页)可以读出我写入的数据
其他页我也用相同的写函数写入,但是在单独去读,读出来的是0xff

看过原子自己写的那部份代码,和我的没什么差别,我的就是读不出来
读ID函数,擦除函数都是正常的,可以读出ID。

#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"

#define U1_Tx GPIO_Pin_9
#define U1_Rx GPIO_Pin_10

#define SPI1_CS GPIO_Pin_4
#define SPI1_SCK GPIO_Pin_5
#define SPI1_MISO GPIO_Pin_6
#define SPI1_MOSI GPIO_Pin_7

#define SPI1_CS_Set GPIO_SetBits(GPIOA, SPI1_CS)
#define SPI1_CS_Reset GPIO_ResetBits(GPIOA, SPI1_CS)

#define SPI1_WriteBuff 0x84 //写到第一缓冲区,14+10缓冲区地址
#define SPI1_BuffToFlash 0x83 //将第一缓冲区的内容写到主储存区(预擦除),2+12页地址+10
#define SPI1_FlashToBuff 0x55 //将主储存区的内容读取到第二缓冲区,2+12页地址+10
#define SPI1_ReadBuff 0xd6 //读取第二缓冲区,14+10缓冲区地址+8

#define SPI1_Read 0x52 //读取FLASH,12页地址+2+10页内地址+32
#define SPI1_Write 0x85 //0x82写入FLASH(经Buff2),2+12页地址+10缓冲区地址

#define SPI1_ReadBusy 0xd7 //读取忙状态,读取返回数据的最高位,为0时处于忙碌状态
#define SPI1_ErasePage 0x81 //页擦除,2+12页地址+10
#define SPI1_ReadID 0x9f //读取设备ID
#define Dummy_Byte 0xff //空数据,用来获取返回数据
#define SPI1_PageSize 528

u8 TxBuff[256];
u8 RxBuff[256];

void Delay_nms(u16 time)
{
  u16 i;
  while(time--)
  {
    i = 12000;
    while(i--);
  }
}

void USART1_3_Init()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);

  GPIO_InitStructure.GPIO_Pin = U1_Tx;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = U1_Rx;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 38400;
  USART_InitStructure.USART_Mode = USART_Mode_Tx;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_Init(USART1, &USART_InitStructure);
  USART_Cmd(USART1, ENABLE);

  USART_GetFlagStatus(USART1, USART_FLAG_TC);
}

int fputc(int ch, FILE *f)
{
  USART_SendData(USART1, ch);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  return ch;
}

//SPI1初始化
void SPI1_Init()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef SPI_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SPI1_MISO|SPI1_MOSI|SPI1_SCK;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = SPI1_CS;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  SPI1_CS_Set;
  GPIO_SetBits(GPIOA, SPI1_SCK|SPI1_MOSI|SPI1_MOSI);

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);

  SPI_Cmd(SPI1, ENABLE);
}

//写数据
u8 SPI1_WRByte(u8 data)
{
  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI1, data);

  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_I2S_ReceiveData(SPI1);
}

//等待忙状态结束
void SPI1_WFEnd()
{
  u8 FLASH_Status = 0;

  SPI1_CS_Reset;
  SPI1_WRByte(SPI1_ReadBusy);                           

  do
  {
    FLASH_Status = SPI1_WRByte(Dummy_Byte);
  }
  while(FLASH_Status & 0x80 == 0);
  SPI1_CS_Set;
}

//擦除页
void SPI1_PageErase(u16 PageAdd)
{
  SPI1_WFEnd(); //等待写入

  SPI1_CS_Reset;
  SPI1_WRByte(SPI1_ErasePage);
  SPI1_WRByte((PageAdd>>6)&0xff);
  SPI1_WRByte((PageAdd<<2)&0xff);
  SPI1_WRByte(0x00);
  SPI1_CS_Set;

  SPI1_WFEnd(); //等待写入
}

//读ID
u32 SPI1_FLASH_ReadID()
{
  u32 Temp = 0;
  SPI1_WFEnd();

  SPI1_CS_Reset;                                    
  SPI1_WRByte(SPI1_ReadID);//发送读取ID命令            
  Temp|=SPI1_WRByte(Dummy_Byte)<<24;         
  Temp|=SPI1_WRByte(Dummy_Byte)<<16;  
  Temp|=SPI1_WRByte(Dummy_Byte)<<8;
  Temp|=SPI1_WRByte(Dummy_Byte);
  SPI1_CS_Set;
  return Temp;
}

//页读出
//void SPI1_BuffRead(u16 BuffAdd, u16 PageBuff, u8 *data, u16 datalen)
//{
//  SPI1_WFEnd(); //等待读出
//  SPI1_CS_Reset;
//  SPI1_WRByte(SPI1_FlashToBuff); //0x55将主储存区的内容读取到第二缓冲区
//  SPI1_WRByte((PageBuff>>6)&0xff);
//  SPI1_WRByte((PageBuff<<2)&0xff);
//  SPI1_WRByte(0x00);
//  SPI1_CS_Set;
//  
//  SPI1_WFEnd(); //等待读到Buff结束
//  SPI1_CS_Reset;
//  SPI1_WRByte(SPI1_ReadBuff); //0xd6从第二缓冲区读取数据
//  SPI1_WRByte(0x00);
//  SPI1_WRByte((BuffAdd>>8)&0xff);
//  SPI1_WRByte(BuffAdd&0xff);
//  SPI1_WRByte(0x00);
//  while(datalen--)
//  {
//    *data = SPI1_WRByte(Dummy_Byte);
//    data++;
//  }
//  SPI1_CS_Set;
//  SPI1_WFEnd(); //等待读结束
//}

//页写入
//void SPI1_PageWrite(u16 BuffAdd, u16 PageBuff, u8 *data, u16 datalen)
//{
//  SPI1_WFEnd(); //等待写入
//  SPI1_CS_Reset;
//  SPI1_WRByte(SPI1_WriteBuff); //0x84将数据写入第一缓冲区
//  SPI1_WRByte(0x00);
//  SPI1_WRByte((BuffAdd>>8)&0xff);
//  SPI1_WRByte(BuffAdd&0xff);

//  while(datalen--)
//  {
//    SPI1_WRByte(*data);
//    data++;
//  }
//  SPI1_CS_Set;
//  
//  SPI1_WFEnd(); //等待写Buff1结束
//  SPI1_CS_Reset;
//  SPI1_WRByte(SPI1_BuffToFlash); //0x83将第一缓冲区内容移到主存储区
//  SPI1_WRByte((PageBuff>>6)&0xff);
//  SPI1_WRByte((PageBuff<<2)&0xff);
//  SPI1_WRByte(0x00);

//  SPI1_CS_Set;
//  SPI1_WFEnd(); //等待写缓冲区结束
//}

//页读出
void SPI1_BuffRead(u16 address, u8 *data, u16 datalen)
{
  SPI1_WFEnd(); //等待写入
  SPI1_CS_Reset;
  SPI1_WRByte(SPI1_Read); //
  SPI1_WRByte(0x00);
  SPI1_WRByte(0x00);
  SPI1_WRByte(0x00);
  SPI1_WRByte(Dummy_Byte);
  SPI1_WRByte(Dummy_Byte);
  SPI1_WRByte(Dummy_Byte);
  SPI1_WRByte(Dummy_Byte);
  while(datalen--)
  {
    *data = SPI1_WRByte(Dummy_Byte);
    printf("%d ", *data);
    data++;
  }
  SPI1_CS_Set;
  SPI1_WFEnd(); //等待读结束
}

//页写入
void SPI1_PageWrite(u16 address, u8 *data, u16 datalen)
{
  SPI1_WFEnd(); //等待写入
  SPI1_CS_Reset;
  SPI1_WRByte(0x82); //2+12+10
  SPI1_WRByte(0x00);
  SPI1_WRByte(0x00);
  SPI1_WRByte(0x00);
  if(datalen > SPI1_PageSize)
    datalen = SPI1_PageSize;
  while(datalen--)
  {
    SPI1_WRByte(*data);
    data++;
  }
  SPI1_CS_Set;
  SPI1_WFEnd(); //等待写入
}


int main()
{
  u16 i;
  SPI1_Init();
  USART1_3_Init();

  for(i=0; i<256; i++)
    TxBuff = i;


  SPI1_PageWrite(0x0000, TxBuff, 256);
  SPI1_BuffRead(0x0000, RxBuff, 256);


  for(i=0; i<256; i++)
    printf("%d ",RxBuff);

  while(1)
  {
  }
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2019-10-7
在线时间
17 小时
 楼主| 发表于 2019-11-27 13:35:42 | 显示全部楼层
读写一起不能接受到的问题解决了,重新写了程序,但是新问题又来了,就是单独用读函数什么也读不出来,我写入后连着读两次,第二次读出的全是0
/*
写buf
*/
u8 Write_Buf(u16 addr, u8 *buf, u16 len)
{
  u16 i;
  if((len + addr) <= SPI1_PageSize)
  {
    SPI1_WFEnd();
    SPI1_CS_Reset;
    SPI1_WRByte(0x84); //写入第一缓冲区
    SPI1_WRByte(0x00);
    SPI1_WRByte((u8)(addr>>8));
    SPI1_WRByte((u8)addr);
   
    for(i=0; i < len; i++)
    {
      SPI1_WRByte(buf[i]);               
    }
    SPI1_CS_Set;
    SPI1_WFEnd();
  }
  else
  {
    return 1;
  }
  
  return 0;
}

/*
读buf
*/
u8 Read_Buf(u16 addr, u8 *buf, u16 len)
{
  u16 i = 0;
  if((len + addr) <= SPI1_PageSize)
  {
    SPI1_WFEnd();
    SPI1_CS_Reset;
    SPI1_WRByte(0xD6); //读第二缓冲区
    SPI1_WRByte(0x00);
    SPI1_WRByte((u8)(addr>>8));
    SPI1_WRByte((u8)addr);
    SPI1_WRByte(0x00);
   
    for(i=0; i < len; i++)
    {
      buf[i] = SPI1_WRByte(Dummy_Byte);               
    }
    SPI1_CS_Set;
    SPI1_WFEnd();
  }
  else
  {
    return 1;
  }       
  
  return 0;
}

/*
将buf写到存储区指定页
*/
u8 Buf_To_MM(u16 page)
{
  if(page < SPI1_PageNumber)
  {
    SPI1_WFEnd();
    SPI1_CS_Reset;       
    SPI1_WRByte(0x83); //将第一缓冲区数据写入第主存储区
    SPI1_WRByte((u8)(page>>6));
    SPI1_WRByte((u8)page<<2);
    SPI1_WRByte(0x00);
    SPI1_CS_Set;
    SPI1_WFEnd();
  }
  else
  {
    return 1;
  }
  
  return 0;
}

/*
将指定页读取到buf
*/
u8 MM_To_Buf(u16 page)
{
  if(page < SPI1_PageNumber)
  {
    SPI1_WFEnd();
    SPI1_CS_Reset;       
    SPI1_WRByte(0x55); //将主存储区的数据移入第二缓冲区
    SPI1_WRByte((u8)(page>>6));
    SPI1_WRByte((u8)page<<2);
    SPI1_WRByte(0x00);
    SPI1_CS_Set;
    SPI1_WFEnd();
  }
  else
  {
    return 1;
  }
  
  return 0;
}

/*
读取指定地址的数据                
*/
u8 Read_Page(u32 addr, u8 *buf, u16 len)
{
  u16 page = 0;
  u16 PageAddr = 0;
  page = addr/SPI1_PageSize;
  PageAddr = addr%SPI1_PageSize;
  if((len + PageAddr) <= SPI1_PageSize)
  {       
   
    //将缓存存入buf
    if(MM_To_Buf(page))       
      return 1;       
    //读取buf
    if(Read_Buf(PageAddr, buf, len))
      return 1;
  }
  else
  {
    return 1;
  }
  
  return 0;
}

/*
写指定地址的数据
*/
u8 Write_Page(u32 addr, u8 *buf, u16 len)
{
  u16 page = 0;
  u16 PageAddr = 0;
  page = addr/SPI1_PageSize;
  PageAddr = addr%SPI1_PageSize;
  if((len + PageAddr) <= SPI1_PageSize)
  {
    //MM读取到缓存
    if(MM_To_Buf(page))       
      return 1;
    //将数据写入缓存
    if(Write_Buf(PageAddr,buf,len))
      return 1;
    //将缓存移回MM
    if(Buf_To_MM(page))       
      return 1;
  }
  else
  {
    return 1;
  }
  return 0;
}
回复

使用道具 举报

233

主题

958

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1796
金钱
1796
注册时间
2011-10-9
在线时间
223 小时
发表于 2019-11-27 14:59:19 | 显示全部楼层
这片玩意好贵哦  161记得不好买而且贵
回复

使用道具 举报

7

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2019-10-7
在线时间
17 小时
 楼主| 发表于 2019-11-27 16:42:13 | 显示全部楼层
simms01 发表于 2019-11-27 14:59
这片玩意好贵哦  161记得不好买而且贵

就买着试着玩下,
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2019-11-27 17:56:51 | 显示全部楼层
帮顶                                       
成功没有捷径
回复

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2019-7-3
在线时间
21 小时
发表于 2020-1-17 11:49:16 | 显示全部楼层
楼主..我读出来的器件ID:0xFFFFFFFF,这个对不对,,我写了四页数据进去但读出来的都是0xff,,什么问题?
回复

使用道具 举报

7

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2019-10-7
在线时间
17 小时
 楼主| 发表于 2020-2-22 13:47:08 | 显示全部楼层
小wang0大wang 发表于 2020-1-17 11:49
楼主..我读出来的器件ID:0xFFFFFFFF,这个对不对,,我写了四页数据进去但读出来的都是0xff,,什么问题?

这个似乎是不对的,如果没写进去,读没问题的话,读出来的就应该是0xff
回复

使用道具 举报

1

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
152
金钱
152
注册时间
2020-3-7
在线时间
25 小时
发表于 2022-3-22 14:18:21 | 显示全部楼层
我也是在用这种芯片,也有一些问题,能请教一下嘛?
回复

使用道具 举报

1

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
152
金钱
152
注册时间
2020-3-7
在线时间
25 小时
发表于 2022-3-22 14:19:10 | 显示全部楼层
芯片手册有个  0x58 和0x59操作指令,楼主知道怎么用吗?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 20:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表