SDカードドライバ1
----STM8S200向けのサンプルプログラムをSTM8S105に移植する----
STMicroのライブラリのUtilityフォルダの中にSTM8Sの上位ラインナップであるSTM8S200向けのSDカードドライバのサンプルコードがあったので、それをSTM8S-DISCOVERYに実装してみました.
以下の実装では、SD cardのブロックREAD/WRITEだけできるようになっています.
したがってできないこと、未確認なことは、
●32MBのSD cardでしか試していない
●SD cardには電源電圧が何種類もあるらしいんだが、3.3V固定である
●FATのようなファイルシステムには対応していない
というわけで、512バイトブロックのREAD/WRITEだけですが、へ〜っ動くんだという確認までをやりましょう.
作る物の仕様
SD card
リセットSW
USBシリアル変換基板
PCのTerminaソフト画面にSD cardへのアクセス結果が出力される.
STM8Sの起動と同時にブロックアドレス0へブロックWRITE/READし、正常にWRITE/READできたかどうかを表示する.
基板写真
右下の14pin ピンヘッダはLCDを取り付けるためにつけたものなので、今回は無関係なので無視してください.
基板回路図
●リセットSWは必須です.写真のCN1に付いているプッシュSWがそれです.
なぜリセットSWが必要なのか?
USBをつないでTerminalソフトのCOM PORT接続を確立させてからSTM8Sを起動させなくてはいけないため、リセットSWが必要です.
●USBシリアル変換基板は、USB経由でCOM PORT接続するためです.
●SD card CNは、秋葉のマルツで買いました.
ヒロセの製品です.製品資料はここにあります. http://www.hirose.co.jp/catalogj_hp/j60900048.pdf
写真にあるように、ユニバーサル基板にコネクタをハンダづけしたドータ基板をつくり、STM8S-DISCOVERYのCN2にグサッと挿すようにしました.
SD card CNの近くの電源にコンデンサをつけました.
SD cardを挿した瞬間にSTM8Sにリセットがかかってしまったので、それを防止するためです.
今回製作する基板はUSBシリアル変換基板内蔵の3.3VをSTM8Sの電源として流用しているので、その3.3Vが弱いのかもしれません.
ハードウエアの製作
@USBシリアル変換回路
まず、UARTをUSBに変換する回路を、STM8S-DISCOVERYにどうやって取り付けるかを説明します.
秋月のUSBシリアル変換基板をSTM8S-DISCOVERYに取り付けます.
回路図は下記です.配線は上記回路図の4本です.
●STM8SのPD5とPD6には、UARTの送信信号と受信信号が出てきますので、それをUSBシリア ル基板に配線しています.
●STM8S-DISCOVERYでは、電源はFLASH焼き回路から5V or 3.3Vが供給されますが、これを切断し、USBシリアル変換基板から3.3Vが供給されるようにします.
ただし5Vじゃダメってことではありません.3.3Vにしたのはなんとなくです.
そのために、ジャンパーをつぎの1)2)のように設定 してください.
1) USBシリアル変換基板のジャンパーピンは、下図の赤色の位置にします.
2) STM8S-DISCOVERYのJP1のジャンパーピンは、外しておきます.
USBシリアル変換基板の取付完了状態はこのようになります.
右の黄色の囲いがUSBシリアル変換回路です.同基板に刺さっているMini-USBがPCのUSBへ行きます.
中央の水色の囲いがSTM8Sマイコンです.USBシリアル変換回路と配線されています.
左の赤い囲いは、ブロック図には描きませんでしたがSTM8Sを焼くために必須な回路です.同基板に刺さっているUSBケーブルは、STM8Sを焼くためのケーブルです.やはりPCに接続します.
この回路は、PCのUSBポートを都合2ヶ占有することになります.
プログラムを焼いてしまえば、焼き用のUSBケーブルは不要になるわけで、下図のようにUSBを外してしまいたくなるのが人情です.
ところが、USBケーブルを外しただけでは、STM8Sにリセットがかかってしまって動かなくなってしまいます.
そこで、下の写真の丸の中にあるSB1とSB2をハンダごてでOPENにしてやればリセット線が切断されるので、STM8Sが動きます.
この方法は憶えておきましょう.
AリセットSW
これは適当につけてください.
プルアップ抵抗は不要で、対GNDへ落とす形式でOKです.
BSD card CN
回路図のとおりに作ってください.
STM8S-DISCOVERYのCN2に挿すドータ基板状態に作るのがオススメです.
電源コンデンサはつけましょうね.私はしっかりとトラブりましたので.
ソースコードの解説
サンプルプログラムをこちらに置きます.
SD cardについてのSTMicro社のサンプルプログラムは、もともと STM8S-128-EVALという機能豊富な基板をターゲットとして作られたものでした.
それをSTM8S-DISCOVERY用にわたしが移植しました.
なので、いろいろとソースコードを削除しました.
PORT宣言のところは変更した箇所の一つです.
stm8_128_eval.hというファイルに次の記述があり、ここでSPIポートがGPIOのどこに接続されているかを設定しています.
SD_SPI_......とSD_CS_.....はSPIのpinがSTM8Sのハードウエア的に決まっているので、変更のしようがありません.
ただし、SD cardの有無を検知する SD_DETECT_....は任意のpinにアサインできますので、ここではPG0にアサインしました.
#define
SD_SPI_SCK_GPIO_PORT
GPIOC //
GPIOC
#define
SD_SPI_SCK_PIN
GPIO_PIN_5 // PC5
#define SD_SPI_MISO_GPIO_PORT GPIOC // GPIOC
#define
SD_SPI_MISO_PIN
GPIO_PIN_7 // PC7
#define SD_SPI_MOSI_GPIO_PORT GPIOC // GPIOC
#define
SD_SPI_MOSI_PIN
GPIO_PIN_6 // PC6
#define
SD_CS_GPIO_PORT
GPIOE //
GPIOE
#define
SD_CS_PIN
GPIO_PIN_5 // PE5
#define
SD_DETECT_GPIO_PORT
GPIOG //
GPIOG
#define
SD_DETECT_PIN
GPIO_PIN_0 // PG0
main()を除いてあまり中身を理解していませんので、main.cだけ解説します.
●#include "stdio.h"
#include "stdlib.h"
C言語の標準関数をインクルード
●#include "stm8s.h"
ライブラリをインクルード
●#include "usrlib-uart.h"
UARTを使うための自作ルーチンをインクルード
●#include "stm8s_eval_spi_sd.h"
SD cardをつかう関数をインクルード
●uint8_t TxBuffer[] = "communication with a microSD card";
この文字列を、SD cardにWRITEします.
●void TIM3_UPD_OVF_BRK_IRQHandler(void) interrupt 15 {
GPIO_WriteReverse(GPIOD, GPIO_PIN_0); // LED flashing
TIM3_ClearFlag(TIM3_FLAG_UPDATE); }
インジケータとしてLEDを点滅させるのそのタイマーです.
●void main(void)
メイン関数の始まり
●@CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
ACLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1 );
BCLK_SYSCLKConfig( CLK_PRESCALER_CPUDIV1 );
@内部クロックの16MHzをつかうように設定します.
Aは16MHzを1分周して(=分周せずに)fMASTER=16MHzに設定します.fMASTERはタイマに供給されます.
BはfMASTERを1分周して(=分周せずに)fCPU=16MHzに設定します.fCPUはCPUに供給されます.
●UART2_DeInit();
UART2_Init((u32)115200,
UART2_WORDLENGTH_9D, UART2_STOPBITS_1, UART2_PARITY_ODD,
UART2_SYNCMODE_CLOCK_DISABLE,
UART2_MODE_TXRX_ENABLE);
UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
UART2_Cmd(ENABLE);
UARTを使うので、その初期化です.
●GPIO_Init(GPIOD, 0b00000001, GPIO_MODE_OUT_PP_HIGH_FAST);
TIM3_DeInit();
TIM3_TimeBaseInit( TIM3_PRESCALER_1024, 7812 );
TIM3_ITConfig(TIM3_IT_UPDATE, ENABLE);
TIM3_Cmd(ENABLE);
インジケータとしてPD0に接続されているLEDを点滅させるための設定です.
●enableInterrupts();
割り込みを許可します.
●GPIO_Init(SD_DETECT_GPIO_PORT, SD_DETECT_PIN, GPIO_MODE_IN_PU_NO_IT);
ヒロセのSD card CNには、下図のように、カードを検出するSWと、ライトプロテクト(WP)を検出するSWの2つがあります.
ここではWPは無視して、SD cardの有無をチェックするポートをpull-up入力ポートに設定しています.
●while (1) {
if(SD_Detect()==SD_NOT_PRESENT) SerialPutString("wait SD card\r\n");
else break; }
SerialPutString("SD card interted\r\n");
SD cardが挿入されるまで、wait SD cardと表示しつつwaitします.
SD cardが挿入されたら、SD card insertedと表示します.
●Status = SD_Init();
SD cardを使うためにSTM8SのSPIインターフェースを設定します.
1ブロックを512バイトに設定するのもこの中でやってます.
●SD_WriteBlock(TxBuffer, 0, BUFFER_SIZE);
SD cardにブロックWRITEします.
TxbufferがWRITEする文字列.
0がブロックアドレス.
BUFFER_SIZEが文字列の文字数.
●SerialPutString("SD WRITE STRING: ");
SerialPutString(TxBuffer);
SerialPutString("\r\n");
WRITEした文字列をTerminal画面に表示
●SD_ReadBlock(RxBuffer, 0, BUFFER_SIZE);
SD cardから1ブロックREADします.
同じ場所をREADしているので、同じ文字列が読み出されるはずです.
●SerialPutString("SD READ STRING: ");
SerialPutString(RxBuffer);
SerialPutString("\r\n");
READした文字列をTermina画面に表示
●TransferStatus = Buffercmp(TxBuffer, RxBuffer, BUFFER_SIZE);
if (TransferStatus == SUCCESS) SerialPutString("SD card read write OK\r\n");
else if (TransferStatus != SUCCESS) SerialPutString("SD card read write NG\r\n");
WRITE文字列とREAD文字列を比較します.
OKかNGを表示します.
実行結果
●SD cardを挿してからSTM8S-DISCOVERYをリセットすると、Terminal画面にこのように表示されます.
start SD card IF test
SD card interted
SD WRITE STRING: communication with a microSD card
SD READ STRING: communication with a microSD card
SD card read write OK
●SD cardを挿さずにSTM8S-DISCOVERYをリセットすると、Terminal画面にこのように表示されます.
start SD card IF test
wait SD card
wait SD card
wait SD card
wait SD card
wait SD card ←挿入されるまでダーッと表示がスクロールしつづけます
wait SD card
wait SD card
wait SD card
wait SD card
SD card interted
SD WRITE STRING: communication with a microSD card
SD READ STRING: communication with a microSD card
SD card read write OK
●空のSD cardを挿してからSTM8S-DISCOVERYをリセットすると、Terminal画面にNGと表示されます.
start SD card IF test
SD card interted
SD WRITE STRING: communication with a microSD card
SD READ STRING:
SD card read write NG
------
次は、FATを実装してみたいと思います.
STM8S-DISCOVERYがSD cardにlogを記録して、それをPCでtextとして簡単に読めるようにしたいです.