×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
STM32F030F4P6でLCD表示を行いました。
LCDは1602規格のもので、市場に安価に大量に出回っているので、供給についての不安は無用だと思います。
/*
** Main.c
** LCD1602
** EmBitz
**
** A1-Input ボタン
** A2-Output RS
** A3-Output E
** A4-Output D4
** A5-Output D5
** A6-Output D6
** A7-Output D7
**
** 空のprojectを作成し、設定をhexファイルが取得できるように変更して、
** main.cにこの文章をcopy&pasteして、コンパイルすれば完成です
**
**********************************************************************/
/*
Last committed: $Revision: 16 $
Last changed by: $Author: Masaomi.Takahashi.$
Last changed date: $Date: 2019-08-09
ID: $Id: 0002$
**********************************************************************/
#include "stm32f0xx.h"
int main(void)
{
RCC ->AHBENR |= (1<<17); // GPIO-Aの初期化(最初は0クロックで無可動状態)
GPIOA -> IDR |= (1<<2); // ピン A - 1 を入力モードに
GPIOA -> PUPDR |= (1<<2); // ピン A - 1 を プルアップ指定
GPIOA -> MODER |= (1<<4); // ピン A - 2 を出力モードに lcd-Rs
GPIOA -> MODER |= (1<<6); // ピン A - 3 を出力モードに lcd-E
GPIOA -> MODER |= (1<<8); // ピン A - 4 を出力モードに lcd-D4
GPIOA -> MODER |= (1<<10); // ピン A - 5 を出力モードに lcd-D5
GPIOA -> MODER |= (1<<12); // ピン A - 6 を出力モードに lcd-D6
GPIOA -> MODER |= (1<<14); // ピン A - 7 を出力モードに lcd-D7
lcd_init(); // lcd初期設定
lcd_clear(); // 全消去
lcd_put_str("STM32F030F4P6");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("Make By EmBitz");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("Vol.1.03");
delay_ms(2500);
lcd_clear(); // 全消去
lcd_put_str("ワレワレハシンリャクシャダ ト");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("イッテミル TEST");
delay_ms(7000);
while(1){
if(!(GPIOA->IDR & GPIO_IDR_1)){
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("ワレワレテキニハ コノワクセイヲ");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("シハイカニオク ヨテイデアル");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("タダシ イカノ");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("アンゴウ ヲ");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("カイドクデキタラ ");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("カンベンシテヤル");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("1899190119251968");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("1975197919922011");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("20192027");
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("ヒント ハ - ワクセイ -");
delay_ms(7500);
lcd_clear(); // 全消去
lcd_put_str("ドウカ・・・"); // "ドウカ・・・"表示
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("セカイガヘイワデスヨウニ");
delay_ms(7000);
} else {
delay_ms(500);
lcd_clear(); // 全消去
lcd_put_str("Hello World!!"); // "Hello World!!"表示
lcd_position(0,1); // カーソル位置 桁0,行1
lcd_put_str("コンニチハ セカイ!!");
} } }
//---------- 文字列出力 ----------
// *str:文字列の先頭ポインタ
void lcd_put_str(char *str)
{
while(*str != 0){
lcd_put_ch( *str );
str++;
}
}
//---------- LCD初期化 ----------
void lcd_init()
{
delay_ms(30);
lcd_put_4bit(0x30, 1); //8bit mode set
delay_ms(5);
lcd_put_4bit(0x30, 1); //8bit mode set
delay_ms(1);
lcd_put_4bit(0x30, 1); //8bit mode set
delay_ms(1);
lcd_put_4bit(0x20, 1); //4bit mode set
delay_ms(1);
lcd_put_cmd(0x2E); //DL=0 4bit mode
lcd_put_cmd(0x08); //display off C=D=B=0
lcd_put_cmd(0x0D); //display on C=D=1 B=0
lcd_put_cmd(0x06); //entry I/D=1 S=0
lcd_put_cmd(0x02); //cursor home
}
//---------- 表示位置設定 ----------
// tx:x座標 ty:y座標
void lcd_position(char tx, char ty)
{
GPIOA ->ODR &= ~(1<<2); //GPIOA-Pin4をOffにする(コマンドデータ)
lcd_put_cmd(0x80 | tx | (0x40 * ty));
GPIOA ->ODR |= (1<<2); //GPIOA-Pin2をOnにする(表示データ)
}
//---------- データ4bit出力 ----------
// code:DB4~DB7 に与えるデータ
// flag:0=表示モード 1=コマンドモード
void lcd_put_4bit(char code, int flag)
{
if(code & 0x80)
GPIOA ->ODR |= (1<<7); //GPIOA-Pin7をOnにする
else
GPIOA ->ODR &= ~(1<<7); //GPIOA-Pin7をOffにする
if(code & 0x40)
GPIOA ->ODR |= (1<<6); //GPIOA-Pin6をOnにする
else
GPIOA ->ODR &= ~(1<<6); //GPIOA-Pin6をOffにする
if(code & 0x20)
GPIOA ->ODR |= (1<<5); //GPIOA-Pin5をOnにする
else
GPIOA ->ODR &= ~(1<<5); //GPIOA-Pin5をOffにする
if(code & 0x10)
GPIOA ->ODR |= (1<<4); //GPIOA-Pin4をOnにする
else
GPIOA ->ODR &= ~(1<<4); //GPIOA-Pin4をOffにする
if (flag == 0)
GPIOA ->ODR |= (1<<2); //GPIOA-Pin2をOnにする(表示データ)
else
GPIOA ->ODR &= ~(1<<2); //GPIOA-Pin2をOffにする(コマンドデータ)
delay_us(1);
GPIOA ->ODR |= (1<<3); //GPIOA-Pin3をOnにする
delay_us(2);
GPIOA ->ODR &= ~(1<<3); //GPIOA-Pin3をOffにする
}
//---------- 1文字出力 ----------
// ch:出力するデータ
void lcd_put_ch(char ch)
{
lcd_put_4bit(ch, 0); //上位4bit出力
lcd_put_4bit(ch<<4, 0); //下位4bit出力
delay_us(50);
}
//---------- コマンド出力 ----------
// cmd:コマンド
void lcd_put_cmd(char cmd)
{
lcd_put_4bit(cmd, 1); //上位4bit出力
lcd_put_4bit(cmd<<4, 1);//下位4bit出力
delay_ms(2); //2msec待ち
}
//---------- 全消去 ----------
void lcd_clear()
{
lcd_put_cmd(0x01); //初期化コマンド出力
delay_ms(15); //15msec待ち
}
void delay_ms(uint32_t i)
{
i=i*100;
while(i>0){
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
i--;
} }
void delay_us(uint32_t i)
{
while(i>0){
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
i--;
} }
以上をEmBitzで新規に作成したProjectのmain.cにまるごとコピペして、コンパイルすれば(ライブラリ等を新たに設定しなくても)動きます。
注意点は、LCDのEとRS端子の間にあるRW端子をGNDに繋げてやらないとダメ、という点です。
これが判らなくて、私は延々とドツボにはまり続けました。
なお、プログラムの主要部分は、
ohkinというブログの、
STM32と Arduino IDE で
液晶ディスプレイに文字表示(その1)
~ライブラリ未使用~
という記事を参考(丸パクリ)にさせていただきました。なお、delayに関しては、完全に「適当」です。一切計測とかしてません。カンです。動いたから、そのままにしているだけです。他のプログラムにこれを流用して、そのままタイミングをとるとか無茶なことをされても、一切責任は負いません。
あと、割り込みとかしてないので、delay中にボタンを押しても反応しません。ので、次の処理へ移行させるためには、延々とボタンを押し続ける必要があります。
ちなみに、このプログラムによって使用される容量は4.5KBぐらい。
STM32F030F4P6のメモリは16KBだから、メインの処理を他に作って、こちら(ディスプレイ表示)を隠しモードとして潜ませておく、なんて事も可能ではないかと思います。
STM32F030F4P6はものすごく安くて高性能なので、もっと使いこなせるようになりたいです。
PR
コメント