📄 virtualspi.c
字号:
/*************************************** Copyright (c) *************************************************
*
* UESTC
* 电子科技大学自动化工程学院
*
* 文 件 名: VirtualSPI.C
* 文件描述:模拟SPI功能,实现对flash的读写功能。
*
* 说 明:
*
********************************************************************************************************/
#include "config.h"
#include "RS232.h"
#include "RS485.h"
#include "RTC.h"
#include "SPI.h"
#include "VirtualSPI.h"
#include "PinSet.h"
extern union FLASH_ADDR addr;
/********************************************************************************************************
*
* 函数名称:VirtualSpiInit()
*
* 功能描述:初始化虚拟SPI接口,设置为主机。
*
* 入口参数:无
* 出口参数:无
*
********************************************************************************************************/
void VirtualSpiInit(void)
{
PinFuncSelct(PIN_FLASH_CS, PIN_FUNCTION1);
GPIODirSet(PIN_FLASH_CS, TRUE);
IOSET = (PIN_MASK(PIN_FLASH_CS));
//设置SPI的SCK、MOSI(P0.4、P0.6)为GPIO输出
PinFuncSelct(PIN_SCK0, PIN_FUNCTION2);
PinFuncSelct(PIN_MOSI0, PIN_FUNCTION2);
PinFuncSelct(PIN_MISO0, PIN_FUNCTION2);
S0SPCCR = 0X08;
S0SPCR = 0X38;
}
/********************************************************************************************************
*
* 函数名称:Read_BYTE_VSPI()
*
* 功能描述:接收FLASH发回的一个字节数据。
*
* 入口参数:Data--要发送的数据
* 出口参数:无
*
********************************************************************************************************/
unit8 Read_BYTE_VSPI(void)
{
unit8 data = 0;
S0SPDR = 0X00;
while(0 == (S0SPSR&0X80));
data = S0SPDR;
return(data);
}
/********************************************************************************************************
*
* 函数名称:Send_BYTE_VSPI()
*
* 功能描述:发送命令与地址。
*
* 入口参数:Data--要发送的数据
* 出口参数:无
*
********************************************************************************************************/
void Send_BYTE_VSPI(unit8 Data)
{
S0SPDR = Data;
while(0 == (S0SPSR&0X80));
Data = S0SPDR;
return;
}
unit8 AT45_read_status_VSPI(void)
{
unit8 data;
unit8 Send_BUF[3];
//int i;
unit8 buf[]= "AT45 status:";
unit8 buf1[]="\n";
addr.bytes[3] = AT45_READ_STATUS_CMD;
IOCLR = (PIN_MASK(PIN_FLASH_CS));
Delay(FLASH_DELAY_TIME); //延时
Send_BYTE_VSPI(addr.bytes[3]);
data = Read_BYTE_VSPI();
if((data/16)>9)
{
Send_BUF[0] = data/16+'7';
}
else
{
Send_BUF[0] = (data/16)+'0';
}
if((data%16)>9)
{
Send_BUF[1] = data%16+'7';
}
else
{
Send_BUF[1] = data%16+'0';
}
Send_BUF[2] = '\n';
ISendBuf(buf,12);
ISendBuf(Send_BUF,3);
ISendBuf(buf1,1);
IOSET = (PIN_MASK(PIN_FLASH_CS));
return(data);
}
unit8 AT45_Wait_Ready_VSPI(void)
{
unit8 state;
do{
state = AT45_read_status_VSPI();
}while((state & 0x80) != 0x80);
return TRUE;
}
/********************************************************************************************************
*
* 函数名称:AT45_write_to_buffer_VSPI()
*
* 功能描述:将*data_buff中数据的前data_len个字节写入到指定buffer1或者buffer2之中
*
* 入口参数:*data_buff 存放数据的数组
* data_len 数据长度
* buffer_number buffer号码
* begin_addr 起始地址
* 出口参数:无
*
********************************************************************************************************/
unit8 AT45_write_to_buffer_VSPI(unit32 data_len,unit8 buffer_number,unit32 begin_addr,char *data_buff)
{
int data;
unit32 i;
if(AT45_Wait_Ready_VSPI() == FALSE)//等待flash空闲
return FALSE;
addr.value = begin_addr;
if(buffer_number == 0)
addr.bytes[3] = AT45_WRITE_BUFFER1_CMD;
else
addr.bytes[3] = AT45_WRITE_BUFFER2_CMD;
IOCLR = (PIN_MASK(PIN_FLASH_CS));
Send_BYTE_VSPI(addr.bytes[3]);
Send_BYTE_VSPI(addr.bytes[2]);
Send_BYTE_VSPI(addr.bytes[1]);
Send_BYTE_VSPI(addr.bytes[0]);
for(i=0; i<data_len; i++) // 写入data_len个数据
{
data = data_buff[i];
Send_BYTE_VSPI(data);
}
IOSET = (PIN_MASK(PIN_FLASH_CS));
return TRUE;
}
/********************************************************************************************************
*
* 函数名称:AT45_write_buffer_to_page_VSPI()
*
* 功能描述:将指定buffer中的数据写入到指定主存page中,然后自动删除
* buffer_number =0:保存buffer1到主存, =1:保存buffer2到主存
*
* 入口参数:page 指定页面
* buffer_number 指定缓存器
* 出口参数:无
*
********************************************************************************************************/
unit8 AT45_write_buffer_to_page_VSPI(unit32 page, unit8 buffer_number)
{
if(AT45_Wait_Ready_VSPI() == FALSE)//等待flash空闲
return FALSE;
addr.value = page;
addr.value *= 512;
if(buffer_number == 0)
addr.bytes[3] = AT45_WRITE_BUFFER1_TO_Page_CMD;
else
addr.bytes[3] = AT45_WRITE_BUFFER2_TO_Page_CMD;
IOCLR = (PIN_MASK(PIN_FLASH_CS));
Send_BYTE_VSPI(addr.bytes[3]);
Send_BYTE_VSPI(addr.bytes[2]);
Send_BYTE_VSPI(addr.bytes[1]);
Send_BYTE_VSPI(addr.bytes[0]);
IOSET = (PIN_MASK(PIN_FLASH_CS));
return TRUE;
}
/********************************************************************************************************
*
* 函数名称:AT45_read_MainMemory_VSPI()
*
* 功能描述:将page页面以begin_addr为起始页内地址的data_len个字节读入*data_buff中,这个操作,当读到一页的最后一个字节时,将继续读下一页的第一个字节,不经过缓冲区
*
* 入口参数:page 指定页面
* begin_addr 开始地址
* data_len 数据长度
* *data_buff 存放数据的数组
* 出口参数:无
*
********************************************************************************************************/
unit8 AT45_read_MainMemory_VSPI(unit32 page,unit32 begin_addr,unit32 data_len,char *data_buff)
{
unit32 i = 0;
if(AT45_Wait_Ready_VSPI() == FALSE)//等待flash空闲
return FALSE;
addr.value = 0;
addr.value = page;
addr.value = addr.value * 512; // 页地址左移9位,空出页内9位地址等待镶嵌
addr.value |= begin_addr; // 镶嵌页内起始地址
addr.bytes[3] = AT45_READ_MainMemory_CMD; // 高位地址写入命令字
IOCLR = (PIN_MASK(PIN_FLASH_CS));
Send_BYTE_VSPI(addr.bytes[3]);
Send_BYTE_VSPI(addr.bytes[2]);
Send_BYTE_VSPI(addr.bytes[1]);
Send_BYTE_VSPI(addr.bytes[0]);
Send_BYTE_VSPI(0);
Send_BYTE_VSPI(0);
Send_BYTE_VSPI(0);
Send_BYTE_VSPI(0);
for(i = 0 ;i < data_len; i++)
{
data_buff[i] = Read_BYTE_VSPI();
}
// 设置AT45的CS无效
IOSET = (PIN_MASK(PIN_FLASH_CS));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -