找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12542|回复: 0
打印 上一主题 下一主题
收起左侧

stm32单片机SPI通信程序(W25x16驱动程序)

[复制链接]
跳转到指定楼层
楼主
ID:73735 发表于 2015-2-19 00:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

main.c
#include "stm32f10x_it.h"
#include"hw_conf.h"
#include "spi_flash.h"
void delay(int d);
u8 DataByte=0;
u8 Tx_Buffer[] = {0x72,0x62};
u8 i, Rx_Buffer[BufferSize];
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = PASSED;
TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);
vu32 FLASH_ID = 0;
int main(void)
{
#ifdef DEBUG
  debug();
#endif
  Setup_System();
  SPI_FLASH_Init();
  
  SPI_FLASH_ByteWrite(0x72, 0x10F10F);
  DataByte = SPI_FLASH_ByteRead(0x10F10F);
  
  while (1)
  {
    if( DataByte==0x72)
    {
      GPIO_WriteBit(GPIOC,GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6)));
      delay(100);
      GPIO_WriteBit(GPIOC,GPIO_Pin_7,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_7)));
      delay(100);
    }  
  }
}

void delay(int d)
{
  int i = 0;
  for ( ;d;--d)
  for (i = 0;i<10000;i++);
}

TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }
    pBuffer1++;
    pBuffer2++;
  }
  return PASSED;  
}

hw_conf.c
#include"stm32f10x_lib.h"
#include "hw_conf.h"
ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void)
{
  RCC_DeInit();
  RCC_HSEConfig(RCC_HSE_ON);
  HSEStartUpStatus = RCC_WaitForHSEStartUp();
  if(HSEStartUpStatus == SUCCESS)
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2);
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
}
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;  //Configure SPI1 pins: NSS, SCK, MISO and MOSI
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  //Configure PA.4 as Output push-pull, used as Flash Chip select
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void SPI_configuration()  //SPI1 configuration
{
  SPI_InitTypeDef  SPI_InitStructure;
  
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //设置为主 SPI  
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  //SPI发送接收 8 位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //时钟悬空高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  //数据捕获于第二个时钟沿
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //内部 NSS 信号有 SSI位控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  //波特率预分频值为 4
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;   //数据传输从 MSB 位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;  //定义了用于 CRC值计算的多项式 7
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);   //Enable SPI1
}
void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM  
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif
}
void Setup_System(void)
{
RCC_Configuration();
GPIO_Configuration();
SPI_configuration();
NVIC_Configuration();
}
hw_conf.h
#ifndef   _hw_conf_H_
#define   _hw_conf_H_
extern void Setup_System(void);
#endif
SPI_flash.c
#include "stm32f10x_spi.h"
#include "spi_flash.h"
#define SPI_FLASH_PageSize 256
void SPI_FLASH_Init(void)
{
  SPI_FLASH_CS_HIGH();
}
void SPI_FLASH_ByteWrite(u8 Byte, u32 WriteAddr)
{
  SPI_FLASH_WriteEnable();
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(Page_Program);
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);  
  SPI_FLASH_SendByte(WriteAddr & 0xFF);
  
  SPI_FLASH_SendByte(Byte);
  SPI_FLASH_CS_HIGH();
  SPI_FLASH_WaitForWriteEnd();
}
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  SPI_FLASH_WriteEnable();
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(Page_Program);
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);  
  SPI_FLASH_SendByte(WriteAddr & 0xFF);
  
  while(NumByteToWrite--)
  {
    SPI_FLASH_SendByte(*pBuffer);
    pBuffer++;
  }
  SPI_FLASH_CS_HIGH();
  SPI_FLASH_WaitForWriteEnd();
}
u8 SPI_FLASH_ByteRead(u32 ReadAddr)
{
  u32 Temp = 0;
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(Read_Data);
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
  
  Temp = SPI_FLASH_SendByte(Dummy_Byte);
  SPI_FLASH_CS_HIGH();
  return Temp;
}
u32 SPI_FLASH_ReadID(void)
{
  u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(ReadJedec_ID);
  Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
  Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
  Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
  SPI_FLASH_CS_HIGH();      
  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
  return Temp;
}
void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(Read_Data);
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
}

u8 SPI_FLASH_ReadByte(void)
{
  return (SPI_FLASH_SendByte(Dummy_Byte));
}
u8 SPI_FLASH_SendByte(u8 byte)
{
  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
  SPI_SendData(SPI1, byte);
  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
  return SPI_ReceiveData(SPI1);
}
void SPI_FLASH_WriteEnable(void)
{
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(WriteEnable);
  SPI_FLASH_CS_HIGH();
}
void SPI_FLASH_WaitForWriteEnd(void)
{
  u8 FLASH_Status = 0;
  SPI_FLASH_CS_LOW();
  SPI_FLASH_SendByte(ReadStatusRegister);
  do
  {
    FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);
  } while((FLASH_Status & WriteStatusRegister) == SET);
  SPI_FLASH_CS_HIGH();
}
SPI_flash.h
#include "stm32f10x_lib.h"
#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H
#define  FLASH_WriteAddress       0x700700
#define  FLASH_ReadAddress        FLASH_WriteAddress
#define  FLASH_SectorToErase      FLASH_WriteAddress
#define  M25P64_FLASH_ID          0xEF0000
#define  BufferSize               (countof(Tx_Buffer)-1)
#define countof(a)                (sizeof(a) / sizeof(*(a)))
#define SPI_FLASH_PageSize        256
#define Dummy_Byte                0xA5
#define SPI_FLASH_CS_LOW()        GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define SPI_FLASH_CS_HIGH()       GPIO_SetBits(GPIOA, GPIO_Pin_4)

#define WriteEnable               0x06       //写使能,设置状态寄存器
#define WriteDisable              0x04       //写禁止
#define ReadStatusRegister        0x05       //读状态寄存器
#define WriteStatusRegister       0x01       //写状态寄存器
#define Read_Data                 0x03       //读取存储器数据
#define FastReadData              0x0B       //快速读取存储器数据
#define FastReadDualOutput        0x3B       //快速双端口输出方式读取存储器数据
#define Page_Program              0x02       //页面编程--写数据
#define BlockErace                0xD8       //块擦除
#define SectorErace               0x20       //扇区擦除
#define ChipErace                 0xC7       //片擦除
#define Power_Down                0xB9       //掉电模式
#define ReleacePowerDown          0xAB       //退出掉电模式、设备ID信息
#define ReadDeviceID              0xAB       //退出掉电模式、设备ID信息
#define ReadManuID_DeviceID       0x90       //读取制造厂商ID信息和设备ID信息
#define ReadJedec_ID              0x9F       //JEDEC的ID信息
void SPI_FLASH_Init(void);
void SPI_FLASH_SectorErase(u32 SectorAddr);
void SPI_FLASH_BulkErase(void);
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
u32 SPI_FLASH_ReadID(void);
void SPI_FLASH_StartReadSequence(u32 ReadAddr);
u8 SPI_FLASH_SendByte(u8 byte);
u8 SPI_FLASH_ReadByte(void);
u16 SPI_FLASH_SendHalfWord(u16 HalfWord);
void SPI_FLASH_WriteEnable(void);
void SPI_FLASH_WaitForWriteEnd(void);


void SPI_FLASH_ByteWrite(u8 Byte, u32 WriteAddr);
u8 SPI_FLASH_ByteRead(u32 ReadAddr);
#endif



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表