摘要:本文討論如何使用安全數字(SD)媒體格式擴展MAXQ2000的非易失數據存儲器。
低功耗、低噪聲的MAXQ2000微控制器適合于多種應用。MAXQ2000在閃存中存儲非易失性數據,并和用戶代碼空間共享32k字(64kB)的閃存容量。但如果你的應用需要更多的非易失性存儲器怎么辦呢?這篇文章說明了如何使用安全數碼(SD?)存儲介質來擴展MAXQ2000的非易失性數據存儲器。
其次,在保證能為目標應用提供足夠帶寬的前提下,應將連接外部存儲器的MAXQ2000 I/O數限制到最少。例如,Atmel的AT29LV512閃存芯片與一個主機微控制器連接時,需要15條地址線、8條數據線和3條控制線。由于MAXQ2000沒有外部地址/數據總線,在上述例子中,就需要由軟件來控制總線事務。對于某些應用來說,這種方法不能很有效地利用MAXQ2000的I/O引腳。
然而,基于SPI?和I2C的外部閃存器件只需要3到4個接口引腳。MAXQ2000具有一個硬件SPI模塊,而I2C在MAXQ2000上必須由用戶通過軟件實現(即"位模擬")。這種集成功能使得SPI接口成為訪問外部非易失性存儲器的主要途徑。
由于SD卡采用專有的共享總線,乍一看,似乎很難與MAXQ2000接口。然而,SD繼承了MMC的第二總線格式-SPI。由于MAXQ2000提供SPI硬件支持,連接非常容易。
圖1. MAXQ2000與SD存儲卡的接口非常簡單。
圖1的電路圖給出了一個典型應用電路。SD卡要求全雙工、8位SPI操作。數據從MAXQ2000的MOSI引腳同步輸入SD卡的DI引腳,并由SD卡的DO線同步輸入MAXQ2000的MISO引腳。數據在CLK信號的上升沿同步輸入和輸出。在每次數據傳輸的末尾還必須提供8個額外的時鐘,以允許SD完成任何未完結的操作。對應這些額外時鐘的輸入數據必須全為1。識別階段的時鐘頻率必須限定在400kHz以內,但SD卡一經識別后,時鐘頻率便可提高到25MHz。
CRC算法將被保護的數據用選中的除數進行除法運算,產生一個余數。因為該算法中用得的是多項式,所以該除法運算不含進位邏輯。無需考慮進位時,除法運算可通過邏輯XOR操作來實現。所選中的除數通常用CRC的多項式來表示。接著,計算出的余數和數據一起傳輸,接收器用此余數來檢查確認數據在傳輸過程中是否正常。
對于CRC-7,余數可通過一個7位移位寄存器在軟件中計算。計算開始時,將該移位寄存器初始化置為全零。當受保護數據的每一位(MSB在先)被移入移位寄存器的LSB時,移出移位寄存器的MSB,并進行檢查。如果移出的位為1,則用CRC-7多項式系數0x09進行異或運算,以此來修正移位寄存器的內容。如果從移位寄存器中移出的位為0,則無需XOR操作。受保護數據的最后一位被移入移位寄存器且完成了條件XOR操作后,必須按此類似方式移入7個或更多0。這一過程稱作擴張并完成多項式除法運算。此時,CRC-7值可從移位寄存器直接讀出。
圖2. 通過移位寄存器架構計算CRC-7。
當接收器收到所有受保護的數據后,接收器可計算基于受保護數據的CRC-7值并將改值與接收到的CRC-7值進行比較。如果這兩個值不同,接收器就能判斷出受保護數據在傳輸過程中出現錯誤。如果這兩個值相同,則接收器可完全判定通信通道上的數據是完整的。
CRC-16算法可用同樣的方式來構建。在這種情況下,移位寄存器長度為16位而不是7位;多項式系數改為0x1021,且輸入數據通過16個0位來擴張。
圖3. 發送給存儲卡的SPI模式SD命令采用6字節格式。
表1. 部分SD存儲卡命令
圖4. R1響應指示發出的命令是否成功執行。
SD卡進入SPI模式后,SD規范要求主機在進行其它任何請求之前先發送一條初始化命令。為了能區分MMC卡和SD卡,SD卡采用了一種不同的初始化命令,MMC卡對該命令是不響應的。先向卡發送命令55 (APP_CMD),緊接著再發送應用命令41 (SEND_OP_COND),這樣即完成了這個重要的步驟。MMC卡對命令55不做回應,通過這一點可鑒別出MMC卡,并將其視作無效介質而拒絕訪問。這個命令序列要一直重復執行,直到來自存儲卡的R1響應中所有位均為0 (也就是說,IDLE位變為低)才停止。
清單1. 代碼必須用SEND_OP_COND來識別SD和MMC卡。
SD卡包含了一些重要的寄存器,用來提供SD卡的相關信息。最重要的寄存器是存儲卡特定數據寄存器(CSD)。對于我們的應用示例而言,我們感興趣的是存儲器的數據塊大小和總容量。我們還必須對存儲卡標識數據寄存器(CID)加以注意,因為它包含了存儲卡的制造商詳細信息和序列號。圖5顯示了CSD寄存器和CID寄存器的配置結構。
圖5. CSD寄存器和CID寄存器提供SD卡的相關信息。
圖6. 從SD卡到主機的數據傳輸要加入一個起始令牌作為前綴。
如果完成了SD介質的讀取操作并且沒有錯誤發生,則先發送一個起始數據令牌,接著是固定數量的數據,最后是兩個字節的CRC-16校驗和。如果SD卡碰到硬件故障或介質讀取錯誤,則不會發送起始數據令牌。而是發送一個錯誤令牌,數據傳輸隨之中止。
如果數據被接受,SD卡會在存儲卡忙時始終將DO線保持為低電平。存儲卡忙期間,主機不必始終將卡選擇線保持為低電平,如果解除CS選擇狀態,SD卡將釋放DO線。當多于一個的設備與SPI總線連接時,上述處理方式非常有用。主機可以一直等待SD卡釋放忙指示標志,也可以定期觸發片選信號以檢查存儲卡的工作狀態。如果卡仍然處于忙狀態,它會將DO線拉低以指示該狀態。否則,存儲卡會使DO線返回至空閑狀態(見圖7)。
圖7. 從主機到SD卡的數據傳輸使用一套更為復雜的握手機制。
清單2. 強烈推薦使能CRC校驗和。
低功耗、低噪聲的MAXQ2000微控制器適合于多種應用。MAXQ2000在閃存中存儲非易失性數據,并和用戶代碼空間共享32k字(64kB)的閃存容量。但如果你的應用需要更多的非易失性存儲器怎么辦呢?這篇文章說明了如何使用安全數碼(SD?)存儲介質來擴展MAXQ2000的非易失性數據存儲器。
外部存儲器的設計考慮
對于你的應用設計來說,首要應該考慮電源電壓和電流的要求。在典型的MAXQ2000應用中,可采用一個雙路線性穩壓器,從而在所選的時鐘頻率下使處理器工作于盡可能低的核心電壓(VDD)下。MAXQ2000的VDD電壓可低至1.8V。VDDIO為MAXQ2000的I/O引腳供電,允許的電壓范圍最低至VDD,最高可達3.6V。可接受的外部存儲器電流消耗受限于電源的額定電流,對于電池供電設備,則電流消耗受限于電池系統的容量。其次,在保證能為目標應用提供足夠帶寬的前提下,應將連接外部存儲器的MAXQ2000 I/O數限制到最少。例如,Atmel的AT29LV512閃存芯片與一個主機微控制器連接時,需要15條地址線、8條數據線和3條控制線。由于MAXQ2000沒有外部地址/數據總線,在上述例子中,就需要由軟件來控制總線事務。對于某些應用來說,這種方法不能很有效地利用MAXQ2000的I/O引腳。
然而,基于SPI?和I2C的外部閃存器件只需要3到4個接口引腳。MAXQ2000具有一個硬件SPI模塊,而I2C在MAXQ2000上必須由用戶通過軟件實現(即"位模擬")。這種集成功能使得SPI接口成為訪問外部非易失性存儲器的主要途徑。
SD存儲卡
SD存儲介質是一種非易失性外部存儲器,可滿足許多應用的上述要求。SD格式是"多媒體卡" (MMC)格式的繼任產品。SD卡存儲器一般工作于3.3V電壓,具有適度的電流要求。SD卡的容量從幾兆字節到最高4GB不等。容量范圍如此之寬,可為眾多應用提供充足的外部存儲空間。由于SD卡采用專有的共享總線,乍一看,似乎很難與MAXQ2000接口。然而,SD繼承了MMC的第二總線格式-SPI。由于MAXQ2000提供SPI硬件支持,連接非常容易。
圖1. MAXQ2000與SD存儲卡的接口非常簡單。
圖1的電路圖給出了一個典型應用電路。SD卡要求全雙工、8位SPI操作。數據從MAXQ2000的MOSI引腳同步輸入SD卡的DI引腳,并由SD卡的DO線同步輸入MAXQ2000的MISO引腳。數據在CLK信號的上升沿同步輸入和輸出。在每次數據傳輸的末尾還必須提供8個額外的時鐘,以允許SD完成任何未完結的操作。對應這些額外時鐘的輸入數據必須全為1。識別階段的時鐘頻率必須限定在400kHz以內,但SD卡一經識別后,時鐘頻率便可提高到25MHz。
MAXQ2000的SPI模塊
MAXQ2000包含一個硬件SPI模塊,可以方便地針對SD卡接口進行配置。為了配置時鐘極性和數據長度,需將SPICF寄存器置為全零。這種SPI模塊配置在時鐘的上升沿鎖存數據,并將數據長度設置為8位。對于本應用,MAXQ2000的系統時鐘頻率為16MHz。在這種情況下,需要將SPICK寄存器置為0x28,從而使SPI時鐘頻率接近380kHz。必須將SPICN寄存器的低2位置位,以使能SPI主機模式。SD SPI數據格式
SD卡的SPI協議與SD總線協議相似。如果一片SD卡沒有數據要發送,則將DO引腳保持在全1的空閑狀態,因此不是在每個時鐘沿都從SD卡的DO引腳接收有效數據。當SD卡有數據要回送給主機時,要在數據之前先發送一些以0為起始位的特定令牌。當這些令牌發送完畢之后,SD卡要發送的所有定長數據立即被發送出去。由于接收器事先已經知道要接收的字節數,因而響應中不包含表征長度的字節。此外,由于在起始令牌和數據都發送完畢后才會進入空閑狀態,所以全部數據字節都以不帶前綴的原始形式發送。和總線上其它所有通信過程一樣,令牌大小也要和SPI傳輸的8位邊界對齊。主機發送給SD卡的指令和數據都遵循類似的格式,以全1指示總線空閑。除了狀態令牌以外,所有傳輸都由附加在數據末尾的循環冗余校驗(CRC)碼進行保護。系統提供兩種CRC算法:CRC-7用于小數據塊,CRC-16則用于大數據塊。CRC是SD SPI接口的可選部分,但除非應用系統限制它的使用,否則應該使用CRC來確保數據的完整性。循環冗余校驗
CRC算法通常用于檢測由不可靠的通信通道引起的誤差。特定CRC類型的選擇根據需要保護的數據長度來決定。對于基于SD存儲介質的數據,采用CRC-7和CRC-16編碼方式。CRC算法將被保護的數據用選中的除數進行除法運算,產生一個余數。因為該算法中用得的是多項式,所以該除法運算不含進位邏輯。無需考慮進位時,除法運算可通過邏輯XOR操作來實現。所選中的除數通常用CRC的多項式來表示。接著,計算出的余數和數據一起傳輸,接收器用此余數來檢查確認數據在傳輸過程中是否正常。
對于CRC-7,余數可通過一個7位移位寄存器在軟件中計算。計算開始時,將該移位寄存器初始化置為全零。當受保護數據的每一位(MSB在先)被移入移位寄存器的LSB時,移出移位寄存器的MSB,并進行檢查。如果移出的位為1,則用CRC-7多項式系數0x09進行異或運算,以此來修正移位寄存器的內容。如果從移位寄存器中移出的位為0,則無需XOR操作。受保護數據的最后一位被移入移位寄存器且完成了條件XOR操作后,必須按此類似方式移入7個或更多0。這一過程稱作擴張并完成多項式除法運算。此時,CRC-7值可從移位寄存器直接讀出。
圖2. 通過移位寄存器架構計算CRC-7。
當接收器收到所有受保護的數據后,接收器可計算基于受保護數據的CRC-7值并將改值與接收到的CRC-7值進行比較。如果這兩個值不同,接收器就能判斷出受保護數據在傳輸過程中出現錯誤。如果這兩個值相同,則接收器可完全判定通信通道上的數據是完整的。
CRC-16算法可用同樣的方式來構建。在這種情況下,移位寄存器長度為16位而不是7位;多項式系數改為0x1021,且輸入數據通過16個0位來擴張。
SD命令格式
發送給SD卡的命令采用6字節的格式(圖3)。命令的第1個字節可通過將6位命令碼與16進制碼0x40進行或運算得到。如果命令需要,則在接下來的4個字節中提供一個32位的參數;最后1個字節包含了從第1個字節到第5個字節的CRC-7校驗和。表1列出了一些重要的SD命令。圖3. 發送給存儲卡的SPI模式SD命令采用6字節格式。
表1. 部分SD存儲卡命令
Command | Mnemonic | Argument | Reply | Description |
0 (0x00) | GO_IDLE_STATE | none | R1 | Resets the SD card. |
9 (0x09) | SEND_CSD | none | R1 | Sends card-specific data. |
10 (0x0a) | SEND_CID | none | R1 | Sends card identification. |
17 (0x11) | READ_SINGLE_BLOCK | address | R1 | Reads a block at byte address. |
24 (0x18) | WRITE_BLOCK | address | R1 | Writes a block at byte address. |
55 (0x37) | APP_CMD | none | R1 | Prefix for application command. |
59 (0x3b) | CRC_ON_OFF | Only Bit 0 | R1 | Argument sets CRC on (1) or off (0). |
41 (0x29) | SEND_OP_COND | none | R1 | Starts card initialization. |
將SD卡初始化為SPI模式
剛上電時,SD卡缺省使用專有的SD總線協議。為了將SD卡切換到SPI模式,主機應發出命令0 (GO_IDLE_STATE)。SD卡會檢測到SPI模式選擇信息,因為卡選擇(CS)引腳在該命令和其它所有SPI命令傳送過程中都保持為低電平。SD卡以R1響應(圖4)作為回應。空閑狀態位被置為高電平,表明SD卡已進入空閑狀態。為了保持與MMC卡的兼容性,此階段的SPI時鐘頻率一定不能超過400kHz。圖4. R1響應指示發出的命令是否成功執行。
SD卡進入SPI模式后,SD規范要求主機在進行其它任何請求之前先發送一條初始化命令。為了能區分MMC卡和SD卡,SD卡采用了一種不同的初始化命令,MMC卡對該命令是不響應的。先向卡發送命令55 (APP_CMD),緊接著再發送應用命令41 (SEND_OP_COND),這樣即完成了這個重要的步驟。MMC卡對命令55不做回應,通過這一點可鑒別出MMC卡,并將其視作無效介質而拒絕訪問。這個命令序列要一直重復執行,直到來自存儲卡的R1響應中所有位均為0 (也就是說,IDLE位變為低)才停止。
清單1. 代碼必須用SEND_OP_COND來識別SD和MMC卡。
SD卡包含了一些重要的寄存器,用來提供SD卡的相關信息。最重要的寄存器是存儲卡特定數據寄存器(CSD)。對于我們的應用示例而言,我們感興趣的是存儲器的數據塊大小和總容量。我們還必須對存儲卡標識數據寄存器(CID)加以注意,因為它包含了存儲卡的制造商詳細信息和序列號。圖5顯示了CSD寄存器和CID寄存器的配置結構。
圖5. CSD寄存器和CID寄存器提供SD卡的相關信息。
檢查SD卡的響應
要讀取存儲卡的寄存器或數據塊,我們首先必須理解存儲卡如何響應我們的請求。在SPI模式下,SD卡以R1應答SEND_CSD (9)、SEND_CID (10)和READ_SINGLE_BLOCK (17)命令。接著則是一個起始令牌,然后是所請求的數據,最后是數據的CRC-16校驗和。我們不能想當然地認為數據起始令牌是緊接著R1響應即刻發出的,因為總線在這兩個事件之間會進入空閑狀態一段時間。圖6顯示了數據響應的細節。圖6. 從SD卡到主機的數據傳輸要加入一個起始令牌作為前綴。
讀取CSD寄存器和CID寄存器的元數據
使用SEND_CSD和SEND_CID命令可返回寄存器的內容,以便確定SD卡的參數。這些命令分別返回與CSD或CID寄存器容量大小一致的固定數量的字節。SEND命令字節中包含的參數被SD卡忽略。從SD卡中讀取一個數據塊
從SD卡中讀取一個數據塊是相當簡單的。主機發出READ_SINGLE_BLOCK命令,并將起始字節地址作為參數。這個地址必須和介質上一個塊的起始位置對齊。然后SD卡會驗證這個字節地址,并以一個R1命令作為響應。如果命令中的地址越界,則會在命令響應中指示這種情況。如果完成了SD介質的讀取操作并且沒有錯誤發生,則先發送一個起始數據令牌,接著是固定數量的數據,最后是兩個字節的CRC-16校驗和。如果SD卡碰到硬件故障或介質讀取錯誤,則不會發送起始數據令牌。而是發送一個錯誤令牌,數據傳輸隨之中止。
向SD卡中寫入一個數據塊
寫入一個數據塊和讀取數據塊類似,即主機必須提供一個與SD卡數據塊邊界對齊的字節地址。寫入數據塊的大小必須與READ_BL_LEN相同,一般為512字節。通過發出WRITE_BLOCK (24)命令啟動寫操作過程,SD卡將以R1命令響應格式進行應答。如果命令響應表明寫操作可以進行,則主機發送數據起始令牌,接著是固定數量的數據字節,最后以發送數據的CRC-16校驗和結束。SD卡返回一個數據響應令牌以指示待寫入的數據是否被接受。如果數據被接受,SD卡會在存儲卡忙時始終將DO線保持為低電平。存儲卡忙期間,主機不必始終將卡選擇線保持為低電平,如果解除CS選擇狀態,SD卡將釋放DO線。當多于一個的設備與SPI總線連接時,上述處理方式非常有用。主機可以一直等待SD卡釋放忙指示標志,也可以定期觸發片選信號以檢查存儲卡的工作狀態。如果卡仍然處于忙狀態,它會將DO線拉低以指示該狀態。否則,存儲卡會使DO線返回至空閑狀態(見圖7)。
圖7. 從主機到SD卡的數據傳輸使用一套更為復雜的握手機制。
SPI命令與數據錯誤檢測
可利用CRC-7和CRC-16校驗來檢測主機與SD卡間的通信錯誤。如果因物理因素而導致錯誤發生,如在插入、移除時的觸點抖動,或是可拆卸介質固有的接觸不良狀況,錯誤檢測機制可實現堅固的錯誤恢復功能。我們強烈建議使用校驗和機制,這可以通過發出CRC_ON_OFF (59)命令并將參數的最低位置為高來啟動該功能。清單2. 強烈推薦使能CRC校驗和。
評論
查看更多