⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 这是C8051F005的SPI通信程序
💻 C
字号:
#include <c8051f020.h>
#include <stdio.h>
#include <intrins.h>

unsigned int Count1msInc;
unsigned int AT450XXPageAddr;

void SYSCLK_Init (void);
void PORT_Init (void);
void SPI0_Init (void);
void Timer0_Init (void);

#define SYSCLK     11059200
#define DF_RESET     P4&=~0x10; P4|=0x10;      // AT45DB081复位
#define DF_RDY_BUSY    P4|=0x20; while(!(P4&0x20));  // 等待AT45DB081准备好
#define DF_CHIP_SELECT    P4&=~0x4;       // AT45DB081片选开
#define DF_CHIP_NOSELECT   P4|=0x4;       // AT45DB081片选关
#define RAM_CHIP_SELECT_BANK0  ES0=1;P4 = 0xF4;  
#define RAM_CHIP_SELECT_BANK1  P4 = 0xF5;  
#define BUFFER_1 0x00       // buffer 1
#define BUFFER_2 0x01       // buffer 2
#define BUFFER_1_WRITE 0x84     // buffer 1 write
#define BUFFER_2_WRITE 0x87     // buffer 2 write
#define BUFFER_1_READ  0x54     // buffer 1 read (change to 0xD4 for SPI mode 0,3)
#define BUFFER_2_READ  0x56     // buffer 2 read (change to 0xD6 for SPI mode 0,3)
#define B1_TO_PAGE_WITH_ERASE 0x83    // buffer 1 to main memory page program with built-in erase
#define B2_TO_PAGE_WITH_ERASE 0x86    // buffer 2 to main memory page program with built-in erase
#define B1_TO_PAGE_WITHOUT_ERASE 0x88   // buffer 1 to main memory page program without built-in erase
#define B2_TO_PAGE_WITHOUT_ERASE 0x89   // buffer 2 to main memory page program without built-in erase
#define PAGE_PROG_THROUGH_B1 0x82    // main memory page program through buffer 1
#define PAGE_PROG_THROUGH_B2 0x85    // main memory page program through buffer 2
#define AUTO_PAGE_REWRITE_THROUGH_B1 0x58  // auto page rewrite through buffer 1
#define AUTO_PAGE_REWRITE_THROUGH_B2 0x59  // auto page rewrite through buffer 2
#define PAGE_TO_B1_COMP 0x60     // main memory page compare to buffer 1
#define PAGE_TO_B2_COMP 0x61     // main memory page compare to buffer 2
#define PAGE_TO_B1_XFER 0x53     // main memory page to buffer 1 transfer
#define PAGE_TO_B2_XFER 0x55     // main memory page to buffer 2 transfer
#define STATUS_REGISTER 0x57
#define MAIN_MEMORY_PAGE_READ 0x52    // main memory page read (change to 0xD2 for SPI mode 0,3)

void SendSPIByte(unsigned char ch)
{
  SPIF = 0;
  SPI0DAT = ch;
  while (SPIF == 0);      // 等待写结束           
} 
unsigned char GetSPIByte(void)
{
        SPIF = 0;
  SPI0DAT = 0;
  while (SPIF == 0);
  return  SPI0DAT;                   // 等待读结束
}
//启用缓存1读
void FlashBuffer1Read(unsigned int star_addr,unsigned int len, unsigned char *buffer) //从缓冲区1的指定位置(0-263)中读入指定字节
{                                       
       unsigned int i;
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(BUFFER_1_READ);  //缓冲区1为54H
  SendSPIByte(0);
  SendSPIByte((unsigned char)(star_addr>>8));
  SendSPIByte((unsigned char)star_addr);
  SendSPIByte(0);
  for (i=0;i<len;i++)
  {
        buffer = GetSPIByte();   // read data from SPI
     }
        DF_CHIP_NOSELECT;
}
//启用缓存2读
void FlashBuffer2Read(unsigned int star_addr,unsigned int len, unsigned char *buffer) //从缓冲区2的指定位置(0-263)中读入指定字节
{                                       
       unsigned int i;
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(BUFFER_2_READ);  //缓冲区2为56H
  SendSPIByte(0);
  SendSPIByte((unsigned char)(star_addr>>8));
  SendSPIByte((unsigned char)star_addr);
  SendSPIByte(0);
  for (i=0;i<len;i++)
  {
      buffer = GetSPIByte();     // read data from SPI
          buffer++;
  }
        DF_CHIP_NOSELECT;
}
//启用缓存1写
void FlashBuffer1Write(unsigned int start_addr, unsigned int len,unsigned char *buffer) //向缓冲区1的指定位置(0-263)写入指定字节
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好?
     DF_CHIP_SELECT;//芯片选择       
  SendSPIByte(BUFFER_1_WRITE);//缓冲区1为84H
     SendSPIByte(0x00);
     SendSPIByte((unsigned char)(start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}
//启用缓存2写
void FlashBuffer2Write(unsigned int start_addr, unsigned int len,unsigned char *buffer) //向缓冲区2的指定位置(0-263)写入指定字节
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好?
     DF_CHIP_SELECT;//芯片选择     
  SendSPIByte(BUFFER_2_WRITE);//缓冲区2为87H
     SendSPIByte(0x00);
     SendSPIByte((unsigned char)(start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}
//读取状态
unsigned char GetFlashStatus() //读Flash当前状态Bit7=1:空闲 0:忙 Bit6=1:比较结果不匹配 0:匹配 Bit5Bit3Bit2:芯片标志 100:081 
{
        unsigned char idata ret;
  DF_CHIP_SELECT;//芯片选择
        SendSPIByte(STATUS_REGISTER);
        ret=GetSPIByte();
        DF_CHIP_NOSELECT;
        return ret;
}
//读主存至缓存
void PageToBuffer1(void)  //从Flash读一页至缓存1
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(PAGE_TO_B1_XFER);
  SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
  SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
  SendSPIByte(0);    
  DF_CHIP_NOSELECT;
}
//读主存至缓存
void PageToBuffer2(void)    //从Flash读一页至缓存2
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(PAGE_TO_B2_XFER);
  SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
  SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
  SendSPIByte(0);    
  DF_CHIP_NOSELECT;
}
//缓存1写主存
void FlashBuffer1ProgNoErase(void)  //直接将缓存1写入Flash一页(不擦除)
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(B1_TO_PAGE_WITHOUT_ERASE);
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
        SendSPIByte(0x00);
  DF_CHIP_NOSELECT;
}
//缓存2写主存
void FlashBuffer2ProgNoErase(void) //直接将缓存2写入Flash一页(不擦除)
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(B2_TO_PAGE_WITHOUT_ERASE);
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
        SendSPIByte(0x00);
  DF_CHIP_NOSELECT;
}
//擦除+缓存1写主存
void FlashBuffer1ProgAutoErase(void) //直接将缓存1写入Flash一页(先擦除)
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(B1_TO_PAGE_WITH_ERASE);
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
        SendSPIByte(0x00);
  DF_CHIP_NOSELECT;
}

//擦除+缓存2写主存
void FlashBuffer2ProgAutoErase(void) //直接将缓存2写入Flash一页(先擦除)
{
  DF_RDY_BUSY;//测芯片准备好?
  DF_CHIP_SELECT;//芯片选择
  SendSPIByte(B2_TO_PAGE_WITH_ERASE);
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
        SendSPIByte(0x00);
  DF_CHIP_NOSELECT;
}

//读主存
//写缓存+缓存写主存
void FlashProgViaBuffer1(unsigned int start_addr, unsigned int len,unsigned char *buffer) //将指定数据通过缓存1写入Flash指定位置(不擦除)
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好?
     DF_CHIP_SELECT;//芯片选择     
  SendSPIByte(PAGE_PROG_THROUGH_B1);//缓冲区1为82H
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}
//写缓存+缓存写主存
void FlashProgViaBuffer2(unsigned int start_addr, unsigned int len,unsigned char *buffer) //将指定数据通过缓存2写入Flash指定位置(不擦除)
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好?
     DF_CHIP_SELECT;//芯片选择     
  SendSPIByte(PAGE_PROG_THROUGH_B2);//缓冲区2为85H
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}

//写缓存+擦除+缓存写主存
void FlashAutoProgViaBuffer1(unsigned int start_addr, unsigned int len,unsigned char *buffer) //将指定数据通过缓存1写入Flash指定位置(先擦除)
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好?
     DF_CHIP_SELECT;//芯片选择     
  SendSPIByte(AUTO_PAGE_REWRITE_THROUGH_B1);//缓冲区1为84H
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}

//写缓存+擦除+缓存写主存
void FlashAutoProgViaBuffer2(unsigned int start_addr, unsigned int len,unsigned char *buffer) //将指定数据通过缓存2写入Flash指定位置(先擦除)
{
     unsigned int  i;
  DF_RDY_BUSY;//测芯片准备好? 
     DF_CHIP_SELECT;//芯片选择     
  SendSPIByte(AUTO_PAGE_REWRITE_THROUGH_B2);//缓冲区2为87H
        SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
        SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
     SendSPIByte((unsigned char)start_addr);
     for (i=0;i<len;i++)
      SendSPIByte(buffer);
  DF_CHIP_NOSELECT;
}

void main (void) {
unsigned char xdata MyBuff[270];
unsigned char xdata MyBuff1[270];
unsigned char xdata *idata MyBuff11;
unsigned int i,j;
 WDTCN = 0xde;                       // disable watchdog timer
 WDTCN = 0xad;
 SYSCLK_Init ();                     // initialize oscillator
 Timer0_Init();
 PORT_Init ();                       // initialize crossbar and GPIO
 EA=1;
 DF_RESET;
 SPI0_Init ();                       // initialize SPI0
// RAM_CHIP_SELECT_BANK0;
//    EMI0CF = 0x2F;
/*---------------------------------------------------------------------------
缓存读写测试
---------------------------------------------------------------------------*/
 for(j=0;j<264;j++)     //初始化数组数据为:0--264
  {
     MyBuff[j]=j;
    }   
 FlashBuffer1Write(0,264,MyBuff); //写数据至数据缓存区1
 _nop_();
 for(j=0;j<264;j++)     //初始化数组数据全为:0
  {
     MyBuff[j]=0;
    }
 FlashBuffer1Read(0,264,MyBuff);  //读数据缓存区1数据至数组
 _nop_();
/*---------------------------------------------------------------------------
FLASH读写测试
---------------------------------------------------------------------------*/
 for(i=0;i<4096;i++)
 { MyBuff[0]=i>>8;
   MyBuff[1]=i;           //将页地址写入数组的前两个字节.
  for(j=2;j<264;j++)
  {
     MyBuff[j]=i;
    }                    //向数组写数据共262个字节
        AT450XXPageAddr=i;     //指定待写页
  FlashBuffer1Write(0,264,MyBuff);//将数组的内容写入缓存1
  FlashBuffer1ProgAutoErase();  //将缓存的内容写入主存(带擦除)
    }
 _nop_();
 for(i=0;i<4096;i++)
 {  
     AT450XXPageAddr=i;     //指定待读页
     MyBuff11=0x0+i*264;     //指定数据放置的XRAM的地址(首地址为0x0).
  PageToBuffer2();     //将主存内容读入缓存2
  FlashBuffer2Read(0,264,MyBuff11);  //将缓存2的内容读入XRAM
  _nop_();         //在此设断点观察XRAM中的数据是否与写入的数据相符.
 }
 _nop_();         //同时在此设一断点在全部读完主存后观察XRAM中的内容.
/*---------------------------------------------------------------------------
其它测试
---------------------------------------------------------------------------*/
 AT450XXPageAddr=0;
 FlashBuffer1Write(20,14,"1234567890UUAA");
 FlashBuffer1Read(0,260,MyBuff1);
 FlashBuffer1Write(20,14,"3234567890UUAA");
 FlashBuffer1Read(20,14,MyBuff); //在此处设置断点,观察MyBuff的内容
 FlashBuffer1ProgNoErase();
 PageToBuffer2();
 FlashBuffer2Read(20,14,MyBuff); 
 Count1msInc=0;
 FlashBuffer2Read(100,14,MyBuff);
 Count1msInc=0;
 FlashBuffer1Write(20,14,"1234567890UUAA");
 Count1msInc=0;
 FlashBuffer1Read(100,14,MyBuff);
 Count1msInc=0;
 FlashBuffer1ProgNoErase(); 
 Count1msInc=0;
 PageToBuffer2();
 Count1msInc=0;
 FlashBuffer2Read(100,14,MyBuff);
 FlashProgViaBuffer1(100,14,MyBuff);
 //ErasingDataFlash();
 //EraseFlashPage(); 
 FlashBuffer1Read(1,1, MyBuff); //从缓冲区1的指定位置(0-263)中读入指定字节
 FlashBuffer2Read(1,1,MyBuff);  //从缓冲区2的指定位置(0-263)中读入指定字节
 FlashBuffer1Write(1,1,"!");
 FlashBuffer2Write(1,1,"1");
 GetFlashStatus();
 PageToBuffer1();
 PageToBuffer2();
 FlashBuffer1ProgNoErase();
 FlashBuffer2ProgNoErase();
 FlashBuffer1ProgAutoErase();
 FlashBuffer2ProgAutoErase();
 FlashProgViaBuffer1(1,1, MyBuff);
 FlashProgViaBuffer2(1,1, MyBuff);
 FlashAutoProgViaBuffer1(1,1, MyBuff);
 FlashAutoProgViaBuffer2(1,1, MyBuff);
 while(1);
}
void SYSCLK_Init (void)
{
   int i;                              // delay counter
   OSCXCN = 0x67;                      // start external oscillator with
                                       // 11.0592MHz crystal
   for (i=0; i < 256; i++) ;           // Wait for osc. to start up
   while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle
   OSCICN = 0x88;                      // select external oscillator as SYSCLK
                                       // source and enable missing clock
}
void PORT_Init (void)
{
   XBR0    = 0x07;                     // Enable SMBus, SPI0, and UART0
   XBR1    = 0x00;
   XBR2    = 0x44;                     // Enable crossbar and weak pull-ups
//   EMI0TC  = 0x21;
   P74OUT  = 0x00;
   P0MDOUT = 0x15;
}
void SPI0_Init (void)
{
   SPI0CFG = 0x07;                     // data sampled on 1st SCK rising edge
                                       // 8-bit data words
   SPI0CFG|=0xC0;//CKPOL =1;

   SPI0CN = 0x03;                      // Master mode; SPI enabled; flags
                                       // cleared
   SPI0CKR = SYSCLK/2/2000000-1;       // SPI clock <= 8MHz (limited by 
                                       // EEPROM spec.)
}

void Timer0_Init (void)
{
   CKCON|=0x8;
   TMOD|=0x1;    //16Bit
   TR0 = 0;                          // STOP Timer0
   TH0 = (-SYSCLK/1000) >> 8;      // set Timer0 to overflow in 1ms
   TL0 = -SYSCLK/1000;
   TR0 = 1;    // START Timer0
   IE|= 0x2; 
}
void Timer0_ISR (void) interrupt 1  //1ms
{
 TH0 = (-SYSCLK/1000) >> 8;  
    TL0 = -SYSCLK/1000;
 Count1msInc++;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -