【STM32学习】 您所在的位置:网站首页 stm32软著 【STM32学习】

【STM32学习】

2024-06-19 08:45| 来源: 网络整理| 查看: 265

 四、软件SPI读写W25Q64

工程思路与I2C类似,MySPI.c是通信底层,主要包括通信引脚封装、初始化、SPI通信的三个拼图(起始、终止和交换一个字节);基于此文件建立W25Q64.c,调用MySPI三个拼图,拼接成各种指令和功能的完整时序,如写使能、擦除、页编程、读数据等,可看作W25Q64芯片的硬件驱动层。在主函数调用驱动层函数:

//MySPI.c #include "stm32f10x.h" void MySPI_W_SS(uint8_t BitValue){//SS或CS,片选或从机选择。 GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue); } void MySPI_W_SCK(uint8_t BitValue){ GPIO_WriteBit(GPIOA,GPIO_Pin_5,(BitAction)BitValue); } void MySPI_W_MOSI(uint8_t BitValue){ GPIO_WriteBit(GPIOA,GPIO_Pin_7,(BitAction)BitValue); } uint8_t MySPI_R_MISO(void){ return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6); } //上面这样的函数,也可用有参宏定义实现 void MySPI_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;//推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_5 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); MySPI_W_SS(1);//初始化后默认电平 MySPI_W_SCK(0);//初始化后默认电平 } void MySPI_Start(void){//起始 MySPI_W_SS(0); } void MySPI_Stop(void){//终止 MySPI_W_SS(1); } uint8_t MySPI_SwapByte(uint8_t ByteSend){ uint8_t i,ByteReceive = 0x00; for(i=0;i> i);//放到线上。与从机同步的 MySPI_W_SCK(1);//线上的数据被分别读走(交换) if(MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}//主机接收到的数据位存到ByteReceive MySPI_W_SCK(0); } return ByteReceive; } //0x80 >> i的作用是用来挑出数据的某一位或者某几位(或屏蔽其他的无关位,是掩码操作思想)。好处是没改变传入参数ByteSend //另一种更简洁的方法,但会改变ByteSend变量: //uint8_t MySPI_SwapByte(uint8_t ByteSend){ // uint8_t i; // for(i=0;i 16); MySPI_SwapByte(Address >>8); MySPI_SwapByte(Address); MySPI_Stop(); W25Q64_WaitBusy();//等待Busy(注意事项) } void W25Q64_ReadData(uint32_t Address,uint8_t* DataArray,uint32_t Count){//指定起始地址,给个接收数组和元素数量,就可帮我们读取数据(读) uint32_t i; MySPI_Start(); MySPI_SwapByte(W25Q64_READ_DATA); MySPI_SwapByte(Address >> 16); MySPI_SwapByte(Address >>8); MySPI_SwapByte(Address); for(i=0;i> 8); //交换发送地址15~8位 MySPI_SwapByte(Address); //交换发送地址7~0位 for (i = 0; i < Count; i ++) //循环Count次 { MySPI_SwapByte(DataArray[i]); //依次在起始地址后写入数据 } MySPI_Stop(); //SPI终止 W25Q64_WaitBusy(); //等待忙 } /** * 函 数:W25Q64扇区擦除(4KB) * 参 数:Address 指定扇区的地址,范围:0x000000~0x7FFFFF * 返 回 值:无 */ void W25Q64_SectorErase(uint32_t Address) { W25Q64_WriteEnable(); //写使能 MySPI_Start(); //SPI起始 MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB); //交换发送扇区擦除的指令 MySPI_SwapByte(Address >> 16); //交换发送地址23~16位 MySPI_SwapByte(Address >> 8); //交换发送地址15~8位 MySPI_SwapByte(Address); //交换发送地址7~0位 MySPI_Stop(); //SPI终止 W25Q64_WaitBusy(); //等待忙 } /** * 函 数:W25Q64读取数据 * 参 数:Address 读取数据的起始地址,范围:0x000000~0x7FFFFF * 参 数:DataArray 用于接收读取数据的数组,通过输出参数返回 * 参 数:Count 要读取数据的数量,范围:0~0x800000 * 返 回 值:无 */ void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count) { uint32_t i; MySPI_Start(); //SPI起始 MySPI_SwapByte(W25Q64_READ_DATA); //交换发送读取数据的指令 MySPI_SwapByte(Address >> 16); //交换发送地址23~16位 MySPI_SwapByte(Address >> 8); //交换发送地址15~8位 MySPI_SwapByte(Address); //交换发送地址7~0位 for (i = 0; i < Count; i ++) //循环Count次 { DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //依次在起始地址后读取数据 } MySPI_Stop(); //SPI终止 }

由于涉及的文件较多,这里不全部列举,下面是文件下载链接:

百度网盘打开icon-default.png?t=N7T8http://xn--https-bl8js66z7n7i//pan.baidu.com/s/1T0yRNeCorQgHZuZWtdnf7g?pwd=eqld%20%20%E6%8F%90%E5%8F%96%E7%A0%81%EF%BC%9Aeqld软硬件波形对比:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有