📄 spi.c
字号:
/************************************************
文件:spi.c
用途:SPI驱动
注意:
创建:2008.1.25
修改:2008.1.25
Copy Right (c) www.avrvi.com AVR与虚拟仪器
************************************************/
#include "..\config.h"
/*************************************************************************
** 函数名称: spi_init(void)
** 功能描述: SPI初始化
** 输 入:
** 输出 :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void spi_init(void)
{
DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//设置MOSI,SCK输出
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主机模式
}
/*************************************************************************
** 函数名称: SPI_MasterTransmit(char Data)
** 功能描述: SPI主机发送数据
** 输 入: Data 需要通过SPI传输的数据
** 输出 :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void SPI_MasterTransmit(char Data)
{
/* 启动数据传输 */
SPDR = Data;
/* 等待传输结束 */
while(!(SPSR & (1<<SPIF)))
;
}
/*******************************************************
描述: 主 存读取指定页地址与字节地址固写长度
参数: page_adderss 主存的页地址<=2047
buffer_adderss 缓存字节地址0-263
*Read_pHeader 读出数据存贮地址指针
length 读入数据的长度,<=263
*******************************************************/
void AT45DB041B_ContinuousArrayRead(unsigned int page_adderss,unsigned int buffer_adderss,unsigned char *Read_pHeader,unsigned char length)
{
unsigned int i;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
SPI_HostWriteByte(0xe8);
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)((page_adderss<<1)|(buffer_adderss>>8)));
SPI_HostWriteByte((unsigned char)buffer_adderss);
for(i=0;i<4;i++)
{
SPI_HostWriteByte(0x00);
}
for(i=0;i<length;i++)
{
Read_pHeader[i]=SPI_HostReadByte();
}
SPI_CS_D;
}
/*******************************************************
描述:主存转到缓存
参数:buffer 缓存选择0X01选取buffer 1, 0X02选取buffer 2,
page_adderss 主存的页地址<=2047
*******************************************************/
void AT45DB041B_MainMemoryBufferTransfer(unsigned char buffer,unsigned char page_adderss)
{
unsigned int i;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x53);break; //buffer 1 writ
case 2:SPI_HostWriteByte(0x55);break; //buffer 2 writ
}
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)(page_adderss<<1));
SPI_HostWriteByte(0x00);
SPI_CS_D;
}
/*******************************************************
Status Register Format:
-----------------------------------------------------------------------
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|--------|--------|-----|------|-----|-----|------|------|
|RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X |
| -----------------------------------------------------------------------
bit7 - 忙标记,0为忙1为不忙
当Status Register的位0移出之后,
接下来的时钟脉冲序列将使SPI器件继续
将最新的状态字节送出
bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。
bit5
bit4
bit3
bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记
16种不同密度的器件。
bit1
bit0 - 这2位暂时无效
*******************************************************/
uchar AT45DB041B_StatusRegisterRead(void)
{
uchar i;
SPI_CS_E;
SPI_HostWriteByte(0xd7);
i=SPI_HostReadByte();
SPI_CS_D;
return i;
}
/*******************************************************
描述: 一、 将指定的数据写入buffer 中的指定地址(0-263)
二、带擦除将buffer 中的数据写入到指定的页中
参数: buffer 缓存选择0X01选取buffer 1, 0X02选取buffer 2,
buffer_adderss 缓存字节地址0-263
*writ_pHeader 待写入数据的指针
length 写入数据的长度,<=263
page_adderss 主存的页地址<=2047
*******************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(unsigned char buffer,unsigned int buffer_adderss,unsigned char *writ_pHeader,unsigned int length,unsigned int page_adderss)
{
unsigned int i=0;
unsigned char statu_bit=0;
AT45DB041B_BufferWrite(buffer,buffer_adderss,writ_pHeader,length);
for(i=0;i<1000;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x83);break;
case 2:SPI_HostWriteByte(0x86);break;
}
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)(page_adderss<<1));
SPI_HostWriteByte(0x00);
SPI_CS_D;
}
/*******************************************************
描述: 将指定的数据写入buffer 中的指定地址(0-263)
参数: buffer 缓存选择0X01选取buffer 1, 0X02选取buffer 2,
buffer_adderss 缓存字节地址0-263
*writ_pHeader 待写入数据的指针
length 写入数据的长度,<=263
*******************************************************/
void AT45DB041B_BufferWrite(unsigned char buffer,unsigned int buffer_adderss,unsigned char *writ_pHeader,unsigned int length)
{
unsigned int i=0;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x84);break; //buffer 1 writ
case 2:SPI_HostWriteByte(0x87);break; //buffer 2 writ
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((unsigned char)(buffer_adderss>>8));
SPI_HostWriteByte((unsigned char)buffer_adderss);
for(i=0;i<length;i++)
{
SPI_HostWriteByte(writ_pHeader[i]);
}
SPI_CS_D;
}
void SPI_HostWriteByte(unsigned char send_data)
{
SPDR=0;
SPDR=send_data;
while(!(SPSR&(1<<SPIF)));
}
unsigned char SPI_HostReadByte(void)
{
while(!(SPSR&(1<<SPIF)));
return SPDR;
}
int main(void)
{
uint16_t i,j;
DDRB|=_BV(PB0);
for(i=0;i<128;i++)
xx[i]=i+5;
IoInit();
df_init();
printf_P(PSTR("\n开始测试AT45DB161D!\n"));
/* //测试写
df_write_open(8000);
for(i=0;i<5;i++)
df_write(xx,128);
df_write_close();
*/
//测试读
df_read_open(8000);
for(j=0;j<5;j++)
{
df_read(xx,128);
for(i=0;i<128;i++)
{
if(i%16 == 0)
printf("\n");
printf("%x ",xx[i]);
}
}
df_read_close();
printf("\n");
/* //测试读器件ID
df_read_deviceid(xx);
for(i=0;i<4;i++)
printf("0x%x ",xx[i]);
*/
while(1)
{
DelayMs(300);
PORTB^=_BV(PB0); //测试完后进入LED闪烁死循环
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -