Hardware platform: atmega8L minimum system
hard SPI (the SD card initialization uses the IO port simulation timing, because it is found in the experiment that a lower rate is required for stable initialization)
Software development platform: ICC-AVR version 6.31a
Hardware configuration: atmega8L internal 8m clock
Sandisk 128m SD card
Several basic subroutines and their introductions:
1. The IO port simulates SPI to realize data transmission, and is used during initialization
void iodatatransfer(unsigned char iodata)
{
unsigned char num,b;
num=0x80;
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
//SD_Write|=(1<
SD_Write|=(1<
SD_Write&=~(1<
WDR();//feed the dog
//SD_Write&=~(1<
if(num>0x01)
num=num>>1;
}
}
2. The io port simulates spi to realize data reading. During initialization, use
unsigned char iodataread(void)
{
unsigned char data,temp,b;
data=0;
temp=0;
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
SD_Write&=~(1<
WDR();//feed the dog
SD_Write|=(1<
temp&=0x10;//to maintain the pb.4 bit(data_in)
WDR();//feed the dog
if(temp)
{
data|=0x01;
}
if(b<7)
{
data=data<<1;//
}
delay_4ms();//4ms
WDR();//feed the dog
}
return data ;
}
3. The io port simulates spi to implement command sending and read response. During initialization, use
unsigned char iocmd(unsigned char *cmd)
{
unsigned temp,a,timeout;
temp=0xff;
timeout=0;
// Raise chip select -- ---/ss=1
SD_Disable();
WDR();//feed the dog
// Send an 8 bit pulse
iodatatransfer(0xff);
WDR();//feed the dog
// Lower chip select
SD_Enable();
for(a=0;a<6;a++)
{
iodatatransfer(*cmd++);
WDR();
//transfer cmd in io_mode
}
while(temp==0xff)//
{
WDR();//feed the dog
temp =iodataread();
if(timeout++>100)
{
break;
}
}
WDR();//feed the dog
return(temp);//the respone of the byte_write_operation
}
4. Hard spi read data
unsigned char Read_Byte_SD(void)
{
char Byte;
//SD_Enable();
SPDR=0xff;
while(!(SPSR&(1<
return(Byte) ;
}
5. Hard spi write data
void Write_Byte_SD(char Byte)
{
//SD_Enable();
SPDR=Byte;
while(!(SPSR&(1<
6. Hard spi write command and read response
unsigned char Write_Command_SD(char *CMD)
{
unsigned char a;
unsigned char tmp=0xff;
unsigned char Timeout=0;
// Raise chip select -----/ss=1
SD_Disable();
// Send an 8 bit pulse
Write_Byte_SD (0xFF);
// Lower chip select
SD_Enable();
//Send the 6 byte command
for(a=0;a<0x06;a++)
{
Write_Byte_SD(*CMD++);
}
//Wait for the response
while(tmp==0xff)//
{
tmp=Read_Byte_SD();
if(Timeout++>100)
{
break ;
}
}
//for some reason we need to delay here
//delay_1ms();
return(tmp);//the respone of the byte_write_operation
}
7. Initialize
unsigned char SDInit(void)
{
unsigned char a,b,retry, erroetoken;
unsigned char CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
// Set certain pins to inputs and others to outputs
// Only SPI_DI (data in) is an input
//SD_Direction_REG ==ddrb
SD_Direction_REG&=~(1<
//We need to wait for the SD_Direction_REG to be ready
for(a=0;a<200;a++)
{
WDR();//feed the dog
nop();
nop();
};
delay_1ms();
SD_Disable();//
iodatatransfer(0xff);
WDR();//feed the dog
//return 0;///////////
retry=0;
SD_Enable();
while((erroetoken=iocmd(CMD))!=0x01)//
{
WDR();
//serial(erroetoken);
if(retry++>200)
{ //fail and return
return 1;
}
}
//return 0;///////////
//Send the 2nd command
retry=0;
CMD[0]=0x41;
CMD[5]=0xFF;
while(erroetoken=iocmd(CMD)!=0x00)
{
WDR();
if (retry++>200)
{
return 2;
}
}
//Set the SPI bus to full speed
SPCR=0x50;
SPSR|=0x01;
//Raise Chip Select
SD_Disable();
return 0;
}
8.设置每次读的字节数
char SD_set_length(unsigned int length)
{
unsigned char retry;
//Command to set the block length;
char CMD[]={0x50,0x00,0x00,0x00,0x00,0xFF}; //cmd16
CMD[3]=((length&0xFF00)>>8);//
CMD[4]= (length&0x00FF);
while(Write_Command_SD(CMD)!=0)//
{
WDR();
if (retry++>200)
{
return 1;
}
}
SD_Disable();
return 0;
}
9.write 512 bytes to a given sector from a Byte_byte_long Buffer
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer,unsigned int Bytes)
{
unsigned int a;
unsigned char retry,temp;
//Command to read a block;
char CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};//cmd24
CMD[1]=((addr&0xFF000000)>>24);
CMD[2]=((addr&0x00FF0000)>>16);
CMD[3]=((addr&0x0000FF00)>>8);
CMD[4]=(addr&0x000000FF);
//Send the write command
while(Write_Command_SD(CMD)!=0)
{
if (retry++>50)
{
return 1;
}
}
//Send the start byte
Write_Byte_SD(0xfe);
//Read off all the bytes in the block
for(a=0;a
Write_Byte_SD(*Buffer++);
}
while((temp=Read_Byte_SD())&0x10);
//serial(temp);//according to p101 of datasheet
if((temp&0x0f)!=0x05)
return 2;
//Read CRC byte
while(SD_READ&0x10);//detect if data_in pb.4 is still busy(high)
// Set SD_Chip_Select to high
SD_Disable();
//SEI(); //re-enable interrupts
return 0;
}
unsigned char SD_read_sector(unsigned long addr,unsigned char *Buffer,unsigned int Bytes)
{
unsigned int a;
unsigned char retry;
//Command to read a block;
char CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17
//CLI(); //disable all interrupts
//addr = addr << 9; //addr = addr * 512
CMD[1]=((addr&0xFF000000)>>24);
CMD[2]=((addr&0x00FF0000)>>16);
CMD[3]=((addr&0x0000FF00)>>8);
CMD[4]=(addr&0x000000FF);
//Send the read command
while(Write_Command_SD(CMD)!=0)
{
WDR();//feed the dog
if (retry++>200)
{
return 1;
}
}
//Send the start byte
while(Read_Byte_SD()!=0xfe)
{
WDR();//feed the dog
}
//Read off all the bytes in the block
for(a=0;a
WDR();//feed the dog
*Buffer=Read_Byte_SD();
//serial(*Buffer);
Buffer++;
}
//Read CRC byte
Read_Byte_SD();
Read_Byte_SD();
// Set SD_Chip_Select to high
SD_Disable();
//SEI(); //re-enable interrupts
return 0;
}
/*
//read xx bytes no matter of misalignment!!
*/
unsigned char read_antimisaliment(unsigned long addr_temp,unsigned char *p_buffer, unsigned int length)
{
unsigned int _length=0x0000;
SD_Enable();
while(SD_read_sector(addr_temp,p_buffer,length))
{
SD_Enable();//
length-=0x0001;//to find a suuitable length to avoid misalignment
_length+=0x0001;// _length+length==xx
SD_set_length(length);
}
///
if(_length==0x0000)
{
return 0;
}
///
addr_temp+=length;
SD_Enable();//
SD_set_length(_length);
SD_Enable();//
while(SD_read_sector(addr_temp,p_buffer,_length))
{
SD_Enable();
}
SD_Enable();//
SD_set_length(length+_length);//to read the rest bytes of the xx bytes
return 0;
/////////////////
}
Previous article:Fuse configuration of avr microcontroller
Next article:AVR's SD card basic reading and writing procedures (I)
Recommended ReadingLatest update time:2024-11-16 13:29
- Popular Resources
- Popular amplifiers
- Principles and Applications of Single Chip Microcomputers 3rd Edition (Zhang Yigang)
- Metronom Real-Time Operating System RTOS for AVR microcontrollers
- Learn C language for AVR microcontrollers easily (with video tutorial) (Yan Yu, Li Jia, Qin Wenhai)
- ATmega16 MCU C language programming classic example (Chen Zhongping)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Disassembling a 32G USB flash drive
- STM32MP157A-DK1 evaluation + GO language web service (5)
- MSP432 serial port 0 transceiver
- The algorithm of digital filtering in single chip microcomputer
- TI Wireless Connectivity Technology Selection Guide
- Adding SDCard functionality to ESP32-S3 with MicroPython
- Show off the development boards I bought in recent months
- The flavor of the New Year is the “poor flavor” of backward productivity
- ZigBee Power Consumption Calculation
- When burning the program, you mistakenly select "cold start" and the program can only be downloaded when P3.2/P3.3 is 0/0. Solution