マイコン入門spacer ad
トップページに戻る(マイコン徹底入門:STM32で始めるARM/Cortex-M3組み込み開発)
「マイコン徹底入門」とは? |  「マイコン徹底入門」を読む |  ダウンロード |  掲示板 |  筆者の自己紹介


Previous: 2.3.4.1. GPIO初期化関数

Up: 2.3.4. 実験のためのサンプルプログラム

Next: 2.3.4.3. 書き込み用関数


マイコン徹底入門:周辺回路編:STM32のペリフェラルを活用: 2. 汎用入出力(GPIO): 2.3. キャラクタ液晶の利用: 2.3.4. 実験のためのサンプルプログラム:

2.3.4.2. 読み込み用関数

 LCDモジュールからの命令の読み取り用にLCD_Read_Inst関数、データの読み取り用にLCD_Read_Data関数を作成しました。HD44780の場合、命令の読み取りもデータの読み取りも、RSピンのレベルが違うだけで、その後の処理は同じですので、共通部分をLCD_Read_Core関数としてまとめています。これらの関数を実行することによりLCDモジュールが出力する命令・データが戻り値として得られます。

uint8_t LCD_Read_Inst(void)

{

? //RS=0: Instruction

? GPIO_ResetBits(GPIOY_0_PORT, GPIOY_0_PIN);

 

??return(LCD_Read_Core());

}

uint8_t LCD_Read_Data(void)

{

? //RS=1: Data

? GPIO_SetBits(GPIOY_0_PORT, GPIOY_0_PIN);

 

? return(LCD_Read_Core());

}

 読み込み処理はHD44780が規定するタイミングと順番に従って出力ピンの処理、データの読み取りを行っていきます。

uint8_t LCD_Read_Core(void)

{

? uint8_t ReadData;

 

? //RW=1: Read (Output from LCD)

? GPIO_SetBits(GPIOY_1_PORT, GPIOY_1_PIN);

? //Wait: Setup time: tAS(40) : 40ns : 3 clocks

? WAIT_3_CLOCK;

? //Set GPIO as input

? GPIO_In_Configuration();

? //E=1:Enable

? GPIO_SetBits(GPIOY_2_PORT, GPIOY_2_PIN);

? //Wait: Pulse time: PWEH(220) : 220ns : 18 clocks

? WAIT_18_CLOCK;

? //Read data from GPIO

? ReadData =(uint8_t)GPIO_ReadInputData(GPIOX_PORT);

? //E=0:Disable

? GPIO_ResetBits(GPIOY_2_PORT, GPIOY_2_PIN);

? //Wait: Pulse holdtime: tH(10) : 10ns

? //should be passed during commands

? //RW=0: Write (Output to LCD)

? GPIO_ResetBits(GPIOY_1_PORT, GPIOY_1_PIN);

? //Wait: tC(500) - PWEH(220) - tH(10) - tAS(40) : 230ns : 18 clocks

? WAIT_18_CLOCK;

? return(ReadData);

}

 RWを設定したあとの「WAIT_3_CLOCK;」はマクロであり、

__asm__(“mov r8,r8\n\tmov r8,r8\n\tmov r8,r8\n\t”)

に置換されます。

 「__asm__(“x”)」はインラインアセンブラです。インラインアセンブラを使用すると、C言語のソースコードの中に直接アセンブリ言語を書き込むことができます。STM32の場合、アセンブリ言語を使用しなくてもプログラミングは十分に可能です。ただ40ns(ナノセコンド:1ナノセコンドは1,000,000分の1)のようなごく短い時間だけ待つという場合には、時間待ち関数を呼び出すだけで、もっと長い時間が経過してしまいます。そこで3クロック分(42ns)だけ無駄な処理をすることで時間待ちをさせることにしました。「mov a,b」はレジスタaの内容をレジスタbにコピーするというアセンブラ命令です。「mov r8,r8」はレジスタr8の内容をレジスタr8にコピーすることになりますので、意味のない処理ということになります。

 ちなみに3クロックであれば、その前後の関数の実行中に経過してしまっている可能性が高く、あえて待ち処理をする必要も無いのですがここでは確実を期するために待ち処理を挿入しました。

 「WAIT_18_CLOCK;」は同じ要領のマクロで、こちらは18クロック分無駄な処理を行っています。

 インラインアセンブラは便利なのですが、gcc以外のコンパイラを使用する場合に互換性が無くなる場合がありますので注意して下さい。


Previous: 2.3.4.1. GPIO初期化関数

Up: 2.3.4. 実験のためのサンプルプログラム

Next: 2.3.4.3. 書き込み用関数


このページはITと知的財産の法律情報「法務ネット」の管理人が制作・運営しています。
_Toc266801166