前面说了STM32的I2C,作为STM32的另外一个串行接口就不得不提到了——SPI。与I2C差不多,同样有硬件接口,有库函数支持,我们要做的就是结合SPI接口芯片调用库函数,就能实现SPI驱动了。一切看代码,你会懂的,注释非常详细的,很适合初学者。代码能够直接用到实际项目工程里面去的。SPI芯片选用W25X系列。。。
演示效果使用超级终端或者SecureCRT 5.5(这货真的不错)
工程结构图:
1、工程里面的beep.c led.c usart1.c 与《STM32 基于库函数控制按键&nb… 》《STM32 串口例程之查询收》里面完全一样,这里就不在上代码。
2、main.c
//程序功能:主要用于测试SPI W25X16驱动是否正常
#include"stm32f10x.h"
#include"user_usart1.h"
#include"user_led.h"
#include"user_beep.h"
#include"user_spi_w25x16.h"
#include
#define FLASH_ID1 0xef3015
#define FLASH_ID2 0xef4015
#define FLASH_WriteAddress 0x000000
#define FLASH_ReadAddress FLASH_WriteAddress
#define FLASH_SectorErase FLASH_WriteAddress
#define CountOf(a) (sizeof(a)/sizeof(*(a)))
#define DataSize(CountOf(TxDataTable)-1)
u8 TxDataTable[]="Hello,I am wgchnln,我 爱 ARM,I will persist in learning ARM,坚决不放弃";
u8 RxDataTable[DataSize];
//=============================================
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
//=============================================
TestStatus User_SPI_DataCompare(u8 *TxData,u8 *RxData,u8 Num)
{
while(Num--)
{
if(*TxData!=*RxData)
{
return Failed;
}
RxData++;
TxData++;
}
return Successed;
}
void User_SPI_Test(void)
{
vu32 ID,DeviceID;
u8 Buffer;
volatile TestStatus Test1=Failed;
volatile TestStatus Test2=Successed; //存放两次测试的结果
printf("正在努力读取ID号.....");
User_LedSpark(Led1,2);
ID=User_SPI_W25X16_ReadID();
printf("flashID:%x",ID);
printf("正在努力读取DeviceID号......");
User_LedSpark(Led1,2);
DeviceID=User_SPI_W25X16_ReadDeviceID();
printf("flashDeviceID:%x",DeviceID);
if((ID==FLASH_ID1)||(ID==FLASH_ID2))
{
printf("ARM在芯片擦除......");
User_LedSpark(Led1,2);
User_SPI_W25X16_SectorErase(FLASH_SectorErase);
printf("完成");
printf("你要写入的数据:%s",TxDataTable);
printf("努力为你芯片写入中......");
User_LedSpark(Led1,2);
User_SPI_W25X16_ChipWrite(TxDataTable,FLASH_WriteAddress,DataSize);
printf("完成");
printf("芯片数据读取......");
User_LedSpark(Led1,2);
User_SPI_W25X16_ChipRead(RxDataTable,FLASH_ReadAddress,DataSize);
printf("完成");
User_LedSpark(Led1,2);
printf("为您读取的数据:%s",RxDataTable);
printf("为您做数据比较中......");
User_LedSpark(Led1,2);
Test1=User_SPI_DataCompare(RxDataTable,TxDataTable,DataSize);
if(Test1==Successed)
{
printf("数据相同");
}
else
{
printf("数据不相同");
User_LedSpark(Led2,2);
printf("为您分析可能原因:数据未写入、读取错误、或者两者同时存在");
}
printf("再一次芯片擦除......");
User_LedSpark(Led1,2);
User_SPI_W25X16_SectorErase(FLASH_SectorErase);
printf("完成");
printf("又一次芯片读取......");
User_LedSpark(Led1,2);
User_SPI_W25X16_ChipRead(RxDataTable,FLASH_ReadAddress,DataSize);
printf("完成");
printf("判断是否擦除掉......");
User_LedSpark(Led1,1);
for(Buffer=0;Buffer
{
if(RxDataTable[Buffer]!=0xff)
{
Test2=Failed;
}
}
if(Test2==Failed)
{
printf("失败");
printf("为您分析的可能原因:读取错误、擦除失败、或者两者同时存在");
}
else
{
printf("擦除OK");
}
printf("------------为您展示此次测试结果------------");
if((Test1==Successed)&&((Test2==Successed)))
{
User_LedSpark(Led1,2);
printf("恭喜你,SPI W25X16驱动测试通过啦");
}
else
{
User_LedSpark(Led2,2);
printf("糟糕,SPI功能演示失败了......原因可能是读写数据不一致、软件擦除失败");
}
}
else
{
User_LedSpark(Led2,2);
printf("悲剧了,SPI功能演示失败啦.....原因是芯片ID号码读取出错哦");
}
}
int main(void)
{
User_USART1Config();
printf("串口1配置......");
printf("完成");
printf("蜂鸣器初始化...");
User_BeepConfig();
printf("蜂鸣器测试......");
User_BeepStatus(BeepStatus_TurnOn);
printf("完成");