http://blog.163.com/zhaojun_xf/blog/static/300505802008111521454957/ 2008 來(lái)自:http://www./posts/5202.html #include <iom16v.h> // MMC commands #define MMC_GO_IDLE_STATE 0 #define MMC_SEND_OP_COND 1 #define MMC_SEND_CSD 9 #define MMC_SEND_CID 10 #define MMC_SEND_STATUS 13 #define MMC_SET_BLOCKLEN 16 #define MMC_READ_SINGLE_BLOCK 17 #define MMC_WRITE_BLOCK 24 #define MMC_PROGRAM_CSD 27 #define MMC_SET_WRITE_PROT 28 #define MMC_CLR_WRITE_PROT 29 #define MMC_SEND_WRITE_PROT 30 #define MMC_TAG_SECTOR_START 32 #define MMC_TAG_SECTOR_END 33 #define MMC_UNTAG_SECTOR 34 #define MMC_TAG_ERASE_GROUP_START 35 #define MMC_TAG_ERARE_GROUP_END 36 #define MMC_UNTAG_ERASE_GROUP 37 #define MMC_ERASE 38 #define MMC_CRC_ON_OFF 59 #define R1_BUSY 128 #define R1_PARAMETER 64 #define R1_ADDRESS 32 #define R1_ERASE_SEQ 16 #define R1_COM_CRC 8 #define R1_ILLEGAL_COM 4 #define R1_ERASE_RESET 2 #define R1_IDLE_STATE 1 #define led1_off (PORTA|=(1<<6)) #define led1_on (PORTA&=~(1<<6)) #define led2_off (PORTA|=(1<<5)) #define led2_on (PORTA&=~(1<<5)) #define disable_mmc_cs (PORTB|=(1<<0)) #define enable_mmc_cs (PORTB&=~(1<<0)) unsigned char ram_data[512]; extern void LCD_write(unsigned char data,unsigned char dc); /***********SPI初始化******************/ void SPI_masterinit(void) { //不中斷 允許 主模式 fck/4 SPCR=0b01010000; //SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 }
/***********SPI讀取/寫(xiě)入****基礎(chǔ)SPI傳送命令******/ unsigned char SPI_tx_rx(unsigned char spi_data); unsigned char SPI_tx_rx(unsigned char spi_data) { SPDR=spi_data; while (!(SPSR&0x80)); return SPDR; } /***********MMC_sendCmd();*****基礎(chǔ)傳送命令*******/ unsigned char MMC_sendCmd(unsigned char cmd,unsigned char A31_24,unsigned char A23_16,unsigned char A15_8,unsigned char A7_0); unsigned char MMC_sendCmd(unsigned char cmd,unsigned char A31_24,unsigned char A23_16,unsigned char A15_8,unsigned char A7_0) { signed char temp; enable_mmc_cs; SPI_tx_rx(cmd|0x40); //cmd"01xxxxxx" SPI_tx_rx(A31_24); SPI_tx_rx(A23_16); SPI_tx_rx(A15_8); SPI_tx_rx(A7_0); SPI_tx_rx(0x95); //crc for cmd0 SPI_tx_rx(0xff); //one empty cycle
temp=SPI_tx_rx(0xff); //0=busy //LCD_write(temp,1); //test point if ((temp-0x80)>=0) //0b1xxxxxxx=err { temp=0xff; while (SPI_tx_rx(0xff)==0); // led1_on; //test point } else if (cmd==MMC_SEND_STATUS) //如果是讀狀態(tài)命令 { temp=SPI_tx_rx(0xff); //read STATUS while (SPI_tx_rx(0xff)==0); // led1_on; } else //是其他命令 { while (SPI_tx_rx(0xff)==0); // led1_on; } return temp; } /***********MMC_finish();***停止卡片******/ void MMC_finish(void) { disable_mmc_cs; SPI_tx_rx(0xff); } /***********MMC_flush();*****丟棄幾個(gè)字節(jié)*******/ void MMC_flush(unsigned char flush_num); void MMC_flush(unsigned char flush_num) { unsigned char counter; for (counter=0;counter<flush_num;counter++) SPI_tx_rx(0xff); //丟棄幾個(gè)字節(jié) MMC_finish(); }
/***********MMC_reset();***將MMC卡轉(zhuǎn)到SPI模式****/ void MMC_reset(void) { unsigned char counter,mmc_response,lcd_add; for (counter=0;counter<11;counter++) SPI_tx_rx(0xff);//80個(gè)時(shí)鐘開(kāi)始總線 mmc_response=MMC_sendCmd(MMC_GO_IDLE_STATE,0,0,0,0); //send cmd0 MMC_finish();
for (counter=0;counter<80;counter++) //失敗嘗試次數(shù) { mmc_response=MMC_sendCmd(MMC_SEND_OP_COND,0,0,0,0); MMC_finish(); if (mmc_response==0) //切換到SPI成功 { led2_on; counter=81; //跳出失敗嘗試次數(shù) } else led1_on; //切換到SPI失敗 }
}
/***********MMC_check();******測(cè)試卡是否正常為0***********/ unsigned char MMC_check(void); unsigned char MMC_check(void) { unsigned char mmc_response; mmc_response=MMC_sendCmd(MMC_SEND_STATUS,0,0,0,0); //send cmd MMC_finish(); LCD_write(0x55,1); //test point LCD_write(mmc_response&0x93,1); //test point LCD_write(0x55,1); //test point return (mmc_response&0x93); }
/***********MMC_name();**獲得卡的名字*****/ void MMC_name(void) { unsigned char counter,lcd_add,mmc_response=1; mmc_response=MMC_sendCmd(MMC_SEND_CID,0,0,0,0); while (mmc_response) //讀到數(shù)據(jù)為0表示正常,就跳出 { MMC_finish(); mmc_response=MMC_sendCmd(MMC_SEND_CID,0,0,0,0); LCD_write(mmc_response,1); //test point led1_on; //test point // prog_flag=1; //錯(cuò)誤標(biāo)記 } led1_off; //test point for (counter=0;counter<26;counter++) { ram_data[counter]=SPI_tx_rx(0xff); LCD_write(ram_data[counter],1); //test point } MMC_flush(8); }
/***********MMC_capactity();******************/ unsigned long MMC_capactity(void); unsigned long MMC_capactity(void) { unsigned char counter,lcd_add,mmc_response=1; mmc_response=MMC_sendCmd(MMC_SEND_CSD,0,0,0,0); while (mmc_response) //讀到數(shù)據(jù)為0表示正常,就跳出 { MMC_finish(); mmc_response=MMC_sendCmd(MMC_SEND_CID,0,0,0,0); LCD_write(mmc_response,1); //test point led1_on; //test point // prog_flag=1; //錯(cuò)誤標(biāo)記 } led1_off; //test point for (counter=0;counter<26;counter++) { ram_data[counter]=SPI_tx_rx(0xff); LCD_write(ram_data[counter],1); //test point } MMC_flush(8);
}
|