⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f34x_msd_cf_basic_functions.c

📁 C8051F340读写SD卡的程序
💻 C
字号:
//-----------------------------------------------------------------------------
// F34x_MSD_Basic_Functions.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// Module contains basic functions for Compact Flash card.
//
//
//
// How To Test:    See Readme.txt
//
//
// FID:            34X000028
// Target:         C8051F34x
// Tool chain:     Keil
// Command Line:   See Readme.txt
// Project Name:   F34x_USB_MSD
//
// Release 1.1
//    -All changes by PKC
//    -09 JUN 2006
//    -No changes; incremented revision number to match project revision
//
// Release 1.0
//    -Initial Release
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include "F34x_MSD_Physical_Settings.h"
#include "F34x_MSD_CF_Basic_Functions.h"
#include <stdio.h>

sbit Led1 = P2^2;
sbit Led2 = P2^3;
void CF_Port_Init();

//----------------------------------------------------------------------------
// Init_CF
//----------------------------------------------------------------------------
//
// This routine initializes the Compact Flash memory card
//
// Parameters   :
// Return Value :
//----------------------------------------------------------------------------

char Init_CF()
{
  xdata char result = Dtct_Card(); 
  xdata unsigned int loop = 0;
  xdata unsigned reinit = 0;
  if (result == 1) return (CF_NO_CARD); 
REINIT:
  CF_RST = 1;
  while(++loop);
  CF_WAIT_STATE;
  CF_WAIT_STATE;
  CF_WAIT_STATE;
  CF_WAIT_STATE;
  CF_RST = 0;
  while(!CF_RDY) {
    if(++loop == 0) {
      CF_GET_REGISTER_VALUE(0x01);
      goto REINIT;
    }
  }
  while(++loop);
  if((CF_GET_REGISTER_VALUE(0x01) & 0xf0) != 0)
    goto REINIT;
  return 0;
}


//----------------------------------------------------------------------------
// Wait_Drq
//----------------------------------------------------------------------------
//
// This function waits until data reqeust bit in staus register is clear
//
// Parameters   :
// Return Value :
//----------------------------------------------------------------------------

void Wait_Drq()
{
  xdata char wait, wait_drq;
  xdata int loopguard = 0;
  do {
    #ifndef MACRO_CF_VERSIONS
    wait = CF_GET_REGISTER_VALUE(0x07);	// Read status register
    #else
    CF_GET_REGISTER_VALUE(0x07,wait);	// Read status register
    #endif
    if(wait & 0x01) {
      wait_drq = CF_GET_REGISTER_VALUE(0x01);
      return;
    }
    wait_drq = wait & 0x08;		// Wait for DRQ to SET
  } while (wait_drq == (char)0x00);
}


//----------------------------------------------------------------------------
// Wait_Busy
//----------------------------------------------------------------------------
//
// This function waits until busy bit is set
//
// Parameters   :
// Return Value :
//----------------------------------------------------------------------------

void Wait_Busy()
{
  xdata char wait, wait_bsy;
  do {
    #ifndef MACRO_CF_VERSIONS
    wait = CF_GET_REGISTER_VALUE(0x07);	// Read status register
    #else
    CF_GET_REGISTER_VALUE(0x07,wait);	// Read status register
    #endif
    wait_bsy = wait & 0x80;		// Wait for DRQ to SET
  } while (wait_bsy == (char)0x80);
}


//----------------------------------------------------------------------------
// Dtct_Card
//----------------------------------------------------------------------------
//
// Function detcts if compact flash card is in slot
//
// Parameters   :
// Return Value : 0 card is on , 1 off
//----------------------------------------------------------------------------

char Dtct_Card(void)
{
  xdata char card_detect;
  card_detect = CF_CD1; 
  return (card_detect); // 0 card is on , 1 off
}

#ifndef MACRO_CF_VERSIONS

//----------------------------------------------------------------------------
// CF_GET_REGISTER_VALUE
//----------------------------------------------------------------------------
//
// Function returns value from register pointed by addr
//
// Parameters   : addr - address value of CF register
// Return Value : value stroed in register
//----------------------------------------------------------------------------

char CF_GET_REGISTER_VALUE(char addr)
{
  xdata char ret = 0;
  CF_SET_ADDR_LINE(addr);
  CF_READ;
  CF_WAIT_STATE;
  ret = CF_READ_DATA;
  CF_READWRITE_IDLE;
  return ret;
}


//----------------------------------------------------------------------------
// CF_SET_REGISTER_VALUE
//----------------------------------------------------------------------------
//
// Function sets value of register
//
// Parameters   : addr - register address
//				  value - value to set
// Return Value : 
//----------------------------------------------------------------------------

void CF_SET_REGISTER_VALUE(char addr, char value)
{
  CF_SET_ADDR_LINE(addr);
  CF_WR_DATA(value);
  CF_WRITE;
  CF_WAIT_STATE;
  CF_READWRITE_IDLE;
}
#endif

//----------------------------------------------------------------------------
// Write_Sector
//----------------------------------------------------------------------------
//
// Function writes buffer into address
//
// Parameters   : address - LBA address
//                buffer - buffer with data to write
// Return Value : return error status or 0 if everything was OK
//----------------------------------------------------------------------------

char Write_Sector(unsigned long address, char* buffer)
{
  xdata char cylinder_low, cylinder_high,sector,head;
  xdata char result, error;
  xdata int i;
  result = Dtct_Card(); 
  if (result == 1) return (CF_NO_CARD); 
	
  Led2=1;
  sector = address & 0xff;
  cylinder_low = (address >> 8 ) & 0x0FF; 
  cylinder_high = (address >> 16) & 0xff; 
  head = (address >> 24) & 0x0f;

	
  CF_SET_REGISTER_VALUE(2,0x01);
  CF_SET_REGISTER_VALUE(3,sector);
  CF_SET_REGISTER_VALUE(4,cylinder_low);
  CF_SET_REGISTER_VALUE(5,cylinder_high);
  CF_SET_REGISTER_VALUE(6,(0xE0 | head));
  CF_SET_REGISTER_VALUE(7,0x30);

  error = CF_GET_REGISTER_VALUE(1);

  Wait_Drq(); // Wait for DRQ
  Wait_Busy(); 

  for(i=0;i<PHYSICAL_BLOCK_SIZE;i++) {
    CF_SET_REGISTER_VALUE(0,buffer[i]);
  }

  Wait_Busy(); 
  #ifndef MACRO_CF_VERSIONS
  error = CF_GET_REGISTER_VALUE(1);
  #else
  CF_GET_REGISTER_VALUE(1,error);
  #endif
  Led2=0;
  return(error); 
}


//----------------------------------------------------------------------------
// Read_Sector
//----------------------------------------------------------------------------
//
// Function reads buffer from address
//
// Parameters   : address - LBA address
//                buffer - buffer with data to write
// Return Value : return error status or 0 if everything was OK
//----------------------------------------------------------------------------

char Read_Sector(unsigned long address, char* buffer)
{
  xdata char cylinder_low, cylinder_high,sector,head;
  xdata char result, error;
  xdata int i;
  result = Dtct_Card(); 
  if (result == 1) return (CF_NO_CARD); 
  Led1 = 1;
  sector = address & 0xff;
  cylinder_low = (address >> 8 ) & 0x0FF; 
  cylinder_high = (address >> 16) & 0xff; 
  head = (address >> 24) & 0x0f;

  error = CF_GET_REGISTER_VALUE(1);
	
  CF_SET_REGISTER_VALUE(2,0x01);
  CF_SET_REGISTER_VALUE(3,sector);
  CF_SET_REGISTER_VALUE(4,cylinder_low);
  CF_SET_REGISTER_VALUE(5,cylinder_high);
  CF_SET_REGISTER_VALUE(6,(0xE0 | head));
  CF_SET_REGISTER_VALUE(7,0x20);

  error = CF_GET_REGISTER_VALUE(1);

  Wait_Drq(); // Wait for DRQ

  #ifndef MACRO_CF_VERSIONS
  error = CF_GET_REGISTER_VALUE(1);
  #else
  CF_GET_REGISTER_VALUE(1,error);
  #endif

		

  for(i=0;i<PHYSICAL_BLOCK_SIZE;i++) {
#ifndef MACRO_CF_VERSIONS
    buffer[i] = CF_GET_REGISTER_VALUE(0);
#else
    CF_GET_REGISTER_VALUE(0,buffer[i]);
#endif
  }
  Wait_Busy();
  #ifndef MACRO_CF_VERSIONS
  error = CF_GET_REGISTER_VALUE(1);
  #else
  CF_GET_REGISTER_VALUE(1,error);
  #endif
  Led1 = 0;
  return(error); 
}

//----------------------------------------------------------------------------
// Identify_Drive
//----------------------------------------------------------------------------
//
// This function reads identifier from card
//
// Parameters   : buffer - buffer on data from CF
// Return Value : error number if occurs 
//----------------------------------------------------------------------------

char Identify_Drive(char* buffer)
{
  xdata char error,result;
  xdata int i;
	
  result = Dtct_Card();
  if (result == 1) return (CF_NO_CARD); 

  while(((error = CF_GET_REGISTER_VALUE(1)) & 0xF0) != 0);
			

  CF_SET_REGISTER_VALUE(6,0);
  CF_SET_REGISTER_VALUE(7,0xEC);

  error = CF_GET_REGISTER_VALUE(1);

	
  Wait_Drq();
  for (i = 0; i < PHYSICAL_BLOCK_SIZE; i++) {
    #ifndef MACRO_CF_VERSIONS
    *(buffer + i) = CF_GET_REGISTER_VALUE(0);
    #else
    CF_GET_REGISTER_VALUE(0,*(buffer + i));
    #endif
  }
  #ifndef MACRO_CF_VERSIONS
  error = CF_GET_REGISTER_VALUE(1);
  #else
  CF_GET_REGISTER_VALUE(1,error);
  #endif
  return error; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -