?? sd.c
字號:
/*-----------------------------------------------------------
SPI串行flash-at45db161d讀寫函數
作者:zbw 日期:2007.10.25 版本:v1.0
包含文件:SD.C SD.H
功能:運用AVR硬件SPI完成對芯片的不同方式的讀寫,各個函數的
功能和參數參見函數體或頭文件中的注釋
注意:本程序便于操作設置了一個528字節大小的緩存,由于芯片內
部按頁操作,每頁528字節(可編程控制,但只能一次性更改
故不做更改),因此此緩存大小不能隨意改動!
-----------------------------------------------------------*/
#include <mega8.h>
#include "sd.h"
void SD_Port_Init(void)
{
SD_CS_PIN=1;
}
//-----------------------------------------------------------
//SPI Master初始化子程序
//-----------------------------------------------------------
void SPI_MasterInit(void)
{
SD_Direction_REG = (1<<SPI_DO)|(1<<SPI_SS)|(1<<SPI_Clock); /* 設置MOSI 和SCK 為輸出,其他為輸入 */
SPCR = 0x50; /* 使能SPI 主機模式 */
SPSR = 0x01; /* 倍速 */
}
//-----------------------------------------------------------
//SPI Master發送子程序
//-----------------------------------------------------------
void SPI_MasterTransmit(unsigned char cData)
{
SPDR = cData; /* 啟動數據傳輸 */
while(!(SPSR & (1<<SPIF))); /* 等待傳輸結束 */
}
//-----------------------------------------------------------
//SPI Master接收子程序
//-----------------------------------------------------------
unsigned char SPI_MasterReceive(void)
{
SPDR = 0xFF;
while(!(SPSR & (1<<SPIF))); /* 等待接收結束 */
return SPDR; /* 返回數據 */
}
void SDinit(void)
{
SD_Direction_REG=0xff;
DDRD=0xff;
SD_Port_Init();
SPI_MasterInit();
}
/*-----------------------------------------------------------
讀狀態寄存器 操作碼0xD7
結束標志:CS管腳置高 該寄存器在忙狀態下也可讀取,便于判斷狀態
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
RDY/BUSY COMP 1 0 1 1 PROTECT PAGE SIZE
-----------------------------------------------------------*/
unsigned char Status_Register_Read (void)
{
unsigned char c;
SD_CS_PIN=0;
SPI_MasterTransmit(0xd7);//操作碼
c= SPI_MasterReceive();
SD_CS_PIN=1;
return c;
}
/*-----------------------------------------------------------
連續讀模式1 最高66M 操作碼0xE8
格式:操作碼+3字節地址碼(12頁址+10頁內地址(528byte))+4個空字節(延時啟動內部讀操作)
結束標志:CS管腳置高 注意該模式讀期間頁間轉換無標志 無時差 完全連續直到讀完這個存儲器
由于不能建立太大的緩存,故該模式下,連續讀的優勢得到限制,可在主函數進行操作實現單字節傳輸
-----------------------------------------------------------*/
void Continuous_Array_Read_1 (unsigned char *p,unsigned int pageaddr,unsigned int byteaddr) // 獲取值放到緩存p,此處設置p為512字節
{
unsigned int i;
unsigned long j;
j= ((((unsigned long)pageaddr)<<10)&0x3ffc00)|(((unsigned long)byteaddr)&0x3ff);
SD_CS_PIN=0;
SPI_MasterTransmit(0xe8);//操作碼
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SPI_MasterTransmit(0x00);//無效字節
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
for (i=0;i<528;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//檢測忙狀態確保內部時序完成
}
/*-----------------------------------------------------------
連續讀模式2 最高66M 操作碼0x0B
格式:操作碼+3字節地址碼(12頁址+10頁內地址(528byte))+1個空字節(延時啟動內部讀操作)
結束標志:CS管腳置高 注意該模式讀期間頁間轉換無標志 無時差 完全連續
由于不能建立太大的緩存,故該模式下,連續讀的優勢得到限制,可在主函數進行操作實現單字節傳輸
-----------------------------------------------------------*/
void Continuous_Array_Read_2 (unsigned char *p,unsigned int pageaddr,unsigned int byteaddr) // 獲取值放到緩存p,此處設置p為512字節
{
unsigned int i;
unsigned long j;
j= ((((unsigned long)pageaddr)<<10)&0x3ffc00)|(((unsigned long)byteaddr)&0x3ff);
SD_CS_PIN=0;
SPI_MasterTransmit(0x0b);//操作碼
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SPI_MasterTransmit(0x00);//無效字節
for (i=0;i<528;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//檢測忙狀態確保內部時序完成
}
/*-----------------------------------------------------------
連續讀模式3 最高33M 操作碼0x03
格式:操作碼+3字節地址碼(12頁址+10頁內地址(528byte))
結束標志:CS管腳置高 注意該模式讀期間頁間轉換無標志 無時差 完全連續
由于不能建立太大的緩存,故該模式下,連續讀的優勢得到限制,可在主函數進行操作實現單字節傳輸
-----------------------------------------------------------*/
void Continuous_Array_Read_3 (unsigned char *p,unsigned int pageaddr,unsigned int byteaddr) // 獲取值放到緩存p,此處設置p為512字節
{
unsigned int i;
unsigned long j;
j= ((((unsigned long)pageaddr)<<10)&0x3ffc00)|(((unsigned long)byteaddr)&0x3ff);
SD_CS_PIN=0;
SPI_MasterTransmit(0x03);//操作碼
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
for (i=0;i<528;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//檢測忙狀態確保內部時序完成
}
/*-----------------------------------------------------------
數據讀函數 操作碼0xD2
格式:操作碼+3字節地址碼(12頁址+10頁內地址(528byte))+4個空字節(延時啟動內部讀操作)
結束標志:CS管腳置高 注意該方式讀完一頁返回從同一頁開始讀
緩存大小設置為512字節即工作于每頁528字節模式
-----------------------------------------------------------*/
void Main_Memory_Page_Read (unsigned char *p,unsigned int pageaddr,unsigned int byteaddr) // 獲取值放到緩存p,此處設置p為512字節
{
unsigned int i;
unsigned long j;
j= ((((unsigned long)pageaddr)<<10)&0x3ffc00)|(((unsigned long)byteaddr)&0x3ff);
SD_CS_PIN=0;
SPI_MasterTransmit(0xd2);//操作碼
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SPI_MasterTransmit(0x00);//無效字節
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
for (i=0;i<528;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//檢測忙狀態確保內部時序完成
}
/*-----------------------------------------------------------
緩存數據讀函數 操作碼0xD6 0xD4 0xD3 0xD1
格式:操作碼+3字節地址碼(15無效位+10地址(528byte))
結束標志:CS管腳置高
-----------------------------------------------------------*/
void Buffer_Read (unsigned char *p,unsigned int byteaddr,unsigned char rate,unsigned char buffer) // 獲取值放到緩存p,此處設置p為512字節
{ // 獲取值放到緩存p,此處設置p為528字節 byteaddr 為地址,rate為讀速度設定1為高速66M,0為低速33M
//buffer為buffer選擇,1為buffer1,同理
unsigned int i;
unsigned long j;
j=((unsigned long)byteaddr)&0x03ff;
SD_CS_PIN=0;
if (rate)
{
if (buffer == 1)
SPI_MasterTransmit(0xd4);//操作碼
else
SPI_MasterTransmit(0xd6);//操作碼
}
else
{
if (buffer == 1)
SPI_MasterTransmit(0xd1);//操作碼
else
SPI_MasterTransmit(0xd3);//操作碼
}
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
if (rate)
SPI_MasterTransmit(0x00);//無效字節 僅高速模式下有效
for (i=0;i<528;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//檢測忙狀態確保內部時序完成
}
/*-----------------------------------------------------------
緩存數據寫函數 操作碼0x84 0x87
格式:操作碼+3字節地址碼(15無效位+10地址(528byte))
結束標志:CS管腳置高
-----------------------------------------------------------*/
void Buffer_write (unsigned char *p,unsigned int byteaddr,unsigned char buffer)
{ // 將緩存p寫入buffer,此處設置p為528字節 byteaddr 為地址,buffer為buffer選擇,1為buffer1,同理
unsigned int i;
unsigned long j;
j= ((unsigned long)byteaddr)&0x03ff;
SD_CS_PIN=0;
if (buffer == 1)
SPI_MasterTransmit(0x84);//操作碼
else
SPI_MasterTransmit(0x87);//操作碼
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
for (i=0;i<528;i++)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -