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

📄 test.c

📁 msp430f149读写CF卡操作
💻 C
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************
//    The Code is for TrueIDE MODE of CF Card
//    CF-ATA-4 Command Set 
//    CF+ and CompactFlash Specification Revision 3.0
//    Programed by HeHu (Taiyuan Univ. of Tech.)
//    Email : hoo_hee@msn.com
//    Data : 2005-8-31
//    Compile Enviroment : IAR Embeded Workbench IDE 3.10A
//    Firmware : MSP430F1491 
//               Kingston CompactFlash Digital Memory Card(128MB)
//    Embedded OS : uC/OS-II(Jean J.Labrosse Reserved)
//*****************************************************************
#include <msp430x14x1.h>

//*******************************************************************************
//    Hardware Connection Description
//    D7~D0   to    MSP430F149 P5.7~P5.0
//    A02~A00 to    MSP430F149 P4.2~P4.0
//    /CS1    to    MSP430F149 P4.4
//    /CS0    to    MSP430F149 P4.3
//    /IORD   to    MSP430F149 P4.5
//    /IORW   to    MSP430F149 P4.6
//    /RESET  to    MSP430F149 P4.7
//    CSEL    to    GND
//    /ATASEL to    GND
//    /VS1    to    MSP430F149 P2.0
//    IORDY   to    MSP430F149 P2.1
//    INTRQ   to    MSP430F149 P2.4
//    /DASP is connected to a LED in series with a 510 resistor to VCC.
//    When the CF Card is inactive, LED is OFF; when CF Card is active, LED is ON.
#define CF_DATA_DIR P5DIR
#define CF_DATA_OUT P5OUT
#define CF_DATA_IN  P5IN
#define CF_ADDR_DIR P4DIR
#define CF_ADDR_OUT P4OUT
#define CF_CONTROL_DIR  P2DIR
#define CF_CONTROL_OUT  P2OUT
#define RST   BIT7    //P4
#define CS1   BIT4    //P4
#define CS0   BIT3    //P4
#define A2    BIT2    //P4
#define A1    BIT1    //P4
#define A0    BIT0    //P4
#define WR  BIT6    //P4
#define RD  BIT5    //P4
#define VS1   BIT0    //P2
#define IORDY BIT1    //P2
#define DASP  BIT2    //P2
#define INTRQ BIT4    //P2
//*******************************************************************************

typedef unsigned char  uint8;                   /* 无符号8位整型变量                        */
typedef signed   char  int8;                    /* 有符号8位整型变量                        */
typedef unsigned int   uint16;                  /* 无符号16位整型变量                       */
typedef signed   int   int16;                   /* 有符号16位整型变量                       */
typedef unsigned long  uint32;                  /* 无符号32位整型变量                       */
typedef signed   long  int32;                   /* 有符号32位整型变量                       */
#define    	ATA_REG_DATA          	CS1								/*数据寄存器*/ 
#define    	ATA_REG_ERR           	(CS1 + A0)					/*读错误寄存器*/ 
#define    	ATA_REG_FEATURE       	(CS1 + A0)					/*写功能寄存器*/ 
#define    	ATA_REG_SECCNT        	(CS1 + A1)					/*扇区计数器*/ 
#define    	ATA_REG_SECTOR        	(CS1 + A1 + A0)			/*扇区号*/ 
#define    	ATA_REG_CYLINDER_LOW  	(CS1 + A2)					/*柱面低8位*/ 
#define    	ATA_REG_CYLINDER_HIGH 	(CS1 + A2 + A0)			/*柱面高8位*/ 
#define    	ATA_REG_DEVICE_HEAD   	(CS1 + A2 + A1)			/*选择主从,模式,磁头*/ 
#define    	ATA_REG_COMMAND       	(CS1 + A2 + A1 + A0)/*写命令寄存器*/ 
#define    	ATA_REG_STATUS        	(CS1 + A2 + A1 + A0)/*读状态寄存器*/ 
#define    	ATA_REG_CONTROL       	(CS0 + A2 + A1)			/*写控制寄存器*/ 
#define    	ATA_REG_ASTATUS       	(CS0 + A2 + A1) 		/*读辅助状态寄存器*/
#define TRUE  1
#define FALSE 0
#define OS_EXIT_CRITICAL()	_EINT()
#define OS_ENTER_CRITICAL();	_DINT()
/*驱动与硬件对ATA设备寄存器操作接口*/
#define		GetData()		SYS_PortIn(ATA_REG_DATA)	/*读数据寄存器,与驱动接口*/
#define		SetData(x)		SYS_PortOut(ATA_REG_DATA,x)	/*写数据寄存器,与驱动接口*/

#define		GetERR()		SYS_PortIn(ATA_REG_ERR)		/*读错误寄存器,与驱动接口*/
#define		SetFeature(x)		SYS_PortOut(ATA_REG_FEATURE,x)			/*写特征寄存器,与驱动接口*/

#define		GetSECCNT()		SYS_PortIn(ATA_REG_SECCNT)	/*读扇区计数寄存器,与驱动接口*/
#define		SetSECCNT(x)		SYS_PortOut(ATA_REG_SECCNT,x)			/*写扇区计数寄存器,与驱动接口*/

#define		GetSector()		SYS_PortIn(ATA_REG_SECTOR)	/*读扇区寄存器,与驱动接口*/
#define		SetSector(x)		SYS_PortOut(ATA_REG_SECTOR,x)			/*写扇区寄存器,与驱动接口*/

#define		GetCylinderLow()	SYS_PortIn(ATA_REG_CYLINDER_LOW)		/*读柱面低8位寄存器,与驱动接口*/
#define		SetCylinderLow(x)	SYS_PortOut(ATA_REG_CYLINDER_LOW,x)		/*写柱面低8位寄存器,与驱动接口*/

#define		GetCylinderHigh()	SYS_PortIn(ATA_REG_CYLINDER_HIGH)		/*读柱面高8位寄存器,与驱动接口*/
#define		SetCylinderHigh(x)	SYS_PortOut(ATA_REG_CYLINDER_HIGH,x)	/*写柱面高8位寄存器,与驱动接口*/

#define		GetDeviceHead()		SYS_PortIn(ATA_REG_DEVICE_HEAD)			/*读设备磁头寄存器,与驱动接口*/
#define		SetDeviceHead(x)	SYS_PortOut(ATA_REG_DEVICE_HEAD,x)		/*写设备磁头寄存器,与驱动接口*/

#define		GetStatus()		SYS_PortIn(ATA_REG_STATUS)	/*读状态寄存器,与驱动接口*/
#define		SetCommand(x)		SYS_PortOut(ATA_REG_COMMAND,x)			/*写命令寄存器,与驱动接口*/

#define		GetAStatus()		SYS_PortIn(ATA_REG_ASTATUS)				/*读辅助状态寄存器,与驱动接口*/
#define		SetControl(x)		SYS_PortOut(ATA_REG_CONTROL,x)			/*写控制寄存器,与驱动接口*/

/****************************************************************************************/
/**	以下为本驱动定义部份,用户不需改动													*/
/****************************************************************************************/
/*ATA 指令代码*/ 
#define 	IDE_CMD_ATAPI_RESET      		0x08
#define 	IDE_CMD_RECALIBRATE      		0x10
#define 	IDE_CMD_READ             		0x20	// 读扇区命令
#define 	IDE_CMD_WRITE            		0x30	// 写扇区命令
#define 	IDE_CMD_VERIFY           		0x40
#define 	IDE_CMD_SEEK             		0x70
#define		IDE_CMD_EXEC_DIAGNOSE    		0x90
#define		IDE_CMD_SET_DRIVE_PARAMETERS 	0x91
#define 	IDE_CMD_READ_MULTIPLE    		0xC4	// 多扇区读
#define 	IDE_CMD_WRITE_MULTIPLE   		0xC5	// 多扇区写
#define 	IDE_CMD_SET_MULTIPLE    		0xC6
#define 	IDE_CMD_READ_DMA         		0xC8
#define 	IDE_CMD_WRITE_DMA             	0xCA
#define 	IDE_CMD_GET_MEDIA_STATUS      	0xDA
#define    	IDE_CMD_STANDBY_IMMEDIATE		0xE0	// Standby Immediate
#define    	IDE_CMD_IDLE_IMMEDIATE 			0xE1	// Idle Immediate
#define 	IDE_CMD_SETFEATURES				0xEF
#define 	IDE_CMD_IDENTIFY              	0xEC
#define 	IDE_CMD_MEDIA_EJECT           	0xED


/*状态寄存器相关位*/
#define		ATA_STAT_REG_ERR 				0x01	/*设备发生了错误*/
#define		ATA_STAT_REG_IDX  				0x02  	/**/
#define		ATA_STAT_REG_CORR  				0x04  	/**/
#define		ATA_STAT_REG_DRQ  				0x08 	/*有数据传输请求*/
#define		ATA_STAT_REG_DSC  				0x10 	/**/
#define		ATA_STAT_REG_DF   				0x20 	/**/
#define		ATA_STAT_REG_DRDY  				0x40 	/*设备准备好*/
#define		ATA_STAT_REG_BSY  				0x80 	/*设备忙*/
#define		ATA_STAT_BSY_DRDY		(ATA_STAT_REG_BSY+ATA_STAT_REG_DRDY)
#define		ATA_STAT_BSY_DRQ		(ATA_STAT_REG_BSY+ATA_STAT_REG_DRQ)

/*设备磁头寄存器*/
#define		ATA_DevReg_DEV0  				0x00	/*设备为主盘*/
#define		ATA_DevReg_DEV1  				0x10	/*设备为从盘*/
#define		ATA_DevReg_b5   				0x20	/*保留位,为1*/
#define		ATA_DevReg_LBA  				0x40	/*模式选择位*/
#define		ATA_DevReg_b7   				0x80	/*保留位,为1*/

/*控制寄存器*/
#define 	CF_SOFT_RESET					0x04	/*软件复位有效*/
#define 	CF_DISABLE_INT					0x00	/*禁能中断*/
#define 	CF_ENABLE_INT					0x02	/*使能中断*/


/*错误代码由16位二进制数组成,低8位与ATA错误寄存器一致,高8位自定义*/
#define ATA_EER_REG_AMNF					0x01	/*一般错误*/
#define ATA_EER_REG_ABRT 					0x04	/*指令无效出错*/
#define ATA_EER_REG_IDNF 					0x10	/*寻扇区地址出错*/
#define ATA_EER_REG_UNC 					0x40	/*发生了不可纠正的错误*/
#define ATA_EER_REG_BBK						0x80	/*发现错误块*/
/*自定义*/
#define CARD_IS_FALSE						0x00ff	/*CF卡不存在或无效*/
#define CARD_IS_TRUE						0x0000	/*CF卡有效*/
#define CARD_TIMEOUT						0x0100	/*对CF卡操作超时出错*/


#define THIS_DEVICE			((ATA_DevReg&0x10)>>4)	/*当前操作的设备,ATA_SelectDevice函数选择了主或从设备,通过该操作可以确定刚才选定的设备*/

/*设备识别信息*/
/*全部设备信息*/
typedef struct _IDENTIFY_DATA {
	uint16 GeneralConfiguration;            // 00  	 普通设置-CF卡标志0x848A
	uint16 NumberOfCylinders;               // 1   	 默认柱面数
	uint16 Reserved1;                       // 2
	uint16 NumberOfHeads;                   // 3   	 默认磁头数
	uint16 UnformattedBytesPerTrack;      	// 4   	 在2.0规范已不使用
	uint16 UnformattedBytesPerSector;     	// 5   	 在2.0规范已不使用
	uint16 SectorsPerTrack;                 // 6   	 每磁道默认扇区数
	uint32 SectorsPerCard;                  // 7-8 	 每卡扇区数(Word 7=MSW,Word 8=LSW)
	uint16 VendorUnique;					// 9 	 在2.0规范已不使用
	uint16 SerialNumber[10];                // 10-19 ASCII序列号(靠右填写)
	uint16 BufferType;                      // 20 	 在2.0规范已不使用
	uint16 BufferSectorSize;                // 21    在2.0规范已不使用
	uint16 NumberOfEccBytes;                // 22    读/写长指令时的ECC字节数
	uint16 FirmwareRevision[4];             // 23-26 ASCII固件版本。大端格式
    uint16 ModelNumber[20];                 // 27-46 ASCII模式号(靠左填写),大端格式
    uint16 MaximumBlockTransfer;            //*47    多重 读/写指令最大扇区号。
    uint16 Reserved2;                    	// 48    
    uint16 Capabilities;                    // 49    
    uint16 Reserved3;                       // 50    
       
    uint16 PioCycleTimingMode;             	//*51    PIO数据传输周期时序模式

    uint16 DmaCycleTimingMode;             	// 52    在2.0规范已不使用
    uint16 TranslationFieldsValid;          // 53    0位为1,Word54 to 58 有效;1位为1,Word64 to 70 有效

    uint16 NumberOfCurrentCylinders;      	// 54    当前柱面数
    uint16 NumberOfCurrentHeads;            // 55    当前磁头数
    uint16 CurrentSectorsPerTrack;          // 56    当前每磁道扇区数
    uint32 CurrentSectorCapacity;           // 57-58 当前扇区容量(LBAs)(Word 58=MSW,Word 57=LSW)

    uint16 CurrentMultiSectorSetting;       //*59    位8为1,则位0-7,指出可多扇区读写的扇区数
    uint32 UserAddressableSectors;          // 60-61 LAB模式下可被寻址的扇区数
    uint16 Reserved4[2] ;           		// 62-63 
    uint16 AdvancedPIOModes ;               // 64    在2.0规范使用
    uint16 Reserved6[2] ;         			// 65-66
	uint16 MinimumPIOCycleTime;             // 67    非流控制下最小PIO传输周期时间
	uint16 MinimumPIOCycleTimeIORDY; 		// 68    IORDY流控制小最小PIO传输周期时间
    uint16 Reserved7[10];                   // 69-79
    uint32 AtaVersion;           			// 80-81 CF卡返回0
    uint16 FeaturesCommandSupported[3];		// 82-84 特征/命令集技持
    uint16 FeaturesCommandEnabled[3];    	// 85-87 特征/命令集使能
    uint16 Reserved8;       				// 88    
    uint16 MajorRevision;                   // 89    安全单位完全擦除的时间要求
    uint16 MinorRevision;                   // 90    增强型安全单位完全擦除的时间要求
    uint16 PowerManagementValue;			// 91	 当前高级电源管理值									//     91
    uint16 Reserved9[36];                   // 92-127
    uint16 SecurityStatus;					// 128   安全状态
   	uint16 VendorUniqueBytes[32];			// 129-159
    uint16 PowerRequirementDescription; 	// 160   电源要求描述
    uint16 Reserved10;						// 161
    uint16 KeyManagementSupported;        	// 162   按键管理表
    uint16 Reserved11[83];                  // 163-255

} CF_IDENTIFY_DATA, *PCF_IDENTIFY_DATA;

/*设备基本信息*/
typedef struct _ATA_IDENTIFY_DATA {
   	uint16 NumberOfCylinders;               // 1   	 默认柱面数
    uint16 NumberOfHeads;                   // 3   	 默认磁头数
  	uint16 SectorsPerTrack;                 // 6   	 每磁道默认扇区数
    uint32 CurrentSectorCapacity;           // 57-58 当前扇区容量(LBAs)(Word 58=MSW,Word 57=LSW)

} ATA_IDENTIFY_DATA, *PATA_IDENTIFY_DATA;


/*设备信息结构*/
typedef struct {
	uint8   			ATAIsOK;	/*设备正常为1,无效或有错为0*/
	uint16 				ERRCODE;			/*设备出错代码*/
	int32 				ERRSECTOR;	/*读写扇区是出错的扇区号*/
	ATA_IDENTIFY_DATA	INFODATA;			/*设备的基本信息*/
}ATADEVICE,*PATADEVICE;

#define NULL 0
#define MAX_DEVICE 	2		/*定义设备数,由于只有主和从设备,所以最大值为2*/
#define TIMEOUTSET	0xffff		/*超时响应设备(与CPU的速度有关,没有准确的时间)*/

ATADEVICE 	ATA[MAX_DEVICE];	/*设备识别信息识别结构,及设备的状态*/ 
uint8		ATA_DevReg ;		/*设备磁头寄存器值,通过该寄存器可以确定*/

/******************************************************************************************/
/*相关函数原型*/
/******************************************************************************************/

//****************************************************************************************
/*用户使用函数*/
void 	ATA_INI(void);																/*总线设置与初始化,ATA设备初始化*/
void  	ATA_FindIDEDevice(void);													/*硬件复位,查找IDE设备,并初始化*/ 

uint8 	ATA_IdleImmediate(uint8 Device);				    						/*立即进入空闲状态(硬盘转动)*/ 
uint8 	ATA_StandbyImmediate(uint8 Device);											/*立即进入待机状态(硬盘停转)*/ 
uint8 	ATA_ReadSector(uint8 Device,uint16 *Buffer,uint32 Sector,uint8 count);		
/*读出扇区数据函数*/ 
uint8 	ATA_WriteSector(uint8 Device,uint16 * Buffer, uint32 Sector ,uint8 count);	
/*写入设备扇区数据函数*/ 
uint8 	ATA_IdentifyDrive(uint8 Device,void *PTR);									/*获取设备信息*/
			
//****************************************************************************************
/*驱动内部使用函数*/
uint8 	ATA_IssueIDEIdentify(uint8 Device);		/*设备识别,获取设备基本信息*/

uint8 	ATA_SetFeature(uint8 Device);					/*设备总线特性设置*/
void  	ATA_WriteSetting(uint32 Sectors , uint8 Count);	/*写IDE多数扇区数据*/ 
void  	ATA_ReadSetting(uint32 Sectors , uint8 Count);	/*写IDE多数扇区数据*/ 
void 	ATA_WriteData512B(uint16 * Buffer);		/*连续写512字节数据*/ 
void 	ATA_ReadData512B(uint16 * Buffer);		/*连续读512字节数据*/ 
/*硬件相关函数*/
void 	SYS_BusIni(void);				/*ATA总线初始化函数*/
uint16 	SYS_PortIn(uint8 reg);				/*从ATA设备指定的寄存器读出一个字(2字节)*/ 
void 	SYS_PortOut(uint8 reg,uint16 data);		/*从ATA设备指定的寄存器写入一个字*/ 
void 	SYS_IdeHardReset(void);				/*硬件复位*/
uint8 	SYS_HaveCard(void);				/*检测CF卡是否存在*/
void SYS_WaitInUS(uint32 times);
uint8	temp1,temp2,temp3,temp4,temp5,temp6,temp7;
uint16	temp16;
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;
    BCSCTL1= RSEL2 + RSEL1 + RSEL0;  // 我没接8MHz晶体,所以用DCO最高频率提供MCLK
    DCOCTL = DCO2 + DCO1 + DCO0;
    SYS_BusIni();
	/*探测设备是否存在函数测试*/
	if(SYS_HaveCard())				//探测CF卡是否存在
	{	/*复位及读寄存器函数测试*/
		SYS_IdeHardReset();		//ATA设备硬件复位
		SYS_WaitInUS(48000);		//复位后ATA设备需在480mS内完成硬件初始化和自检
		temp1 = GetSECCNT();		//复位该寄存器的值为0x01
		if(0x01!=temp1)
		{
			while(1);				//读函数有误或设备无效
		}
		temp2 = GetSector();			//复位该寄存器的值为0x01
		temp3 = GetCylinderLow();		//复位该寄存器的值为0x00
		temp4 = GetCylinderHigh();		//复位该寄存器的值为0x00
		temp5 = GetDeviceHead();		//复位该寄存器的值为0x00
		temp6 = GetStatus();			//复位该寄存器的值为0x50
		temp7 = GetAStatus();			//复位该寄存器的值为0x50
	
		/*写函数测试*/
		SetSector(0xaa);				//写数据寄存器
		temp16 = GetSector();	
		if(0xaa!=temp16)			//比较写入与读出的值
		{
			while(1);				//写函数有误
		}
	}
	while(1);
}
void SYS_BusIni(void)
{
    CF_ADDR_DIR |= CS1 +CS0 + A2 + A1 + A0 + WR +RD + RST;
    CF_CONTROL_DIR &= ~(INTRQ + IORDY);
    CF_CONTROL_DIR |= DASP;
    CF_DATA_DIR = 0;
    
    CF_ADDR_OUT |= RST + WR + RD + CS1 + CS0;
    CF_ADDR_OUT &=~(A2+A1+A0);
    CF_CONTROL_OUT |= DASP;
}
/*********************************************************************************************************
** 函数名称: SYS_WaitInUS
** 功能描述: 延时等级约1微秒函数,该函数根据系统时间不同与不同,但不应少到1微秒。
** 输   入: times,延时时间等级
** 输   出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void SYS_WaitInUS(uint32 times)
{	
  _NOP();
  _NOP();

⌨️ 快捷键说明

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