//写SPI_FLASH状态寄存器 //只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!! void SPI_FLASH_Write_SR(u8 sr) { SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_WriteStatusReg); //发送写取状态寄存器命令 SPI1_ReadWriteByte(sr); //写入一个字节 SPI_FLASH_CS=1; //取消片选 }
//写W25QXX状态寄存器 //只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!! void W25QXX_Write_SR(u8 sr) { W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_WriteStatusReg); //发送写取状态寄存器命令 SPI1_ReadWriteByte(sr); //写入一个字节 W25QXX_CS=1; //取消片选 }
//SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 u8 NRF24L01_Write_Reg(u8 reg,u8 value) { u8 status; NRF24L01_CSN=0; //使能SPI传输 status =SPI1_ReadWriteByte(reg);//发送寄存器号 SPI1_ReadWriteByte(value); //写入寄存器的值 NRF24L01_CSN=1; //禁止SPI传输 return(status); //返回状态值 }
//读取SPI寄存器值 //reg:要读的寄存器 u8 NRF24L01_Read_Reg(u8 reg) { u8 reg_val; NRF24L01_CSN = 0; //使能SPI传输 SPI1_ReadWriteByte(reg); //发送寄存器号 reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容 NRF24L01_CSN = 1; //禁止SPI传输 return(reg_val); //返回状态值 }
/******************************************************************************* * Function Name : NRF24L01_Write_Buf * Description : 在指定位置写指定长度的数据 * Input : regaddr:要写的寄存器 datalen:指定长度 * Output : *pBuf:要写入的数据指针 * Return : status ,读到的状态值 *******************************************************************************/ static rt_uint8_t NRF24L01_Write_Buf(rt_uint8_t regaddr, rt_uint8_t *pBuf, rt_uint8_t datalen) { rt_uint8_t status,rt_uint8_t_ctr; Clr_NRF24L01_CSN; //使能SPI传输 status = SPI1_ReadWriteByte(regaddr); //发送寄存器值(位置),并读取状态值 for(rt_uint8_t_ctr=0; rt_uint8_t_ctr<datalen; rt_uint8_t_ctr++)SPI1_ReadWriteByte(*pBuf++); //写入数据 Set_NRF24L01_CSN; //关闭SPI传输 return status; //返回读到的状态值 }
//读取SPI_FLASH的状态寄存器 //BIT7 6 5 4 3 2 1 0 //SPR RV TB BP2 BP1 BP0 WEL BUSY //SPR:默认0,状态寄存器保护位,配合WP使用 //TB,BP2,BP1,BP0:FLASH区域写保护设置 //WEL:写使能锁定 //BUSY:忙标记位(1,忙;0,空闲) //默认:0x00 u8 SPI_Flash_ReadSR(void) { u8 byte=0; SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReadStatusReg); //发送读取状态寄存器命令 byte=SPI1_ReadWriteByte(0Xff); //读取一个字节 SPI_FLASH_CS=1; //取消片选 return byte; }
/******************************************************************************* * Function Name : NRF24L01_Write_Reg * Description : 通过SPI写寄存器 * Input : regaddr:要写的寄存器 data:要写的数据 * Output : None * Return : status ,状态值 *******************************************************************************/ static rt_uint8_t NRF24L01_Write_Reg(rt_uint8_t regaddr,rt_uint8_t data) { rt_uint8_t status; Clr_NRF24L01_CSN; //使能SPI传输 status =SPI1_ReadWriteByte(regaddr); //发送寄存器号 SPI1_ReadWriteByte(data); //写入寄存器的值 Set_NRF24L01_CSN; //禁止SPI传输 return(status); //返回状态值 }
//向ENC28J60寄存器写入数据(带操作码) //op:操作码 //addr:寄存器地址 //data:参数 void ENC28J60_Write_Op(u8 op,u8 addr,u8 data) { u8 dat=0; ENC28J60_CS=0; dat=op|(addr&ADDR_MASK); SPI1_ReadWriteByte(dat); SPI1_ReadWriteByte(data); ENC28J60_CS=1; }
//读取W25QXX的状态寄存器 //BIT7 6 5 4 3 2 1 0 //SPR RV TB BP2 BP1 BP0 WEL BUSY //SPR:默认0,状态寄存器保护位,配合WP使用 //TB,BP2,BP1,BP0:FLASH区域写保护设置 //WEL:写使能锁定 //BUSY:忙标记位(1,忙;0,空闲) //默认:0x00 u8 W25QXX_ReadSR(void) { u8 byte=0; W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReadStatusReg); //发送读取状态寄存器命令 byte=SPI1_ReadWriteByte(0Xff); //读取一个字节 W25QXX_CS=1; //取消片选 return byte; }
/******************************************************************************* * Function Name : NRF24L01_Read_Reg * Description : 通过SPI读寄存器 * Input : regaddr:要读的寄存器 * Output : None * Return : reg_val ,读出的数据 *******************************************************************************/ static rt_uint8_t NRF24L01_Read_Reg(rt_uint8_t regaddr) { rt_uint8_t reg_val; Clr_NRF24L01_CSN; //使能SPI传输 SPI1_ReadWriteByte(regaddr); //发送寄存器号 reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容 Set_NRF24L01_CSN; //禁止SPI传输 return(reg_val); //返回状态值 }
//在指定位置写指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len) { u8 status,u8_ctr; NRF24L01_CSN = 0; //使能SPI传输 status = SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0; u8_ctr<len; u8_ctr++) SPI1_ReadWriteByte(*pBuf++); //写入数据 NRF24L01_CSN = 1; //关闭SPI传输 return status; //返回读到的状态值 }
//读取ENC28J60控制寄存器(带操作码) //op:操作码 //addr:寄存器地址/参数 //返回值:读到的数据 u8 ENC28J60_Read_Op(u8 op,u8 addr) { u8 dat=0; ENC28J60_CS=0; dat=op|(addr&ADDR_MASK); SPI1_ReadWriteByte(dat); dat=SPI1_ReadWriteByte(0XFF); //如果是读取MAC/MII寄存器,则第二次读到的数据才是正确的,见手册29页 if(addr&0x80)dat=SPI1_ReadWriteByte(0XFF); ENC28J60_CS=1; return dat; }
//向ENC28J60写发送缓存数据 //len:要写入的数据长度 //data:数据缓存区 void ENC28J60_Write_Buf(u32 len,u8* data) { ENC28J60_CS=0; SPI1_ReadWriteByte(ENC28J60_WRITE_BUF_MEM); while(len) { len--; SPI1_ReadWriteByte(*data); data++; } ENC28J60_CS=1; }
//SPI在一页(0~65535)内写入少于256个字节的数据 //在指定地址开始写入最大256字节的数据 //pBuffer:数据存储区 //WriteAddr:开始写入的地址(24bit) //NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!! void W25QXX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u16 i; W25QXX_Write_Enable(); //SET WEL W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_PageProgram); //发送写页命令 SPI1_ReadWriteByte((u8)((WriteAddr)>>16)); //发送24bit地址 SPI1_ReadWriteByte((u8)((WriteAddr)>>8)); SPI1_ReadWriteByte((u8)WriteAddr); for(i=0;i<NumByteToWrite;i++)SPI1_ReadWriteByte(pBuffer[i]);//循环写数 W25QXX_CS=1; //取消片选 W25QXX_Wait_Busy(); //等待写入结束 }
//读取ENC28J60接收缓存数据 //len:要读取的数据长度 //data:输出数据缓存区(末尾自动添加结束符) void ENC28J60_Read_Buf(u32 len,u8* data) { ENC28J60_CS=0; SPI1_ReadWriteByte(ENC28J60_READ_BUF_MEM); while(len) { len--; *data=(u8)SPI1_ReadWriteByte(0); data++; } *data='\0'; ENC28J60_CS=1; }
//擦除一个扇区 //Dst_Addr:扇区地址 0~511 for w25x16 //擦除一个山区的最少时间:150ms void SPI_Flash_Erase_Sector(u32 Dst_Addr) { Dst_Addr*=4096; SPI_FLASH_Write_Enable(); //SET WEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_SectorErase); //发送扇区擦除指令 SPI1_ReadWriteByte((u8)((Dst_Addr)>>16)); //发送24bit地址 SPI1_ReadWriteByte((u8)((Dst_Addr)>>8)); SPI1_ReadWriteByte((u8)Dst_Addr); SPI_FLASH_CS=1; //取消片选 SPI_Flash_Wait_Busy(); //等待擦除完成 }
//读取SPI FLASH //在指定地址开始读取指定长度的数据 //pBuffer:数据存储区 //ReadAddr:开始读取的地址(24bit) //NumByteToRead:要读取的字节数(最大65535) void W25QXX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead) { u16 i; W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReadData); //发送读取命令 SPI1_ReadWriteByte((u8)((ReadAddr)>>16)); //发送24bit地址 SPI1_ReadWriteByte((u8)((ReadAddr)>>8)); SPI1_ReadWriteByte((u8)ReadAddr); for(i=0;i<NumByteToRead;i++) { pBuffer[i]=SPI1_ReadWriteByte(0XFF); //循环读数 } W25QXX_CS=1; }
//擦除一个扇区 //Dst_Addr:扇区地址 根据实际容量设置 //擦除一个扇区的最少时间:150ms void W25QXX_Erase_Sector(u32 Dst_Addr) { //监视falsh擦除情况,测试用 printf("fe:%x\r\n",Dst_Addr); Dst_Addr*=4096; W25QXX_Write_Enable(); //SET WEL W25QXX_Wait_Busy(); W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_SectorErase); //发送扇区擦除指令 SPI1_ReadWriteByte((u8)((Dst_Addr)>>16)); //发送24bit地址 SPI1_ReadWriteByte((u8)((Dst_Addr)>>8)); SPI1_ReadWriteByte((u8)Dst_Addr); W25QXX_CS=1; //取消片选 W25QXX_Wait_Busy(); //等待擦除完成 }
//进入掉电模式 void SPI_Flash_PowerDown(void) { SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_PowerDown); //发送掉电命令 SPI_FLASH_CS=1; //取消片选 delay_us(3); //等待TPD }
//唤醒 void W25QXX_WAKEUP(void) { W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB W25QXX_CS=1; //取消片选 delay_us(3); //等待TRES1 }
//进入掉电模式 void W25QXX_PowerDown(void) { W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_PowerDown); //发送掉电命令 W25QXX_CS=1; //取消片选 delay_us(3); //等待TPD }
//唤醒 void SPI_Flash_WAKEUP(void) { SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB SPI_FLASH_CS=1; //取消片选 delay_us(3); //等待TRES1 }
//读取SPI FLASH //在指定地址开始读取指定长度的数据 //pBuffer:数据存储区 //ReadAddr:开始读取的地址(24bit) //NumByteToRead:要读取的字节数(最大65535) void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead) { u16 i; SPI_USART_IO_SET(0);//SPI 工作 SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ReadData); //发送读取命令 SPI1_ReadWriteByte((u8)((ReadAddr)>>16)); //发送24bit地址 SPI1_ReadWriteByte((u8)((ReadAddr)>>8)); SPI1_ReadWriteByte((u8)ReadAddr); for(i=0;i<NumByteToRead;i++) { pBuffer[i]=SPI1_ReadWriteByte(0XFF); //循环读数 } SPI_FLASH_CS=1; //取消片选 SPI_USART_IO_SET(1);//USART2 工作 }
//SPI口初始化 //这里针是对SPI1的初始化 void SPI1_Init(void) { RCC->APB2ENR|=1<<2; //PORTA时钟使能 RCC->APB2ENR|=1<<12; //SPI1时钟使能 //这里只针对SPI口初始化 GPIOA->CRL&=0X000FFFFF; GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 GPIOA->ODR|=0X7<<5; //PA5.6.7上拉 SPI1->CR1|=0<<10;//全双工模式 SPI1->CR1|=1<<9; //软件nss管理 SPI1->CR1|=1<<8; SPI1->CR1|=1<<2; //SPI主机 SPI1->CR1|=0<<11; //8bit数据格式 SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1 SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1 //对SPI1属于APB1的外设.时钟频率最大为36M. SPI1->CR1|=3<<3; //Fsck=Fpclk1/256 SPI1->CR1|=0<<7; //MSBfirst SPI1->CR1|=1<<6; //SPI设备使能 SPI1_ReadWriteByte(0xff);//启动传输 }
void SPI1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); 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_High; //选择了串行时钟的稳态:时钟悬空高 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第二个时钟沿 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI1, ENABLE); //使能SPI外设 SPI1_ReadWriteByte(0xff);//启动传输 }
void SPI1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );//PORTB时钟使能 RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI2时钟使能 /* 初始化SCK、MISO、MOSI引脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA5/6/7复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOB GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PA5/6/7上拉 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_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI1, ENABLE); //使能SPI外设 SPI1_ReadWriteByte(0xff);//启动传输 }
/* * 函数名:SPI_Config_Init() * 输入:void * 输出:void * 功能:对SPI进行初始化设置 */ void SPI1_Config_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; //开启外设时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE); //PORTB时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);//SPI1时钟使能 //配置CLK端口的GPIO GPIO_InitStructure.GPIO_Pin = SPI_CLK_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //10MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(SPI_CLK_GPIO_PORT,&GPIO_InitStructure); //配置MISO端口的GPIO GPIO_InitStructure.GPIO_Pin = SPI_MISO_GPIO_PIN ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 因为复用的时候端口方向由内部控制,所以这里设置成输出相当于浮空输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //10MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(SPI_MISO_GPIO_PORT,&GPIO_InitStructure); //配置MOSI端口的GPIO GPIO_InitStructure.GPIO_Pin = SPI_MOSI_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //10MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(SPI_MOSI_GPIO_PORT,&GPIO_InitStructure); //设置端口复用 GPIO_PinAFConfig(SPI_CLK_GPIO_PORT ,SPI_CLK_AF_PINSOURCE ,GPIO_AF_SPI1); //PB3复用为SPI1 GPIO_PinAFConfig(SPI_MISO_GPIO_PORT,SPI_MISO_AF_PINSOURCE,GPIO_AF_SPI1); //PB4复用为SPI1 GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT,SPI_MOSI_AF_PINSOURCE,GPIO_AF_SPI1); //PB5复用为SPI1 //这里只针对SPI口初始化 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE); //复位SPI1 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //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_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; ////定义波特率预分频的值:波特率预分频值为256 为主时钟分频 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式,含义是CRC的简记式,使用CRC-8 SPI_Init(SPIx_USE, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPIx_USE,ENABLE); //使能SPI外设 SPI1_ReadWriteByte(0xff); //启动传输 }
//擦除整个芯片 //整片擦除时间: //W25X16:25s //W25X32:40s //W25X64:40s //等待时间超长... void SPI_Flash_Erase_Chip(void) { SPI_FLASH_Write_Enable(); //SET WEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ChipErase); //发送片擦除命令 SPI_FLASH_CS=1; //取消片选 SPI_Flash_Wait_Busy(); //等待芯片擦除结束 }
//擦除整个芯片 //等待时间超长... void W25QXX_Erase_Chip(void) { W25QXX_Write_Enable(); //SET WEL W25QXX_Wait_Busy(); W25QXX_CS=0; //使能器件 SPI1_ReadWriteByte(W25X_ChipErase); //发送片擦除命令 W25QXX_CS=1; //取消片选 W25QXX_Wait_Busy(); //等待芯片擦除结束 }
void SPI1_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_SPI1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); // PA5--CLK PA7--MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //PA6--MISO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //PA4--NSS GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //PA3--IRQ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IPU; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //PB0--CE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //一次转换8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //空闲电平低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个上升沿采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS为软件模式 SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_8; //9MHz //SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定义波特率预分频的值:波特率预分频值为16 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输低位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC校验模式 SPI_Init(SPI1, &SPI_InitStructure); //初始化 // SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set); SPI_Cmd(SPI1, ENABLE); //SPI1 SPI1_ReadWriteByte(0xff);//启动传输 }