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

📄 spi_con_one.c

📁 at45db321驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <Mega32.h>
#include "type.h"
#include "45DB321.h" 
#include <Delay.h>

volatile unsigned char data[528];
 
/* SPSR */
#define SPIF    7
#define WCOL    6
/* bits 5-1 reserved */
#define SPI2X   0

/* SPCR */
#define SPIE    7
#define SPE     6
#define DORD    5
#define MSTR    4
#define CPOL    3
#define CPHA    2
#define SPR1    1
#define SPR0    0 

/* SFIOR */
#define ADTS2   7
#define ADTS1   6
#define ADTS0   5
/* bit 4 reserved */
#define ACME    3
#define PUD     2
#define PSR2    1
#define PSR10   0

#define RESET 0
#define WP 1
#define CS  4
#define SI 5
#define SO 6
#define SCK 7 

#define RESET_0 PORTB&=~(1<<RESET)
#define RESET_1 PORTB|=(1<<RESET)  
 
#define CS_0 PORTB&=~(1<<CS)
#define CS_1 PORTB|=(1<<CS) 
#define WP_0 PORTB&=~(1<<WP)
#define WP_1 PORTB|=(1<<WP)
 
#define AT_SO PINB&(1<<SO)

#define SI_0 PORTB&=~(1<<SI)
#define SI_1 PORTB|=(1<<SI)

#define SCK_0 PORTB&=~(1<<SCK)
#define SCK_1 PORTB|=(1<<SCK)
 
void IsBusy(void);
unsigned char ReadFlashState(void);  

static void delayUS(unsigned int n) //n us延时
{   
    unsigned int ss=0;
    for(;ss<n;ss++)
    {
    #asm("nop");
    #asm("nop");
    #asm("nop");
    #asm("nop");
    }
}
static void delayMS(unsigned int k)//n ms延时
{   
    unsigned int mm=0;
    for(;mm<k;mm++)
    {
       delayUS(1000);
    }
}

static void SPI_Init(void)
{
   //PORTB|=0b11110011;
   //DDRB|=0b10110011;	 
   //SFIOR|=(1<<PUD); 
   
   DDRB|=0xB3;
   PORTB|=0x13;   //0x43 miso上拉. ,0x13,miso不上拉.
   
   //SPCR=0X5F;//0X5F,0X5B:32K SPI充许,主模式,高字节在前,工作模式3,fck/16    //TO fck/128 //TO FCK/4
   //SPSR=0X00;
   //中断开0XDF
}

void SPI_WriteByte(uchar spi_write_data)
{
   uchar i;
   SCK_1; //保证sck为高
   #asm("nop");
   #asm("nop");
   
   for(i=0;i<8;i++) //send 8 bits
   {
     SCK_0;    
     #asm("nop");
     
     if((spi_write_data<<i)&0x80)
     {   
     SI_1; 
     }
     else
     {   
     SI_0; 
     }
     #asm("nop");
     #asm("nop");
     #asm("nop");
     #asm("nop");
   
     SCK_1;
     #asm("nop");
     #asm("nop");
     #asm("nop");
     #asm("nop");
   }
}

uchar SPI_ReadByte(void)
{
uchar i,temp;
// bit bit_in;
SCK_1;
#asm("nop");
temp=0x00;//initialize the data output
   
for(i=0;i<8;i++) 
{
     SCK_0;
     #asm("nop");
     #asm("nop");
     #asm("nop");
     #asm("nop");
     SCK_1;
     #asm("nop");
     #asm("nop");
     #asm("nop");
     #asm("nop");
   temp <<= 1;
   if(AT_SO)
   {
   temp |=1;
   }
   else
   {
   temp |=0;
   }
}
return (temp);
}
/*-----------------------------------------------------
             SPI_WriteByte()

Func:      Send a byte of data to the device using
           SPI interface. 
Input:     the data(one byte) you want to send.
Output:    No.
Attention: MODE-->Inactive Clock Polarity High 
           and SPI Mode 3
--------------------------------------------------------*/
/*unsigned char SPI_WriteByte(unsigned char output)
{   
    unsigned char input=0; 
    SPDR=output; 
    while(!(SPSR & 0x80));
    input=SPDR;
    return input;
} 
  */

/*-------------------------------------------------------
            AT45_Write_Buffer()

Func:      Write a block of data to buffer 1 or 2 of 
           the device AT45DB321C. 
Input:     (1)0: choice buffer 1; 
              1: choice buffer 2.
           (2)address of the buffer(0~257,nine bits:BFA8~BFA0).
           (3)a pointer poited to the first address of an array; 
                  
Output:    No.
Attention: (1)the data stream load to the device before
              you write user_data into the device is:
            
           1000 0100 (for buffer 1)
           1000 0111 xxxx xxxx xxxx xxxBFA8 BFA7~BFA0 
           (2) the end of the data array you want to load
               into the device must be '\n'. 
           (3) 1 buffer=258 bytes
---------------------------------------------------------*/
static void AT45_Write_Buffer(unsigned char buffer_choice,unsigned int address, unsigned char *string, unsigned int buf_len)
{
unsigned int i;
unsigned char t; 
CS_0; //active the device
#asm("nop");
#asm("nop");
if(buffer_choice)
{
     SPI_WriteByte(0x87);   //buffer 2
}
else
{
 SPI_WriteByte(0x84); //buffer 1
}
SPI_WriteByte(BYTE_DUMMY);      //xxxx xxxx don’t care bits
t=(uchar)((address>>8)&0x03);
SPI_WriteByte(t);   //BFA9,BFA8
SPI_WriteByte((uchar)address); //BFA7~BFA0
for(i=0;i<buf_len;i++)              /*buffer. More detail in the datasheet.*/
{   
    SPI_WriteByte(string[i]);  
    delayUS(30);
}    
CS_1; //inactive the device
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
}

/*-----------------------------------------------------------------
            AT45_Read_Buffer()

Func:      Read a block of data from buffer 1 or 2 of 
           the device AT45DB041B. 
Input:     (1)0: choice buffer 1; 
              1: choice buffer 2.
           (2)nine address bits(BFA8~BFA0):
           (3)how many bytes do you want to read?(<258)
           (4)a pointer poited to the first address of an array; 
                  
Output:    No.
Attention: (1)the data stream load to the device before
              you write user_data into the device is:      
      
           0101 0100 (for buffer 1)
           0101 0110 xxxx xxxx xxxx xxxBFA8 BFA7~BFA0 xxxx xxxx           
------------------------------------------------------------------*/
static void AT45_Read_Buffer(unsigned char buffer_choice,unsigned int address,unsigned int buf_len,unsigned char * string)
{
unsigned int i;
unsigned char tp;
CS_0; //active the device
#asm("nop");
#asm("nop");
if(buffer_choice)
{
     SPI_WriteByte(0x0D6);   //buffer 2
}
else
{
 SPI_WriteByte(0x0D4); //buffer 1
}
SPI_WriteByte(BYTE_DUMMY);      //xxxx xxxx
tp=(uchar)((address>>8)&0x03);
SPI_WriteByte(tp);   //BFA9,BFA8
SPI_WriteByte((uchar)address); //BFA7~BFA0
SPI_WriteByte(BYTE_DUMMY);      //xxxx xxxx
//now read the user_data 
for(i=0;i<buf_len;i++) 
   {
   string[i]=SPI_ReadByte(); 
   }
CS_1;
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop"); 
}



/*-----------------------------------------------------------
         AT45_MemoryRead()

Func:   sequentially read a continuous stream of data 
        from the device's main memory.
Input: (1)which page?(0~8192)---------------------page
        (2)from where of the page(0~258)--------address
        (3)how many bytes do you want to read?------num
        (4)a pointer poited to the first address 
           of an array.the data is store in this array.           
Output: No.
Attention: D2h--r PA12~PA0 BA9--BA0--32bit Dummy--
           xxxx xxxx--xxxx xxxx--xxxx xxxx--xxxx xxxx
-------------------------------------------------------------*/  
//可以读任意位置.
static void AT45_MemoryRead(unsigned int page,unsigned int address,unsigned int num,unsigned char * string)
{
unsigned int i=0;
unsigned char temp=0;
IsBusy();
CS_0;
#asm("nop");
#asm("nop");
//send command stream of data
SPI_WriteByte(0xE8);// MEM_PAGE_READ    //0x68 我改为了0xD2页读   0XE8
SPI_WriteByte((uchar)(page>>6)); //地址最高字节

   temp = (((uchar)page)<<2);
   temp = temp|((address>>8)&0x03);//地址高字节
   SPI_WriteByte(temp);

   SPI_WriteByte((uchar)address);//地址低字节

   SPI_WriteByte(BYTE_DUMMY);//32 don't care bits 
   SPI_WriteByte(BYTE_DUMMY);
   SPI_WriteByte(BYTE_DUMMY);
   SPI_WriteByte(BYTE_DUMMY);
//now read the user_data
//2048*264=538624,but don't read so many 
//bytes at one time.
for(i=0;i<num;i++)
{  
   //delayUS(10);  
   #asm("nop");
   string[i]=SPI_ReadByte();  
}
CS_1; 
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
delayMS(50);
IsBusy();
} 
/*----------------------------------------------------
              AT45_MemoryPageWrite()

Func:     Main Memory Page Program through Buffer 1 or 2.
Input:    (1)0: use buffer 1
             1: use buffer 2
          (2)the start address of the buffer.-----address
          (3)which page will be write?(0~2047)-------page
          (4) how many bytes will be write?-----------num
          (5)a pointer poited to the first address of 
             the array in which you store your data.
          
Output:   No.
Attention: (1)This operation write data to buffer,until the 
            /cs change from low to high, then load the 
            data from buffer to the choiced page.
            the initial stream of data is:
         
           0x82 (use buffer 1)
           0x85--xxxx PA10~PA7--PA6~PA0 BFA8--BFA7~BFA0            
           
------------------------------------------------------*/ 
static void AT45_MemoryPage_Write(unsigned char buffer_choice,unsigned int page,unsigned int address,unsigned int num,unsigned char *string)
{
unsigned int i;
unsigned char temp;
IsBusy();
CS_0;
#asm("nop");
#asm("nop");
//send command stream of data
if(buffer_choice)
{
    SPI_WriteByte(0x85);    //buffer 2 //0x85   //0x59
}
else
{
    SPI_WriteByte(0x82); //buffer 1 //0x82     //0x58
}
SPI_WriteByte((uchar)(page>>6)); //地址最高字节

   temp = (((uchar)page)<<2);
   temp = temp|((address>>8)&0x03);//地址高字节
   SPI_WriteByte(temp);

⌨️ 快捷键说明

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