|
本帖最后由 dalaoshi 于 2021-4-16 18:41 編輯
最近用STC8G去讀取SD卡,用SPI界面,讀得出,就是比較慢,因?yàn)镸CU的頻率只達(dá)33.1771MHz,SPI的時(shí)鐘最高是系統(tǒng)頻率/4=8mhz, 距離SD卡可用的25MHZ還差一大截,很可惜,沒有再快的8BIT單片機(jī)了,因?yàn)檫@樣,就打算改用SD模式,有四條輸出線,快4倍,很吸引人,但SD模式要用到CRC,否Z則發(fā)給SD卡指令后,卡懶得理你,無(wú)反應(yīng),這也是為何SD卡也叫安全卡的理由,沒有這個(gè)功能,帶電拔進(jìn)拔出時(shí)資料可能會(huì)消失,可是這CRC對(duì)業(yè)余愛好者確是鐵板一塊。
還好有了網(wǎng)絡(luò),經(jīng)過(guò)三天三夜的搜尋與學(xué)習(xí),終于也明白了個(gè)大概,也收集了不少例程,但CRC7的文章比較少,CRC7應(yīng)該是SD卡專用的格式,其種子(多項(xiàng)式)的二進(jìn)值是10001001,這個(gè)種子是用來(lái)除別的數(shù)來(lái)獲得該數(shù)的CRC,這個(gè)過(guò)程很繁雜,要一位一位地比較運(yùn)算,聽說(shuō)要90多個(gè)時(shí)鐘才算完一個(gè)字,如果是一個(gè)長(zhǎng)字串,那就是個(gè)天文數(shù)字的時(shí)鐘數(shù),最后只得了個(gè)7位的數(shù)字,很浪費(fèi)時(shí)間,因此有聰明人就發(fā)明了查表法,就是把0-255的CRC都先算出來(lái),制成一個(gè)表,放在程序內(nèi)某個(gè)區(qū),需要知道一個(gè)BYTE的CRC,就到相應(yīng)位置去查就可,51單片機(jī)就用MOVC A, @A+DPTR,至于字串的CRC怎么算呢?網(wǎng)上文章的說(shuō)法是:
“特別需要關(guān)注的是,對(duì)傳輸?shù)拿恳粋(gè)字節(jié)的與CRC多項(xiàng)式校驗(yàn)完以后的校驗(yàn)值,要和下一個(gè)需要的校驗(yàn)的字節(jié)先異或,然后再與CRC多項(xiàng)式執(zhí)行校驗(yàn)。當(dāng)最后一個(gè)數(shù)據(jù)校驗(yàn)完以后,需左移一位,即獲得CRC7的校驗(yàn)結(jié)果。”
我的理解是:“用字串的第一個(gè)字查表取出該子的CRC, 再與第二個(gè)字XRL,用XRL后的值去查表取出CRC, 以此類推直到最后一個(gè)字,就是該字串的CRC了”。
我根據(jù)這一理解用STC8G來(lái)檢驗(yàn)SD卡的CMD0,“40H,00H, 00H, 00H, 00H”,答案應(yīng)該是4AH,結(jié)果是51H,顯然是我對(duì)上面的論述理解不對(duì),觀察程序每個(gè)步驟的結(jié)果,查表取值都對(duì),但XRL對(duì)于00H沒有變化,附上完整代碼請(qǐng)前輩們幫忙看看,主要程序從74行開始,其他都是支持除錯(cuò)的代碼。
運(yùn)行結(jié)果為(HEX):“55 1B 64 64 72 72 5D 5D 18 18 51”,答案51。
;CRC7 測(cè)試
HEADBUFFER1 EQU 0A0H
LASTBUFFER1 EQU 0FFH ;第一組緩沖區(qū),共32位
IE2 EQU 0AFH ;ETKSUI, ET4, ET3, ES4, ES3, ET2, ESPI, ES2
S2CON EQU 9AH ;S2SM0, S2SM1(RESRVE, MUST BE 1), S2SM2, S2R_ENABLE, S2TB8, S2RB8, S2TI, S2RI
S3CON EQU 0ACH ;SAME AS S2CON
S4CON EQU 84H
S2BUF EQU 9BH
S3BUF EQU 0ADH
S4BUF EQU 85H
P4 EQU 0C0H
P5 EQU 0C8H
P6 EQU 0E8H
P7 EQU 0F8H
T3L EQU 0D5H
T3H EQU 0D4H
T4L EQU 0D3H
T4H EQU 0D2H
MD0 EQU 0FCF3H
MD1 EQU 0FCF2H
MD2 EQU 0FCF1H
MD3 EQU 0FCF0H
MD4 EQU 0FCF5H
MD5 EQU 0FCF4H
ARCON EQU 0FCF6H
OPCON EQU 0FCF7H
T4T3M EQU 0D1H
P_SW2 EQU 0BAH
P_SW1 EQU 0A2H
T2H EQU 0D6H
T2L EQU 0D7H
RELOAD_COUNT EQU 253 ;247(11.0592, 38400BPS) FOR TIMER_1 251=115200(18.4320M 115200BPS) 253(11.0592M 115200BPS)
AUXR EQU 8EH
AUXR1 EQU 0A2H ;7,6=PCA-P4,5=SPI-P4,4=S2-P4,3=GF2,2=ADRJ,1,0=DPS
AUXR2 EQU 08FH
WAKE_CLKO EQU 08FH ;WAKEUP AND CLOCK OUTPUT CONTROL REGISTER 8GNEWNAME:INTCLKO x,EX4,EX3,EX2,xT2CLKO, T1CLKO, T0CLKO
AUXINTIF EQU 0EFH ;EXTRA INT
ORG 0000H
LJMP MAIN
ORG 0023H
LJMP UART1 ;UART1 RECEIVED INTERRUPT
MAIN:
LCALL DELAY3
;MOV 97H, #00000001; SLOW DOWN
MOV R0, #HEADBUFFER1 ;INIT THE BTYE TO SENT IN BUFFER POINTER
MOV R1, #HEADBUFFER1 ;INIT THE POINTER FOR BYTE CAN STORE IN BUFFER
MOV WAKE_CLKO,#00000001B ;ENABLE T2(=4),T1(=2) T0(=1) HAVE CLOCK OUTPUT T2@P1.0 T1@P3.5 T0@P3.4
MOV AUXR,#11111100B ;T0X12,T1X12,UART_M0X6,T2RUN,S2SMOD,T2X12,EXTRAM,S1BRS
MOV AUXR2, #00000000B ;#00010000B=SHIFT UART2
MOV TMOD, #00100010B ;TIMER0, TIMER1 AS MOD2(8 BYTE AUTO RELOAD TIMER)
;GATE, C/T,M1,M0(T1) GATE, C/T,M1,MO(T0)
MOV PCON, #00000000B ;THIS DOUBLE THE T2 AND T0 T1 RATE; SMOD IS AT PCON.7 249(3.64=32US) 219 AT P3.5)
LCALL IOSET8G ;8G初始時(shí)IO腳全為高阻,必須設(shè)定LED才會(huì)亮
LCALL INITIAL_UART1 ;USE T1 AS SERIAL BAUD GENERATE FOR UART1
CLR TI
CLR RI
SETB EA ;ENABLE ALL INTERRUPT
;================這里開始========================
MOV A, #55H ;這個(gè)測(cè)定串口正常
LCALL SENTONEBYTE1
MOV DPTR, #2000H ;這個(gè)取碼表第03H位顯示1BH, 證實(shí)取碼位置正確
MOV A, #03H
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
MOV A, #40H ;第一字節(jié)查表正確,顯示64H
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
MOV B, #00H ;第二字節(jié)
XRL A, B ;根據(jù)網(wǎng)上指導(dǎo),要先與原來(lái)前面獲得的CRC值(64H)異或
LCALL SENTONEBYTE1 ;但與00H異或后還是原來(lái)的值
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
MOV B, #00H
XRL A, B
LCALL SENTONEBYTE1
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
MOV B, #00H
XRL A, B
LCALL SENTONEBYTE1
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
MOV B, #00H
XRL A, B
LCALL SENTONEBYTE1
MOVC A, @A+DPTR
LCALL SENTONEBYTE1
LED: ;停機(jī)
CLR P1.0
LED1:
MOV A, R0
XRL A, R1
JZ LEDEXIT
LEDEXIT:
JMP LED1
INITIAL_UART1: ;
MOV SCON, #01010000B ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK
MOV TH1, #247 ;247(11.0592, 38400BPS) FOR TIMER_1 251=115200(18.4320M 115200BPS) 253(11.0592M 115200BPS) IF PCON.7=0
MOV TL1, #247 ;247(33.1771, 115200 255-253=2 2x2=4=22M, 4X2=33.1771) PCON.7=0
SETB PS ;SERIAL PORT PRORITY HIGH
SETB TR1 ;RUN TIMER_1
SETB ES ;ENABLE UART1 INTERRUPT
RET
SENTONEBYTE1: ;SENT OUT A
CHECKBUSY1:
JB 40H, CHECKBUSY1
SETB 40H
MOV SBUF, A
RET
UART1:
PUSH ACC
PUSH PSW
JNB RI, UART1CHECKTI
MOV A, SBUF ;READ THE CHARACTER FROM THE SERIAL PORT
CLR RI ;CLEAR RECEICED FLAG
MOV @R1, A ;SAVE TO BUFFER
CJNE R1, #LASTBUFFER1, NEXTREADBUFFER
MOV R1, #HEADBUFFER1
JMP UART1EXIT
NEXTREADBUFFER:
INC R1 ;POINT TO NEXT BUFFER
JMP UART1EXIT
UART1CHECKTI:
CLR TI
CLR 40H
UART1EXIT:
POP PSW
POP ACC
RETI
DELAY2:
MOV 40H, #255
SLOWDOWN0:
MOV 41H, #170
SLOWDOWN:
MOV 42H, #2
SLOWDOWN2:
DJNZ 42H, SLOWDOWN2
DJNZ 41H, SLOWDOWN
DJNZ 40H, SLOWDOWN0
RET
DELAY3:
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
RET
IOSET8G:
;-----------I/O CONFIGUE
MOV 93H, #00000000B ;SET P0 0,0=I/0, 0,1=HIGH CURRENT OUTPUT, 1,0=HIGH IMPEDENY INPUT 1,1=OPEN COLLECTIVE OUTPUT
MOV 94H, #00000000B ;SET P0 (CONMAIN WITH 93H THIS IS SENCOND BIT)
MOV 91H, #00000000B ;SET P1
MOV 92H, #00000000B ;SET P1
MOV 95H, #00000000B ;SET P2
MOV 96H, #00000000B ;SET P2
MOV 0B1H, #00000000B ;SET P3
MOV 0B2H, #00000000B ;SET P3
MOV 0B3H, #00000000B ;SET P4
MOV 0B4H, #00000000B ;SET P4
MOV 0C9H, #00000000B ;SET P5
MOV 0CAH, #00000000B ;SET P5
MOV 0CBH, #00000000B ;SET P6
MOV 0CCH, #00000000B ;SET P6
;MOV 0E1H, #00000000B ;SET P7
;MOV 0E2H, #00000000B ;SET P7
RET
ORG 2000H
;G(X)=X7+X3+1
DB 0X00, 0X09, 0X12, 0X1B, 0X24, 0X2D, 0X36, 0X3F, 0X48, 0X41, 0X5A, 0X53, 0X6C, 0X65, 0X7E, 0X77
DB 0X19, 0X10, 0X0B, 0X02, 0X3D, 0X34, 0X2F, 0X26, 0X51, 0X58, 0X43, 0X4A, 0X75, 0X7C, 0X67, 0X6E
DB 0X32, 0X3B, 0X20, 0X29, 0X16, 0X1F, 0X04, 0X0D, 0X7A, 0X73, 0X68, 0X61, 0X5E, 0X57, 0X4C, 0X45
DB 0X2B, 0X22, 0X39, 0X30, 0X0F, 0X06, 0X1D, 0X14, 0X63, 0X6A, 0X71, 0X78, 0X47, 0X4E, 0X55, 0X5C
DB 0X64, 0X6D, 0X76, 0X7F, 0X40, 0X49, 0X52, 0X5B, 0X2C, 0X25, 0X3E, 0X37, 0X08, 0X01, 0X1A, 0X13
DB 0X7D, 0X74, 0X6F, 0X66, 0X59, 0X50, 0X4B, 0X42, 0X35, 0X3C, 0X27, 0X2E, 0X11, 0X18, 0X03, 0X0A
DB 0X56, 0X5F, 0X44, 0X4D, 0X72, 0X7B, 0X60, 0X69, 0X1E, 0X17, 0X0C, 0X05, 0X3A, 0X33, 0X28, 0X21
DB 0X4F, 0X46, 0X5D, 0X54, 0X6B, 0X62, 0X79, 0X70, 0X07, 0X0E, 0X15, 0X1C, 0X23, 0X2A, 0X31, 0X38
DB 0X41, 0X48, 0X53, 0X5A, 0X65, 0X6C, 0X77, 0X7E, 0X09, 0X00, 0X1B, 0X12, 0X2D, 0X24, 0X3F, 0X36
DB 0X58, 0X51, 0X4A, 0X43, 0X7C, 0X75, 0X6E, 0X67, 0X10, 0X19, 0X02, 0X0B, 0X34, 0X3D, 0X26, 0X2F
DB 0X73, 0X7A, 0X61, 0X68, 0X57, 0X5E, 0X45, 0X4C, 0X3B, 0X32, 0X29, 0X20, 0X1F, 0X16, 0X0D, 0X04
DB 0X6A, 0X63, 0X78, 0X71, 0X4E, 0X47, 0X5C, 0X55, 0X22, 0X2B, 0X30, 0X39, 0X06, 0X0F, 0X14, 0X1D
DB 0X25, 0X2C, 0X37, 0X3E, 0X01, 0X08, 0X13, 0X1A, 0X6D, 0X64, 0X7F, 0X76, 0X49, 0X40, 0X5B, 0X52
DB 0X3C, 0X35, 0X2E, 0X27, 0X18, 0X11, 0X0A, 0X03, 0X74, 0X7D, 0X66, 0X6F, 0X50, 0X59, 0X42, 0X4B
DB 0X17, 0X1E, 0X05, 0X0C, 0X33, 0X3A, 0X21, 0X28, 0X5F, 0X56, 0X4D, 0X44, 0X7B, 0X72, 0X69, 0X60
DB 0X0E, 0X07, 0X1C, 0X15, 0X2A, 0X23, 0X38, 0X31, 0X46, 0X4F, 0X54, 0X5D, 0X62, 0X6B, 0X70, 0X79
END
|
|