cortex_m3_stm32嵌入式学习笔记(二十一):SPI实验(通信总线)

article/2025/8/22 3:31:54
SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola首先在其 MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM, FLASH,实时时钟, AD 转换器,还有数字信号处理器和数字信号解码器之间。 SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议, STM32 也有 SPI 接口。

功能类似于上节的I2C,都属于传输数据的用途。。找到一篇I2C VS SPI的文章:点击打开链接

SPI 接口一般使用 4 条线通信:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK 时钟信号,由主设备产生。
CS 从设备片选信号,由主设备控制。

SPI 主要特点有: 可以同时发出和接收串行数据; 可以当作主机或从机工作; 提供频率可编程时钟; 发送结束中断标志; 写冲突保护; 总线竞争保护等。

本章,我们将使用STM32的SPI来读取外部 SPI FLASH 芯片( W25Q64),实现类似上节的功能。
W25Q64 是华邦公司推出的大容量SPI FLASH 产品, W25Q64 的容量为 64Mb, 该系列还有 W25Q80/16/32 等。 MiniSTM32 V3.0开发板所选择的 W25Q64 容量为 64Mb,也就是 8M 字节。

连接图如下:

                

也就说外设我们需要初始化PA5 6 7

配置SPI 和 flash的文件很长。。

spi.c

#include "spi.h"
//以下是SPI模块的初始化代码,配置成主机模式,访问SD Card/W25X16/24L01/JF24C							  
//SPI口初始化
//这里针是对SPI1的初始化SPI_InitTypeDef  SPI_InitStructure;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工作模式:设置为主SPISPI_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;		//定义波特率预分频的值:波特率预分频值为256SPI_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 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   (SPI 36M@sys 72M)
//SPI_BaudRatePrescaler_8   8分频   (SPI 9M@sys 72M)
//SPI_BaudRatePrescaler_16  16分频  (SPI 4.5M@sys 72M)
//SPI_BaudRatePrescaler_256 256分频 (SPI 281.25K@sys 72M)void SPI1_SetSpeed(u8 SpeedSet)
{SPI_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1,ENABLE);
} //SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{		u8 retry=0;				 	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}			  SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位{retry++;if(retry>200)return 0;}	  						    return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据					    
}
spi.h

#ifndef __SPI_H
#define __SPI_H
#include "sys.h" 				  	    													  
void SPI1_Init(void);			 //初始化SPI口
void SPI1_SetSpeed(u8 SpeedSet); //设置SPI速度   
u8 SPI1_ReadWriteByte(u8 TxData);//SPI总线读写一个字节 
#endif
flash.c

#include "flash.h" 
#include "spi.h"
#include "delay.h"   
u16 SPI_FLASH_TYPE=W25Q64;//默认就是25Q64
//4Kbytes为一个Sector
//16个扇区为1个Block
//W25X16
//容量为2M字节,共有32个Block,512个Sector //初始化SPI FLASH的IO口
void SPI_Flash_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;  //SPI CSGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);SPI1_Init();		   //初始化SPISPI1_SetSpeed(SPI_BaudRatePrescaler_4);	//设置为18M时钟,高速模式SPI_FLASH_TYPE=SPI_Flash_ReadID();//读取FLASH ID.
}  //读取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;   
} 
//写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;                            //取消片选     	      
}   
//SPI_FLASH写使能	
//将WEL置位   
void SPI_FLASH_Write_Enable(void)   
{SPI_FLASH_CS=0;                            //使能器件   SPI1_ReadWriteByte(W25X_WriteEnable);      //发送写使能  SPI_FLASH_CS=1;                            //取消片选     	      
} 
//SPI_FLASH写禁止	
//将WEL清零  
void SPI_FLASH_Write_Disable(void)   
{  SPI_FLASH_CS=0;                            //使能器件   SPI1_ReadWriteByte(W25X_WriteDisable);     //发送写禁止指令    SPI_FLASH_CS=1;                            //取消片选     	      
} 			    
//读取芯片ID W25X16的ID:0XEF14
u16 SPI_Flash_ReadID(void)
{u16 Temp = 0;	  SPI_FLASH_CS=0;				    SPI1_ReadWriteByte(0x90);//发送读取ID命令	    SPI1_ReadWriteByte(0x00); 	    SPI1_ReadWriteByte(0x00); 	    SPI1_ReadWriteByte(0x00); 	 			   Temp|=SPI1_ReadWriteByte(0xFF)<<8;  Temp|=SPI1_ReadWriteByte(0xFF);	 SPI_FLASH_CS=1;				    return Temp;
}   		    
//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{ u16 i;    												    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在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!	 
void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{u16 i;  SPI_FLASH_Write_Enable();                  //SET WEL SPI_FLASH_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]);//循环写数  SPI_FLASH_CS=1;                            //取消片选 SPI_Flash_Wait_Busy();					   //等待写入结束
} 
//无检验写SPI FLASH 
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能 
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{ 			 		 u16 pageremain;	   pageremain=256-WriteAddr%256; //单页剩余的字节数		 	    if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节while(1){	   SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);if(NumByteToWrite==pageremain)break;//写入结束了else //NumByteToWrite>pageremain{pBuffer+=pageremain;WriteAddr+=pageremain;	NumByteToWrite-=pageremain;			  //减去已经写入了的字节数if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节else pageremain=NumByteToWrite; 	  //不够256个字节了}};	    
} 
//写SPI FLASH  
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)  		   
u8 SPI_FLASH_BUF[4096];
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{ u32 secpos;u16 secoff;u16 secremain;	   u16 i;    secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16secoff=WriteAddr%4096;//在扇区内的偏移secremain=4096-secoff;//扇区剩余空间大小   if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节while(1) {	SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容for(i=0;i<secremain;i++)//校验数据{if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除  	  }if(i<secremain)//需要擦除{SPI_Flash_Erase_Sector(secpos);//擦除这个扇区for(i=0;i<secremain;i++)	   //复制{SPI_FLASH_BUF[i+secoff]=pBuffer[i];	  }SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区  }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间. 				   if(NumByteToWrite==secremain)break;//写入结束了else//写入未结束{secpos++;//扇区地址增1secoff=0;//偏移位置为0 	 pBuffer+=secremain;  //指针偏移WriteAddr+=secremain;//写地址偏移	   NumByteToWrite-=secremain;				//字节数递减if(NumByteToWrite>4096)secremain=4096;	//下一个扇区还是写不完else secremain=NumByteToWrite;			//下一个扇区可以写完了}	 };	 	 
}
//擦除整个芯片
//整片擦除时间:
//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();   				   //等待芯片擦除结束
}   
//擦除一个扇区
//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();   				   //等待擦除完成
}  
//等待空闲
void SPI_Flash_Wait_Busy(void)   
{   while ((SPI_Flash_ReadSR()&0x01)==0x01);   // 等待BUSY位清空
}  
//进入掉电模式
void SPI_Flash_PowerDown(void)   
{ SPI_FLASH_CS=0;                            //使能器件   SPI1_ReadWriteByte(W25X_PowerDown);        //发送掉电命令  SPI_FLASH_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
}   

flash.h

#ifndef __FLASH_H
#define __FLASH_H			    
#include "sys.h" 
#define W25Q80 	0XEF13 	
#define W25Q16 	0XEF14
#define W25Q32 	0XEF15
#define W25Q64 	0XEF16
extern u16 SPI_FLASH_TYPE;//定义我们使用的flash芯片型号		
#define	SPI_FLASH_CS PAout(2)  //选中FLASH					 
extern u8 SPI_FLASH_BUF[4096];
//W25X16读写
#define FLASH_ID 0XEF14
//指令表
#define W25X_WriteEnable		0x06 
#define W25X_WriteDisable		0x04 
#define W25X_ReadStatusReg		0x05 
#define W25X_WriteStatusReg		0x01 
#define W25X_ReadData			0x03 
#define W25X_FastReadData		0x0B 
#define W25X_FastReadDual		0x3B 
#define W25X_PageProgram		0x02 
#define W25X_BlockErase			0xD8 
#define W25X_SectorErase		0x20 
#define W25X_ChipErase			0xC7 
#define W25X_PowerDown			0xB9 
#define W25X_ReleasePowerDown	0xAB 
#define W25X_DeviceID			0xAB 
#define W25X_ManufactDeviceID	0x90 
#define W25X_JedecDeviceID		0x9F void SPI_Flash_Init(void);
u16  SPI_Flash_ReadID(void);  	    //读取FLASH ID
u8	 SPI_Flash_ReadSR(void);        //读取状态寄存器 
void SPI_FLASH_Write_SR(u8 sr);  	//写状态寄存器
void SPI_FLASH_Write_Enable(void);  //写使能 
void SPI_FLASH_Write_Disable(void);	//写保护
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead);   //读取flash
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);//写入flash
void SPI_Flash_Erase_Chip(void);    	  //整片擦除
void SPI_Flash_Erase_Sector(u32 Dst_Addr);//扇区擦除
void SPI_Flash_Wait_Busy(void);           //等待空闲
void SPI_Flash_PowerDown(void);           //进入掉电模式
void SPI_Flash_WAKEUP(void);			  //唤醒
#endif

函数虽多。。其实用到一般也只有读和写

写:

/写SPI FLASH  
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)  		   
u8 SPI_FLASH_BUF[4096];
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) 

//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)


主函数实现的功能跟I2C类似。。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "key.h"
#include "spi.h"
#include "flash.h"   	
//要写入到W25Q64的字符串数组
const u8 TEXT_Buffer[]={"MY SPI TEST"};
u32 FLASH_SIZE;
#define SIZE sizeof(TEXT_Buffer)	
void init(void)
{delay_init();	    	 //延时函数初始化	  uart_init(9600);	 	//串口初始化为9600LED_Init();		  		//初始化与LED连接的硬件接口LCD_Init();KEY_Init();				//按键初始化		 	SPI_Flash_Init();  		//SPI FLASH 初始化 	 POINT_COLOR=RED;//设置字体为红色 LCD_ShowString(60,50,200,16,16,"Mini STM32");	LCD_ShowString(60,70,200,16,16,"SPI TEST");	LCD_ShowString(60,90,200,16,16,"ATOM@YH");LCD_ShowString(60,110,200,16,16,"2015/1/26");	LCD_ShowString(60,130,200,16,16,"WK_UP:Write  KEY0:Read");	//显示提示信息		while(SPI_Flash_ReadID()!=W25Q64)							//检测不到W25Q64{LCD_ShowString(60,150,200,16,16,"25Q64 Check Failed!");delay_ms(500);LCD_ShowString(60,150,200,16,16,"Please Check!      ");delay_ms(500);LED0=!LED0;//DS0闪烁}LCD_ShowString(60,150,200,16,16,"25Q64 Ready!");FLASH_SIZE=8*1024*1024;	//FLASH 大小为8M字节POINT_COLOR=BLUE;		//设置字体为蓝色	  
}int main(void){ u8 key;u16 i=0;u8 datatemp[SIZE];init();while(1){key=KEY_Scan(0);if(key==WKUP_PRES)	//WK_UP 按下,写入W25Q64{LCD_Fill(0,170,239,319,WHITE);//清除半屏    LCD_ShowString(60,170,200,16,16,"Start Write W25Q64....");SPI_Flash_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE);		//从倒数第100个地址处开始,写入SIZE长度的数据LCD_ShowString(60,170,200,16,16,"W25Q64 Write Finished!");	//提示传送完成}if(key==KEY0_PRES)	//KEY0 按下,读取字符串并显示{LCD_ShowString(60,170,200,16,16,"Start Read W25Q64.... ");SPI_Flash_Read(datatemp,FLASH_SIZE-100,SIZE);				//从倒数第100个地址处开始,读出SIZE个字节LCD_ShowString(60,170,200,16,16,"The Data Readed Is:  ");	//提示传送完成LCD_ShowString(60,190,200,16,16,datatemp);					//显示读到的字符串}i++;delay_ms(10);if(i==20){LED0=!LED0;//提示系统正在运行	i=0;}		   }
}




http://chatgpt.dhexx.cn/article/HOxJpE6l.shtml

相关文章

STM-32:SPI通信协议/W25Q64简介—软件SPI读写W25Q64

目录 一、SPI简介1.1电路模式1.2通信原理1.3SPI时序基本单元1.3.1起始和终止1.3.2交换字节 二、W25Q642.1W25Q64简介2.2W25Q64硬件电路2.3W25Q64框图2.4Flash操作注意事项 三、软件SPI读写W25Q643.1接线图3.2程序代码 一、SPI简介 SPI是串行外设接口&#xff08;Serial Periph…

STM32CubeMx之硬件SPI驱动W25Q64

STM32CubeMx之硬件SPI驱动W25Q64 1.SPI简介 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&a…

SPI读写串行FLASH(W25Q64)

文章目录 1、SPI协议1、硬件连接2、通讯时序3、不同的通信模式 2、W25Q64介绍3、SPI读写驱动编写4、源码 1、SPI协议 SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface)&#xff0c;即串行外围设备接口&#xff0c;是一种高速全双工的通信总线。它被广泛地…

STM32入门开发: 介绍SPI总线、读写W25Q64(FLASH)(硬件+模拟时序)

一、环境介绍 编程软件: keil5 操作系统: win10 MCU型号: STM32F103ZET6 STM32编程方式: 寄存器开发 (方便程序移植到其他单片机) SPI总线: STM32本身支持SPI硬件时序&#xff0c;本文示例代码里同时采用模拟时序和硬件时序两种方式读写W25Q64。 模拟时序更加方便移植到…

树莓派系统介绍

树莓派是一个微型计算机&#xff0c;和普通的电脑没有什么区别&#xff0c;只是体积更小&#xff0c;只有卡片大小&#xff0c;存储能力和计算能力会差一点&#xff0c;主要用于学习&#xff0c;实验所用。 是电脑就要安装操作系统&#xff0c;树莓派官方推荐了两种系统&#…

树莓派 zero linux,树莓派 zero基本调试

回家之前就从网上购买了一堆设备&#xff0c;回去也不能闲着&#xff0c;可以利用家里相对齐全的准备安装调试。结果人还没回来&#xff0c;东西先到了。 购买的核心装备是树莓派zero w&#xff0c;虽然已经知道它比家族大哥树莓派小不少&#xff0c;但拿到手里还是惊奇它的小巧…

树莓派c语言访问mariadb,树莓派之MariaDB

8种机械键盘轴体对比 本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f; 安装MariaDB MariaDB是MySQL的一个分支 直接命令行敲入&#xff1a;1sudo apt-get install mariadb-server 即可完成安装。 一开始安装完成后不知道是需要初始化…

python树莓派_树莓派python

广告关闭 腾讯云11.11云上盛惠 &#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高返5000元&#xff01; 最初拿到树莓派的时候测试过,没成功,后来发现一张华丽丽的说明图,顿时醒悟了.. 记录下来,主要学习自 :htt…

树莓派硬件介绍及配件选择

目录 树莓派Datasheet下载地址&#xff1a; Raspberry 4B 外观图&#xff1a; 技术规格书&#xff1a; 性能介绍&#xff1a; 树莓派配件选用 电源的选用&#xff1a; 树莓派外壳选用&#xff1a; 内存卡/U盘选用 树莓派Datasheet下载地址&#xff1a; Raspberry Pi …

树莓派Pico开发版

Pico开发版有16个PWM通道非常适合用于舵机及电机的控制[1]。 单板机(4B)、微控制器(Pico)&#xff0c;树莓派支持Micro Python和C编程[3]。Thony是Python的开发环境。 [1]【评测】树莓派Pico开发板详细评测&#xff0c;到底值不值&#xff1f; [2] Pico树莓派中文站。 [3]一…

1-树莓派及配件购买推荐

树莓派4b主板及配件购买推荐。 作者&#xff1a;白宸羽 套餐 购买链接&#xff1a;https://item.taobao.com/item.htm?spma1z10.5-c-s.w4002-22269478747.11.277c1a24rkExbq&id597680312428 TF卡建议选择16g&#xff0c;套餐建议选择“摄像头套餐” HDMI用于连接显示屏&a…

python树莓派编程_python树莓派编程

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 例如,你可以用树莓派搭建你自己的家用云存储服务器。? 树莓派用python来进行编程。 树莓派项目的一个核心思想是python编程语言的使用。 python允许树莓派的拥…

树莓派如何第一次启动-树莓派从购买到启动一步一步完全版!

背景 闲来无事&#xff0c;在咸鱼上买了一个树莓派3B。买来配件都十分齐全&#xff0c;于是就想着启动来测试一下。下面是树莓派第一次启动的全过程&#xff0c;包含安装系统。 1 准备工作 1.1所需硬件 笔记本电脑、树莓派3B、16GTF卡、读卡器、电源和电源线共四种。 无需准…

树莓派价格暴涨买不起?他们自己做了一块价格还不到1/4的开发板平替树莓派,还火到海外去了

众所周知&#xff0c;树莓派诞生之初时的设计有四大要点 一个可编程的硬件&#xff08;功能很强&#xff09;√足够有趣&#xff0c;能吸引年轻人&#xff08;可玩性确实高&#xff09;√能反复扔进书包&#xff0c;不怕挤坏&#xff08;质量杠杠滴&#xff09;√ 还有最后一…

当你拿到树莓派后要干什么

最近刚买了一个树莓派&#xff08;pi4 8g&#xff09;&#xff0c;先在分享一些搭建细节&#xff0c;帮助他人更快上手 1.烧录sd卡 官网下载文件 Operating system images – Raspberry Pihttps://www.raspberrypi.com/software/operating-systems/ 下载烧录工具&#xff1a…

[树莓派1] 硬件选购指南

树莓派是一款基于 ARM 架构的微型电脑主板&#xff0c;你可以把它理解成一台微型服务器。目前最新版是树莓派 4b&#xff0c;最大支持 8G 内存。 以前树莓派内存太小了&#xff0c;就没怎么折腾&#xff1b;现在树莓派 CPU 和内存都提高了&#xff0c;就有玩的价值了。 我购买树…

树莓派001-购买树莓派

我是买的树莓派3B中国版-外加一个32G的内存卡。 一个树莓派呢也不算贵&#xff0c;才190一个。当然还有更便宜的。不过贵点性能也就要好点。 树莓派3B 淘宝上有很多树莓派卖&#xff0c;大家择其合适者而购之。 不过你得确保你自己有一个质量不错&#xff0c;容量够大的内存卡&…

一 树莓派简介与购买

什么是树莓派 不知道你们之前听过树莓派没有&#xff0c;反正我当初玩之前是没听说过&#xff0c;第一次听说树莓派这个东西老感觉像个食品&#xff0c;后来百度一下才知道这是一个基于ARM的开发板。它的诞生是这样的&#xff0c;英国剑桥大学有个博士叫埃厄普顿&#xff0c;他…

树莓派4新手购买指南

作为一名嵌入式新手&#xff0c;也曾经不止一次的在淘宝想淘一款自己入手开发的嵌入式设备&#xff0c;网上各种开发板比比皆是&#xff0c;我也是偶尔听到出来一款Raspberry Pi&#xff0c;这款设备性价比绝对没得说&#xff0c;但是网上如何去选择设备&#xff0c;是买个单板…

如何购买您的第一个树莓派

第一课&#xff1a;什么是树莓派 第二课&#xff1a;树莓派能做什么 第三课&#xff1a;购买您的第一个树莓派 第四课&#xff1a;如何安装树莓派系统 1~4课如果看过C语言版本的&#xff0c;请掠过… 会不会买到假货 关于这个问题&#xff0c;可能是很多初学者担心的&#x…