#include "stm32f10x_lib.h"
#include "prtfont.h"
#define uint32 u32
#define uint u16
#define uchar u8
#define CS161_High GPIO_SetBits(GPIOC,GPIO_Pin_5)
#define CS161_Low GPIO_ResetBits(GPIOC,GPIO_Pin_5);NOP();
#define MOSI_Dat1 GPIO_SetBits(GPIOA,GPIO_Pin_8);NOP();
#define MOSI_Dat0 GPIO_ResetBits(GPIOA,GPIO_Pin_8);NOP();
#define MISO_Read() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)
#define MCLK_CLK1 GPIO_SetBits(GPIOD,GPIO_Pin_8);NOP();
#define MCLK_CLK0 GPIO_ResetBits(GPIOD,GPIO_Pin_8);NOP();
//AT45DB161操作码指令
#define DB161_MEMORY_READ 0XD2 //从页读出
#define DB161_BUF1_READ 0XD4 //从缓存1读出
#define DB161_BUF2_READ 0XD6 //从缓存2读出
#define DB161_MEMORY_BUF1_TRANSFER 0X53 //从页读到缓存1
#define DB161_MEMORY_BUF2_TRANSFER 0X55 //从页读到缓存2
#define DB161_MEMORY_PROGRAM_THROUGH_BUF1 0X82 //通过缓存1写入页
#define DB161_MEMORY_PROGRAM_THROUGH_BUF2 0X85 //通过缓存2写入页
#define DB161_BUF1_WRITE 0X84 //写入缓存1
#define DB161_BUF2_WRITE 0X87 //写入缓存2
#define DB161_BUF1_MEMORY_PROGRAM_WITH_ERASE 0X83 //缓存1内容写入页(边擦边写)
#define DB161_BUF2_MEMORY_PROGRAM_WITH_ERASE 0X86 //缓存2内容写入页(边擦边写)
#define DB161_BUF1_MEMORY_PROGRAM_without_ERASE 0X88 //缓存1内容写入页(先擦除)
#define DB161_BUF2_MEMORY_PROGRAM_without_ERASE 0X89 //缓存2内容写入页(先擦除)
#define DB161_PAGE_ERASE 0X81 //页擦除
#define DB161_BLOCK_ERASE 0X50 //块擦除
#define DB161_SECTOR_ERASE 0X7C //扇区擦除
#define DB161_MEMORY_BUF1_COMPARE 0X60 //页内容与缓存1比较
#define DB161_MEMORY_BUF2_COMPARE 0X61 //页内容与缓存2比较
#define DB161_STATUS_REGISTER_READ 0XD7 //读状态字
#define DB161_ID_READ 0X9F //读ID
#define PAGE_BASE_NUMBER 528 //AT45DB161 页尺寸
#define HanZiCode_Base 0x0 //字模起始地址
extern u8 Font[1200];
//---------------------------------------------------------------------------
void NOP(void)
{
u8 i;
for(i=0;i<5;i++);
}
/****************************************************************************
** 函数名称:MSPI_SendByte()
** 函数功能:向SPI总线发送数据
** 入口参数:dat 待发送的数据
** 出口参数:返回值为读取的数据
****************************************************************************/
u8 MSPI_SendByte(u8 dt)
{
u8 i;
u8 temp=0;
for(i=8;i>0;i--)
{
if(dt&0x80)
{ MOSI_Dat1; }
else
{ MOSI_Dat0; }
dt<<=1;
MCLK_CLK1;
NOP();
temp<<=1;
if(MISO_Read())
temp++;
NOP();
MCLK_CLK0;
}
return temp;
}
/***************************************************************************
** 函数名称: AT45DB161_Ready()
** 函数功能:读AT45DB161的状态字
** 入口参数:无
** 出口参数:1:准备好;0:忙
****************************************************************************/
u8 AT45DB161_Ready(void)
{
uchar i;
CS161_Low;
MSPI_SendByte(DB161_STATUS_REGISTER_READ);
i=MSPI_SendByte(0); // 读到0x80说明器件准备好
CS161_High;
if((i&0x80)==0x80)
{ return(1); }
else
{ return(0); }
}
//---------------------------------------------------------------------------
void ReadFlashOnePage(u16 page,u16 insideaddr,u8 *buffer,u16 count)
{
uint i;
uchar command;
command = (uchar)(page>>6);
while(AT45DB161_Ready()==0);
CS161_Low;
MSPI_SendByte(DB161_MEMORY_READ); // 写入读页存储区命令
MSPI_SendByte(command);
command = (uchar)((page<<2) + (insideaddr>>8)); // 写入页号与页内地址
MSPI_SendByte(command);
MSPI_SendByte((uchar)insideaddr);
MSPI_SendByte(0x00);
MSPI_SendByte(0x00);
MSPI_SendByte(0x00); // 写入4字节无关字节
MSPI_SendByte(0x00);
for(i=0;i<count;i++)
{
*buffer=MSPI_SendByte(0); // 读出需要的字节数
buffer++;
}
CS161_High;
}
//---------------------------------------------------------------------------
u8 ReadFlashData(u32 address,u8 *buffer,u16 count)
{
uint32 i,firstcnt,lastcnt;
uint32 page,pageaddr,insideaddr;
pageaddr = address/PAGE_BASE_NUMBER; // 将入口整地址分成页地址,求出页地址地址整数
insideaddr = address%PAGE_BASE_NUMBER; // 求出第一页页内地址,即页内余数
firstcnt = PAGE_BASE_NUMBER - insideaddr; // 求出第一页内包含的字节数
if(firstcnt>count)firstcnt = count; // 判断第一页字节数是否超过要读取的字节数
lastcnt = (count-firstcnt)%PAGE_BASE_NUMBER; // 求出最后一页要读取的字节数
page = (count-firstcnt)/PAGE_BASE_NUMBER; // 除第一页和最后页外要读取的整数页个数
ReadFlashOnePage(pageaddr,insideaddr,buffer,firstcnt); // 读第一页
pageaddr++;
buffer += firstcnt;
for(i=0;i<page;i++) // 读整数页
{
ReadFlashOnePage(pageaddr,0,buffer,PAGE_BASE_NUMBER);
pageaddr++;
buffer += PAGE_BASE_NUMBER;
}
if(lastcnt>0)ReadFlashOnePage(pageaddr,0,buffer,lastcnt);// 读最后一页
return(TRUE);
}
|