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

📄 main.c

📁 avr单片机硬盘控制 (含代码、原理图) avr单片机硬盘控制 (含代码、原理图)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************
WinAVR
项目 : 硬盘控制
版本 : 0.1
日期 : 2005-1-9
作者 : 金方剑


芯片                : ATmega16L
时钟                : 8.000000 MHz
*****************************************************/
#include <avr/io.h>
#include <avr/iom16.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//******************************************************************************
#define byte						unsigned char
#define uint						unsigned int
#define	ulong						unsigned long
#define nop()						__asm__ __volatile__ ("nop" ::)
#define wdr()						__asm__ __volatile__ ("wdr" ::)
#define Set_Bit(val, bitn)			(val |=(1<<(bitn)))//设置某一位
#define Clr_Bit(val, bitn)			(val&=~(1<<(bitn)))//清除某一位
#define Get_Bit(val, bitn)			(val &(1<<(bitn)))//读取某一位
//******************************************************************************
//线路连接定义。如电路有变直接修改就可以了
#define WDataL 						PORTA
#define WDataH 						PORTB
#define RDataL 						PINA
#define RDataH 	   					PINB
#define CS0	   	   					PC0
#define CS1	   			 			PC1
#define DA0	   	   					PD5
#define DA1	   	   					PD6
#define DA2	   	   					PD7
#define Read						PC6
#define Write 						PC7
#define Rst							PD4
//******************************************************************************
//ATA命令
// CB_ERR ERROR REGISTER BITS 
#define ATA_ER_BBK					0x80    // ATA bad block
#define ATA_ER_UNC					0x40    // ATA uncorrected error
#define ATA_ER_MC					0x20    // ATA media change
#define ATA_ER_IDNF					0x10    // ATA id not found
#define ATA_ER_MCR					0x08    // ATA media change request
#define ATA_ER_ABRT					0x04    // ATA command aborted
#define ATA_ER_NTK0					0x02    // ATA track 0 not found
#define ATA_ER_NDAM					0x01    // ATA address mark not found
// CB_DH bits 7-4 OF THE DEVICE/HEAD REGISTER
#define ATA_DH_DEV0					0xE0    // select device 0 LBA MODE
#define ATA_DH_DEV1					0xF0    // select device 1 LBA MODE
//ATA commands (from ATA-3),
#define CMD_CFA_ERASE_SECTORS            0xC0
#define CMD_CFA_REQUEST_EXT_ERR_CODE     0x03
#define CMD_CFA_TRANSLATE_SECTOR         0x87
#define CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD
#define CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38
#define CMD_CHECK_POWER_MODE1            0xE5
#define CMD_CHECK_POWER_MODE2            0x98
#define CMD_DEVICE_RESET                 0x08
#define CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90
#define CMD_FLUSH_CACHE                  0xE7
#define CMD_FORMAT_TRACK                 0x50
#define CMD_IDENTIFY_DEVICE              0xEC
#define CMD_IDENTIFY_DEVICE_PACKET       0xA1
#define CMD_IDENTIFY_PACKET_DEVICE       0xA1
#define CMD_IDLE1                        0xE3
#define CMD_IDLE2                        0x97
#define CMD_IDLE_IMMEDIATE1              0xE1
#define CMD_IDLE_IMMEDIATE2              0x95
#define CMD_INITIALIZE_DRIVE_PARAMETERS  0x91
#define CMD_INITIALIZE_DEVICE_PARAMETERS 0x91
#define CMD_NOP                          0x00
#define CMD_PACKET                       0xA0
#define CMD_READ_BUFFER                  0xE4
#define CMD_READ_DMA                     0xC8
#define CMD_READ_DMA_QUEUED              0xC7
#define CMD_READ_MULTIPLE                0xC4
#define CMD_READ_SECTORS                 0x20
#define CMD_READ_VERIFY_SECTORS          0x40
#define CMD_RECALIBRATE                  0x10
#define CMD_SEEK                         0x70
#define CMD_SET_FEATURES                 0xEF
#define CMD_SET_MULTIPLE_MODE            0xC6
#define CMD_SLEEP1                       0xE6
#define CMD_SLEEP2                       0x99
#define CMD_STANDBY1                     0xE2
#define CMD_STANDBY2                     0x96
#define CMD_STANDBY_IMMEDIATE1           0xE0
#define CMD_STANDBY_IMMEDIATE2           0x94
#define CMD_WRITE_BUFFER                 0xE8
#define CMD_WRITE_DMA                    0xCA
#define CMD_WRITE_DMA_QUEUED             0xCC
#define CMD_WRITE_MULTIPLE               0xC5
#define CMD_WRITE_SECTORS                0x30
#define CMD_WRITE_VERIFY                 0x3C
//******************************************************************************
//硬盘状态寄存器地址定义
#define _Data 							0x0
#define _Err_Features 					0x1
#define _SecCount 						0x2
#define _SecNum 						0x3
#define _CylinderL 						0x4
#define _CylinderH 						0x5
#define _DeviceAndHead 					0x6
#define _Status_AND_Command				0x7
//******************************************************************************
/************************************************************
* D7   D6   D5   D4   D3   D2    D1   D0                    *
 BSY  DRDY DWF  DSC  DRQ  CORR  IDX  ERR                    *
BSY:驱动器忙;                                             *
DRDY:驱动器准备好;                                        *
DWF:驱动器写失败;                                         *
DSC:寻道结束;                                              *
DRQ:请求服务,驱动器希望通过数据寄存器与CPU交换一字节数据	*
CORR:当可以纠正的读错误发生时,该位置1,数据传输将继续进行 *
IDX:收到综引信号;                                         *
ERR:命令执行出错。                                         *
*************************************************************/
#define BSY	 						((HDstate&0x80)==0x80)
#define DRDY						((HDstate&0x40)==0x40)
#define DWF							((HDstate&0x20)==0x20)
#define DSC							((HDstate&0x10)==0x10)
#define DRQ							((HDstate&0x08)==0x08)
#define CORR						((HDstate&0x04)==0x04)
#define IDX							((HDstate&0x02)==0x02)
#define ERR							((HDstate&0x01)==0x01)
//******************************************************************************
//主工程的函数
//int		main(void);
void	delay_ms(uint ms);//毫秒级定时
void	delay_us(uint us);//微秒级定时
//******************************************************************************
//ATA的函数
void HDinit(void);//硬盘初始化
byte ReadReg(byte byAddr);//读寄存器
void WriteReg(byte byAddr,byte byData);//写寄存器
byte WaitBSY(void);//等待BSY信号
byte WaitDRQ(void);//等待DRQ信号
void RegAddrChangePhysics(byte byRegAddr);//把寄存器地址转化为物理接口
void Read_HD_ID(void);//读硬盘ID
void HDStop(void);//让硬盘休眠(停转)
void HDRunningActivation(void);//激活硬盘(转动)
void LBA(unsigned long lba);//LBA寻址
void ReadData(void);//读硬盘数据寄存器内容
void WriteData(byte byDataL,byte byDataH);//写硬盘数据寄存器内容
void ReadSectorData(ulong lSectorAdd);//读一个扇区的数据
void WriteSectorData(ulong lSectorAdd);//写一个扇区的数据
void WriteCHS(uint iCylinder,byte byHead,byte bySector,byte byReadcount);//硬盘寻址
byte ReversalData(byte byReversal);//颠倒数据,0位换到7位,7位换到0位
//******************************************************************************
byte	uartdata=0;
byte	HDDATAL,HDDATAH;						//低字节,高字节
byte	HDstate;								//硬盘状态
byte	HDSectorDATA[512];						//硬盘扇区数据
//******************************************************************************
//UART接收中断
SIGNAL(SIG_UART_RECV)
{
	uartdata=UDR;//调试用的,不用管它
	nop();
	UDR=uartdata;
}
//******************************************************************************
int main(void)
{
ulong t1=0;
cli();
//SP=0x45f;	//WinAVR已经初始化堆栈
DDRC=0xc3;
PORTD=1<<PD0|1<<PD1;
DDRD=0xfe;
UCSRA=1<<U2X;
UCSRB=1<<RXCIE|1<<RXEN|1<<TXEN;
UBRRL=105;   //f0/9615/8+1,9615
delay_ms(10);
Clr_Bit(PORTD,Rst);  //硬盘复位
delay_ms(40);
Set_Bit(PORTD,Rst);
delay_ms(10);
HDinit();
//Read_HD_ID();
sei();
	while(1)
	{
		switch(uartdata)
		{
			case 2:
				Read_HD_ID();
				uartdata=0;
				break;
			case 3:
				ReadSectorData(t1);
				nop();
				UDR=uartdata;
				uartdata=0;
				break;
			case 4:
				WriteSectorData(t1);
				nop();
				UDR=uartdata;
				uartdata=0;
				break;
			case 5:
				HDStop();
				UDR=uartdata;
				uartdata=0;
				break;
			case 6:
				HDRunningActivation();
				UDR=uartdata;
				uartdata=0;
				break;

		}
		wdr();
	}
}
/************************************************************
*函数名称:delay_ms(uint ms)									*
*用途:延时													*
************************************************************/
void delay_ms(uint ms)//乱延时的,可能不准
{
	uint i,j;
	for(j=0;j<ms;j++)
	{
		for(i=0;i<1140;i++)
			wdr();
	}
}
/************************************************************
*函数名称:delay_us(uint us)									*
*用途:延时													*
************************************************************/
void delay_us(uint us)//乱延时的,可能不准
{
	int j;
	for (j=0;j<us;j++) 
	{
		wdr();
		nop();
		nop();
		nop();
		nop();
		nop();
		nop();
		nop();
		nop();
	}
}
/************************************************************
*函数名称:void HDinit(void)									*
*用途:硬盘初始化											*
************************************************************/ 
void HDinit(void)
{
	Set_Bit(PORTC,Write);
	Set_Bit(PORTC,Read);
	Clr_Bit(PORTC,CS0);
	Set_Bit(PORTC,CS1);
	WriteReg(_DeviceAndHead,0xa0);
	do
	{
		WriteReg(_DeviceAndHead,0xa0);
		HDstate=ReadReg(_Status_AND_Command);       
	}while((!DRDY)||BSY);
	WriteReg(_DeviceAndHead,0x40);
	WriteReg(_SecCount,60);
	WriteReg(_Status_AND_Command,CMD_INITIALIZE_DRIVE_PARAMETERS);//0x91
	WaitBSY();
	WriteReg(_Status_AND_Command,CMD_RECALIBRATE);//0x10
	WaitBSY();
}
/************************************************************
*函数名称:byte ReadReg(byte byAddr)							*
*用途:读寄存器												*
************************************************************/ 
byte ReadReg(byte byAddr)

⌨️ 快捷键说明

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