📄 spi_con.c
字号:
#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|=0xB3; //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;
for(i=0;i<8;i++) //send 8 bits
{
SCK_0;
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");
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
}
}
uchar SPI_ReadByte(void)
{
uchar i,temp;
// bit bit_in;
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(0xD2);// 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_MemoryPageWrite(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);
SPI_WriteByte((uchar)address);//地址低字节
//now write the user_data
i=0;
while(i<num)
{
SPI_WriteByte(string[i]);
i++;
}
CS_1;
delayMS(50);
//wait
IsBusy();
}
//规定写用buffer1,读用buffer1.
//写一个字节,向主存中.
void AT45_MemoryByteWrite(unsigned int page,unsigned int address,unsigned char d_byte)
{
unsigned char temp=0;
IsBusy();
CS_0;
SPI_WriteByte(0x82);
SPI_WriteByte((uchar)(page>>6)); //地址最高字节
SPI_WriteByte((unsigned char)((page<<2)|(address>>8)));
SPI_WriteByte((uchar)address);//地址低字节
SPI_WriteByte(d_byte);
CS_1;
delayMS(1);
IsBusy();
}
unsigned char AT45_MemoryByteRead(unsigned int page,unsigned int address)
{
unsigned char temp=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -