1.SPI初始化
- #include "stm32f10x.h" // Device header
- void 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)//MOSI
- {
- GPIO_WriteBit(GPIOA,GPIO_Pin_7,(BitAction)BitValue);
- }
- uint8_t MySPI_R_MISO(void)//MISO
- {
- 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);//时钟线默认为0
- }
- void MySPI_Start(void)
- {
- MySPI_W_SS(0);//片选低电平
- }
- void MySPI_Stop(void)
- {
- MySPI_W_SS(1);//片选高电平
- }
- uint8_t MySPI_BitSend(uint8_t Data)//交换数据
- {
- uint8_t i,BitReivce = 0x00;//接收数据默认为0x00
- for(i=0;i<8;i++)
- {
- MySPI_W_MOSI(Data & (0x80>>i));//此时模式为模式0,因为低电平将数据放入SCk,高电平读取数据
- MySPI_W_SCK(1);
-
- if(MySPI_R_MISO()== 1){BitReivce |= (0x80>>i);}//该语句首先判断接收到的位是否为1,通过|=来提出该位的1,否则为零
- MySPI_W_SCK(0);
- }
- return BitReivce;
- }
复制代码 完成SPI基本时序单元,包罗起始条件,终止条件,互换一个字节。为了方便放标操作,封装了一些函数。
2.1基于SPI的W25Q64初始化
根据W25Q64指令表实现相关指令
为了方便程序的读写,对W25Q64的指令做宏定义,增长程序的可读性
2.2W25Q64头文件
- #ifndef __W25Q64_INS_H_
- #define __W25Q64_INS_H_
- #define W25Q64_WRITE_ENABLE 0x06
- #define W25Q64_WRITE_DISABLE 0x04
- #define W25Q64_READ_STATUS_REGISTER_1 0x05
- #define W25Q64_READ_STATUS_REGISTER_2 0x35
- #define W25Q64_WRITE_STATUS_REGISTER 0x01
- #define W25Q64_PAGE_PROGRAM 0x02
- #define W25Q64_QUAD_PAGE_PROGRAM 0x32
- #define W25Q64_BLOCK_ERASE_64KB 0xD8
- #define W25Q64_BLOCK_ERASE_32KB 0x52
- #define W25Q64_SECTOR_ERASE_4KB 0x20
- #define W25Q64_CHIP_ERASE 0xC7
- #define W25Q64_ERASE_SUSPEND 0x75
- #define W25Q64_ERASE_RESUME 0x7A
- #define W25Q64_POWER_DOWN 0xB9
- #define W25Q64_HIGH_PERFORMANCE_MODE 0xA3
- #define W25Q64_CONTINUOUS_READ_MODE_RESET 0xFF
- #define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID 0xAB
- #define W25Q64_MANUFACTURER_DEVICE_ID 0x90
- #define W25Q64_READ_UNIQUE_ID 0x4B
- #define W25Q64_JEDEC_ID 0x9F
- #define W25Q64_READ_DATA 0x03
- #define W25Q64_FAST_READ 0x0B
- #define W25Q64_FAST_READ_DUAL_OUTPUT 0x3B
- #define W25Q64_FAST_READ_DUAL_IO 0xBB
- #define W25Q64_FAST_READ_QUAD_OUTPUT 0x6B
- #define W25Q64_FAST_READ_QUAD_IO 0xEB
- #define W25Q64_OCTAL_WORD_READ_QUAD_IO 0xE3
- #define W25Q64_DUMMY_BYTE 0xFF
- #endif
复制代码 3.main函数实验
- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "OLED.h"
- #include "MyW25Q64.h"
- uint8_t DataArray[4] = {0x01,0x02,0x03,0x04};//写入数据注意不要超过256个,超出新数据会覆盖地址开头数据
- uint8_t ArrayRead[4];//读数据没有个数限制
- uint8_t MID;
- uint16_t DID;
- int main(void)
- {
- OLED_Init();
- MyW25Q64_Init();
- MyW25Q64_GetID(&MID,&DID);
- OLED_ShowString(1, 1, "MID: DID:");
- OLED_ShowString(2, 1, "W:");
- OLED_ShowString(3, 1, "R:");
-
- OLED_ShowHexNum(1, 5, MID, 2);
- OLED_ShowHexNum(1, 12, DID, 4);
-
- W25Q64_SectorErase( 0x00000);
- W25Q64_PageProgram(0x00000,DataArray,4);//数据写入地址0x00000处,内容为数组DataArray的数据
-
- W25Q64_ReadDate(0x00000,ArrayRead,4);//读取地址0x00000处数据
- OLED_ShowHexNum(2, 3, DataArray[0], 2);
- OLED_ShowHexNum(2, 6, DataArray[1], 2);
- OLED_ShowHexNum(2, 9, DataArray[2], 2);
- OLED_ShowHexNum(2, 12, DataArray[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)
- {
-
-
-
- }
- }
复制代码 4.功能实现
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |