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

📄 ide.i

📁 Accessing IDE Hard disk by ATmega32 microcontroller (Proteus simulation include)
💻 I
字号:
//#ifndef __IDE_H__
//#define __IDE_H__

//control bits of hard drive ('_' means active low)

//data bus of hard drive


//command block registers

//control block registers

void InitDrive(void);
void SetRegAddr(unsigned char reg);
unsigned int ReadRegister();
void WriteRegister(unsigned int val);
void WaitNBusy(unsigned char bReady);
void SetBusIn(void);
void SetBusOut(void);
unsigned char ReadSectorLBA(unsigned long lba,unsigned char *buffer);

//#endif //__IDE_H__

void SetBusIn(void)
{
  //set up data bus as an input 
  DDRA = 0;				//PORTA is an input
  DDRC = 0;				//PORTC is an input  
  PORTA = 0xff;
  PORTC = 0xff;
  delay_us(5);
}

void SetBusOut(void)
{
  //set up data bus as an output 
  DDRA = 0xff;				//PORTA is an output
  DDRC = 0xff;				//PORTC is an output  
  delay_us(5);
}

void InitDrive(void)
{
  //set up data bus as an input
  SetBusIn();
  
  //set up control bus (output)
  DDRB = 0xff;				//PORTB is an output
  PORTB = 0xe3;				//negate all outputs
  delay_us(5);
  
  //send reset signal to drive
  PORTB = 0x63;				//assert reset bit 
  delay_ms(10);				//wait 10 ms
  PORTB = 0xe3;				//negate reset bit
}

void SetRegAddr(unsigned char reg)
{
  SetBusOut();

  //output address of a command or control register  
  PORTB = (PORTB & 0x83) | (reg << 2);             
}

unsigned int ReadRegister()
{
  unsigned int val;
  
  SetBusIn();
       
  //asert read signal
  PORTB.1 = 0;
  delay_us(5);    
   
  //read date from bus
  val =  PINA;
  val |= ((unsigned int) PINC) << 8;
    
  //negate read signal
  PORTB.1 = 1;
  delay_us(5);   
  
  return val;
}

void WriteRegister(unsigned int val)
{  
  SetBusOut();
  
  //asert write signal
  PORTB.0 = 0;
  delay_us(5);    
   
  //read date from bus
  PORTA =  val;
  PORTC = (val >> 8);
    
  //negate write signal
  PORTB.0 = 1;
  delay_us(5);
}

//wait for DRDY as well if (bReady == 1)
void WaitNBusy(unsigned char bReady)
{
  unsigned char val, BSY = 1, DRDY = 0;
  
  SetBusIn();

  //set register address
  SetRegAddr(0x0e);
  
  do
  {
    //get status register
    val = ReadRegister();
    
    //extract bits from register
    BSY = val >> 7;
    DRDY = (val >> 6) & 1;
  }
  while(BSY || (bReady && !DRDY));
}

unsigned char ReadSectorLBA(unsigned long lba,
                	     unsigned char *buffer)
{
  unsigned char head, sector;
  unsigned int cylinder; 
  unsigned char status;
  unsigned int i, tmp;
    
  //convert parse LBA address to load into registers
  sector = (unsigned char) lba;
  cylinder = (unsigned int) (lba >> 8);
  head = (unsigned char) (lba >> 24);
  
  /*printf("lba(lo) = %0x\r\n", lba);
  printf("lba(hi) = %0x\r\n", lba >> 16);
  printf("head = %0x\r\n", head);
  printf("cylinder = %0x\r\n", cylinder);
  printf("sector = %0x\r\n", sector);*/
  
  //wait for device to be not busy
  WaitNBusy(0);
  
  //write drive/head register to select device 0
  SetRegAddr(0x16);
  WriteRegister(head | 0xe0);
  
  //wait for device to be not busy and ready
  WaitNBusy(1);
            
  //write parameters of read sectors command
  SetRegAddr(0x12);
  WriteRegister(1);
  
  SetRegAddr(0x13);
  WriteRegister(sector);
  
  SetRegAddr(0x14);
  WriteRegister(cylinder);
  
  SetRegAddr(0x15);
  WriteRegister(cylinder >> 8);

  //write read sectors command  
  SetRegAddr(0x17);
  WriteRegister(0x20);
  
  for(i = 0; i < 512; i = i + 2)
  { 
    WaitNBusy(0);
  
    SetRegAddr(0x17);
    status = ReadRegister();
  
    //check for error (ERR == 1)
    if (status & 1)
      return 0;
  
    SetRegAddr(0x10);
    tmp = ReadRegister();
  
    //split data into 8-bit pieces
    buffer[i] = tmp;
    buffer[i+1] = tmp >> 8;
  }
 
  return 1;
}

⌨️ 快捷键说明

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