?? main.c
字號:
/*****************************************************
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 + -