公司网站如何上传视频,临沂市建设局兰山区网站,网站案例上海,wordpress 完整搬家前言
本篇文章属于stm32单片机#xff08;以下简称单片机#xff09;的学习笔记#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记#xff0c;只能做参考#xff0c;细节方面建议观看视频#xff0c;肯定受益匪浅。
STM32入门教程-2023版 细…前言
本篇文章属于stm32单片机以下简称单片机的学习笔记来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记只能做参考细节方面建议观看视频肯定受益匪浅。
STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili
一、SPI通信 1.硬件电路规定 2.移位示意图 3.软件时序规定 4.实际通信时序 区别于I2C是对寄存器进行操作SPI通信的从机会定义一个指令集起始条件后主机给从机发一个指令完成相应任务即可 第一个字节为写指令0x02第二三四个字节为地址地址高位先行第五个字节是写入的数据 第一个字节为写指令0x02第二三四个字节为地址第五个字节进行交换字节主机发送一个0xFF或0x00把从机发送的数据交换回来
二、W25Q64
1.简介 2.硬件电路 3.W25Q64框图 把8MB的内存分为128个块Block每个块又分为16个扇Sector每个扇又分16页Page 每页256B
4.Flash操作注意事项 5.具体细节详见W25Q64的参考手册
三、软件SPI读写W25Q64
1.MySPI.c
#include stm32f10x.h // Device headervoid MySPI_W_SS(uint8_t BitValue)
{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_GPIOA, 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 8;i){MySPI_W_MOSI(ByteSend (0x80 i));MySPI_W_SCK(1);if (MySPI_R_MISO() 1) {ByteReceive | (0x80 i);}MySPI_W_SCK(0);}return ByteReceive;
} 其中交换字节函数还可写为 uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i;for (i 0; i 8;i){MySPI_W_MOSI(ByteSend 0x80);ByteSend 1;MySPI_W_SCK(1);if (MySPI_R_MISO() 1) {ByteSend | 0x01;}MySPI_W_SCK(0);}return ByteSend;
} 这样效率更高但会改变ByteSend的值 2.W25Q64.c
#include stm32f10x.h // Device header
#include MySPI.h
#include W25Q64_Ins.hvoid W25Q64_Init(void)
{MySPI_Init();
}void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();MySPI_SwapByte(W25Q64_JEDEC_ID);*MID MySPI_SwapByte(W25Q64_DUMMY_BYTE);*DID MySPI_SwapByte(W25Q64_DUMMY_BYTE);*DID 8;*DID | MySPI_SwapByte(W25Q64_DUMMY_BYTE);MySPI_Stop();
}void W25Q64_WriteEnable(void)
{MySPI_Start();MySPI_SwapByte(W25Q64_WRITE_ENABLE);MySPI_Stop();
}void W25Q64_WaitBusy(void)
{uint32_t TimeOut 100000;MySPI_Start();MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);while((MySPI_SwapByte(W25Q64_DUMMY_BYTE) 0x01) 0x01){TimeOut--;if (TimeOut 0){break;}}MySPI_Stop();
}void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_PAGE_PROGRAM);MySPI_SwapByte(Address 16);MySPI_SwapByte(Address 8);MySPI_SwapByte(Address);for (i 0;i Count;i){MySPI_SwapByte(DataArray[i]);}MySPI_Stop(); W25Q64_WaitBusy();
}void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);MySPI_SwapByte(Address 16);MySPI_SwapByte(Address 8);MySPI_SwapByte(Address);MySPI_Stop(); W25Q64_WaitBusy();
}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 Count;i){DataArray[i] MySPI_SwapByte(W25Q64_DUMMY_BYTE);}MySPI_Stop();
}3.main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include W25Q64.huint8_t MID;
uint16_t DID;uint8_t ArrayWrite[] {0xB1, 0xB2, 0xB3, 0xB4};
uint8_t ArrayRead[4];int main(void)
{OLED_Init();W25Q64_Init();OLED_ShowString(1, 1, MID: DID:);OLED_ShowString(2, 1, W:);OLED_ShowString(3, 1, R:);W25Q64_ReadID(MID, DID);OLED_ShowHexNum(1, 5, MID, 2);OLED_ShowHexNum(1, 12, DID, 4);W25Q64_SectorErase(0x000000);W25Q64_PageProgram(0x000000, ArrayWrite, 4);W25Q64_ReadData(0x000000, ArrayRead, 4);OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);OLED_ShowHexNum(3, 3, ArrayRead[0], 2);OLED_ShowHexNum(3, 6, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);OLED_ShowHexNum(3, 12, ArrayRead[3], 2);while (1){}
}四、硬件SPI读写W25Q64
1.SPI通信外设 2.SPI框图 3.SPI基本结构 4.主模式全双工连续传输较为复杂性能好 5.非连续传输较为简单性能差一点 6.代码部分
只需更改MySPI.c部分的内容即可
配置好硬件SPI
#include stm32f10x.h // Device headervoid MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin 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);SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Mode SPI_Mode_Master;SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_DataSize SPI_DataSize_8b;SPI_InitStructure.SPI_FirstBit SPI_FirstBit_MSB;SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_128;SPI_InitStructure.SPI_CPOL SPI_CPOL_Low;SPI_InitStructure.SPI_CPHA SPI_CPHA_1Edge;SPI_InitStructure.SPI_NSS SPI_NSS_Soft;SPI_InitStructure.SPI_CRCPolynomial 7;SPI_Init(SPI1, SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);MySPI_W_SS(1);
}void MySPI_Start(void)
{MySPI_W_SS(0);
}void MySPI_Stop(void)
{MySPI_W_SS(1);
}uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) ! SET);SPI_I2S_SendData(SPI1, ByteSend);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) ! SET);return SPI_I2S_ReceiveData(SPI1);
}