STM32 F401RE LCDモジュール
開発環境
・評価ボード NUCLEO-F401RE
・IDE MDK-ARM V5 and STM32CubeMX
・OS windows 10 pro
・本
定番!ARMキット&PIC用Cプログラムでいきなりマイコン制御[DVD-ROM付き] (マイコン活用シリーズ)
- 作者:芹井 滋喜
- 発売日: 2016/01/29
- メディア: 単行本
LCDモジュールを動かしていきたいと思います。
LCDのコントローラにルネサスのHD44780の互換品ICを搭載した
LCDキャラクタディスプレイモジュール 16×2行 バックライト付白抜き: ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
を今回は使用していきます。
よくあるE,RS,R/WとDB0~7の内のDB0~3の4bitを使用して駆動するあれです。
まずはSTM32CubeMXの設定を行います。
ピンアサインは
E: PC0
RS: PC1
DB4: PB4
DB5: PB5
DB6: PB6
DB7: PB7
としました。
ソースの詳しい解説はおいておいて、lcd.hとlcd.cをApplication/Userフォルダに追加します。
(フォルダを選択して、右クリック→Add New Item to Group '~'→Type C or H file→Nameを変更→LocationをC:\WorkSpace\MDKARM\F401RE_LCD_00\Src\に変更)
・lcd.h
#ifndef _LCD_H_ #define _LCD_H_ /*=============================================================== 関数名: LcdCls 機能: LCDの表示をクリアする ===============================================================*/ extern void LcdCls(void); /*=============================================================== 関数名: LcdDisplayMode 機能: LCDの表示モードを設定する disp: LCD全体の表示のON/OFF cursor: カーソル表示のON/OFF blink: カーソル位置の文字のブリンクのON/OFF ===============================================================*/ extern void LcdDisplayMode(char disp, char cursor, char blink); /*=============================================================== 関数名: LcdInit 機能: LCDの初期化. 起動時に一回だけ呼び出す. ===============================================================*/ extern void LcdInit(void); /*=============================================================== 関数名: LcdPutc 機能: 現在設定されているLCDのDDRAMアドレスへ1文字出力する. ===============================================================*/ extern void LcdPuts(char *str); /*=============================================================== 関数名: LcdXy 機能: 引数 x, y で示された位置へ文字列sを表示する. ===============================================================*/ extern void LcdXy(char x, char y); #endif /*end of #ifndef _LCD_H_*/
・lcd.c
#include "lcd.h" #include "stm32f4xx_hal.h" #define CMD 0 #define DAT 1 #define ON 1 #define OFF 0 #define IN 1 #define OUT 0 // LCD Control(ハードウェア依存部) #define E_PORT GPIOC #define E_PIN (1<<0) #define RS_PORT GPIOC #define RS_PIN (1<<1) void LCD_RW(char act); void LCD_E(char act); void LCD_RS(char act); void LCD_OUT(int dat); void LCD_RW(char act) { // RW = L } void LCD_E(char act) { if(act){ HAL_GPIO_WritePin(E_PORT, E_PIN, GPIO_PIN_SET); }else{ HAL_GPIO_WritePin(E_PORT, E_PIN, GPIO_PIN_RESET); } } void LCD_RS(char act) { if(act){ HAL_GPIO_WritePin(RS_PORT, RS_PIN, GPIO_PIN_SET); }else{ HAL_GPIO_WritePin(RS_PORT, RS_PIN, GPIO_PIN_RESET); } } void LCD_OUT(int dat) { int pin; pin = dat & 0x0f0; HAL_GPIO_WritePin(GPIOB, pin, GPIO_PIN_SET); pin = (~pin) & 0x0f0; HAL_GPIO_WritePin(GPIOB, pin, GPIO_PIN_RESET); } void lcd_write8(char reg, char dat); void lcd_write(char reg, char dat); // 8bit mode write void lcd_write8(char reg, char dat) { LCD_RS(reg); LCD_OUT(dat); LCD_E(ON); HAL_Delay(1); LCD_E(OFF); HAL_Delay(2); } // 4bit mode write void lcd_write(char reg, char dat) { LCD_RS(reg); LCD_OUT(dat); LCD_E(ON); HAL_Delay(1); LCD_E(OFF); dat<<=4; LCD_OUT(dat); LCD_E(ON); HAL_Delay(1); LCD_E(OFF); } void LcdCls() { lcd_write(CMD, 1); } void LcdDisplayMode(char disp, char cursor, char blink) { char mode = 0x08; if(disp) mode |= 0x04; if(cursor) mode |= 0x02; if(blink) mode |= 0x01; lcd_write(CMD, mode); } void LcdInit() { // LCDの初期化 LCD_RW(OUT); HAL_Delay(30); lcd_write8(CMD, 0x30); // Function 8bit HAL_Delay(5); lcd_write8(CMD, 0x30); // Function 8bit HAL_Delay(5); lcd_write8(CMD, 0x30); // Function 8bit HAL_Delay(5); lcd_write8(CMD, 0x20); // Function 4bit HAL_Delay(5); lcd_write8(CMD, 0x20); // Function 4bit HAL_Delay(5); lcd_write8(CMD, 0x20); // Function 4bit HAL_Delay(5); LcdDisplayMode(0, 0, 0); HAL_Delay(5); LcdCls(); HAL_Delay(5); lcd_write(CMD, 0x06); // Entry Mode Set HAL_Delay(40); LcdDisplayMode(1, 1, 1); HAL_Delay(5); } void LcdPutc(char c) { lcd_write(DAT, c); } void LcdPuts(char *str) { while(*str){ LcdPutc(*str); str++; } } void LcdXy(char x, char y) { unsigned char adr; adr = (x+(y%2)*0x40) | 0x80; lcd_write(CMD, adr); HAL_Delay(10); }
・main.c
/* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" #include "lcd.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); void Error_Handler(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ void HAL_Delay_s(int sec) { while(sec){ HAL_Delay(1000); sec--; } } /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ LcdInit(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_Delay_s(1); LcdPuts((char *)"NUCLEO F401RE"); HAL_Delay_s(1); LcdCls(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
としました。
実行結果がこちら。(LcdXyにバグがあるような・・・)