#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);
}
|