こんばんわ
としぶぅ~です。
今日は昨日のつづきで、温度表示用のソースコード”lcd_f88.c”を貼り付けて、
少しだけ解説入れます。
大したことやっていないので解説といっても・・・・って感じですが^^;
後、この”lcd_f88.c”ですが、SC1602を使用する場合、他のマイコンでもちょっと
した修正だけで使えると思います。(以前NXPのARM(32bit)で修正して使いました。)
とりあえずソースを添付します。
lcd_f88.c
//*
//* LCD(SC1602) interface file(pic16f88 board)
//*
//* 以下の機能を供給する
//* lcd_cmd(unsigned char) LCDにコマンドデータを出力する
//* lcd_data(unsigned char) LCDに表示データを出力する
//* lcd_clear(void) 画面をクリアする
//* lcd_puts("ABCD・・・HJ") 文字列を表示する
//* lcd_posyx(y,x) カーソル位置を、行 y、横位置 xにする
//* lcd_init(void) LCDの初期化をする
//*
//*
//* LCD_RS PORTA, 7 ;RS信号
//* LCD_E PORTA, 6 ;E信号
//* LCD_DB PORTA ;DB6-4:PORTA 2-0(上位4ビット)
//* LCD_DB PORTB ;DB7:PORTB 3
//*
#include
#include "delay.h"
#include "lcd_f88.h"
#include "ad.h"
#define LCD_RS RA7
#define LCD_EN RA6
// write a byte to the LCD in 4 bit mode
void lcd_cmd(unsigned char c)
{
unsigned char cdata;
unsigned char cdataA;
cdataA = (c >> 4) & 0x0f;
PORTB = (cdataA & 0x08) | (PORTB & 0xf7);
// Making MSB Command Data 4bit
cdata = (cdataA | (PORTA & 0x70 & 0xb0));
PORTA = cdata; // RS = "H"→”L"
PORTA = cdata | 0x40; // E = "H"→”L"
PORTA = cdata;
cdataA = (c & 0x0f);
PORTB = (cdataA & 0x08) | (PORTB & 0xf7);
// Making LSB Command Data 4bit
cdata = cdataA | (PORTA & 0x70 & 0xb0);
PORTA = cdata; // RS = "H"→”L"
PORTA = cdata | 0x40; // E = "H"→”L"
PORTA = cdata;
DelayMs(5);
}
// write one character to the LCD
void lcd_data(unsigned char c)
{
unsigned char cdata;
unsigned char cdataA;
cdataA = (c >> 4) & 0x0f;
PORTB = (cdataA & 0x08) | (PORTB & 0xf7);
// Making MSB Data 4bit
cdata = cdataA | (PORTA & 0xf0) | 0x80;
PORTA = cdata; // RS = "L"→”H"
PORTA = cdata | 0x40; // E = "H"→”L"
PORTA = cdata;
cdataA = (c & 0x0f);
PORTB = (cdataA & 0x08) | (PORTB & 0xf7);
// Making LSB Data 4bit
cdata = cdataA | (PORTA & 0xf0) | 0x80;
PORTA = cdata; // RS = "L"→”H"
PORTA = cdata | 0x40; // E = "H"→”L"
PORTA = cdata;
DelayMs(5);
}
// Clear and home the LCD
void lcd_clear(void)
{
lcd_cmd(0x1);
DelayMs(5);
}
// write a string of chars to the LCD
void lcd_puts(const char * s)
{
while(*s)
lcd_data(*s++);
}
// Go to the specified position
void lcd_posyx(unsigned char ypos,unsigned char xpos)
{
unsigned char pcode;
switch(ypos & 0x03){
case 0: pcode=0x80;
break;
case 1: pcode=0xC0;
break;
case 2: pcode=0x94;
break;
case 3: pcode=0xD4;
break;
}
lcd_cmd(pcode += xpos);
}
// initialise the LCD - put into 4 bit mode
void lcd_init(void)
{
// Initalize コマンドを2~3回書き込まないとうまく動かない(2Lineモードにならなかった))
lcd_cmd(0x2c); // 4 bit mode, 2-LineMode, 5x8 font
DelayUs(40);
lcd_cmd(0x2c); // 4 bit mode, 2-LineMode, 5x8 font
DelayUs(40);
lcd_cmd(0x0c); // display on, blink curson on
DelayUs(40);
lcd_clear(); // display off
DelayMs(2);
lcd_cmd(0x06); // entry mode
}
void disp_ad()
{
unsigned char ad_fugou;
unsigned char ad_10;
unsigned char ad_1;
unsigned char ad_temp;
if(ad_disp == 1){
ad_disp = 0; /* display flag clear */
// 温度表示の計算
if((ad_data_old >= 0x5c) & (ad_data_old
ad_fugou = 0x20;
ad_10 = 0x20;
ad_1 = 0x30;
}else {
if(ad_data_old > 0x5d){
ad_fugou = 0x2b;
ad_temp = (ad_data_old - 0x5d) >> 1;
ad_10 = ad_temp / 10;
ad_1 = ad_temp - ad_10 * 10;
}else{
ad_fugou = 0x2d;
ad_temp = 1-((ad_data_old - 0x5c) >> 1);
ad_10 = ad_temp / 10;
ad_1 = ad_temp - ad_10 * 10;
}
}
// アスキー変換
if(ad_10
ad_10 = ad_10 | 0x30;
}else ad_10 = (ad_10-0x09) | 0x40;
if(ad_1
ad_1 = ad_1 | 0x30;
}else ad_1 = (ad_1-0x09) | 0x40;
// LCDへの温度表示
lcd_posyx(1,0);
lcd_data(ad_fugou);
lcd_posyx(1,1);
lcd_data(ad_10);
lcd_posyx(1,2);
lcd_data(ad_1);
}
}
以前貼り付けたソースコードに、disp_ad()関数を追加したものです。(マーカー部分)
追加部分の説明を少ししておきます。
まず、ADのデータが前回と違っていて表示書き換えが必要かを確認する。
→ ad_disp変数が”1”であれば書き換えが必要
”0”であれば、書き換えの必要がなく何もせずにこの関数から抜ける
次に、温度表示の計算を行います。
→ その16を参照ください。
その16で検討した計算式をそのまま実行しています。
私のプログラムはちょっとわかりにくいかもしれませんが・・・・すみません^^;
計算したデータを表示用の10ケタ目と1ケタ目のデータに分けます。
最後に、10ケタ目と1ケタ目のデータをアスキー変換しています。
10ケタ目に”0”があるときの処理は忘れていました^^;
でも、”+”と”-”の表示はちゃんと処理しました。
最後の数行は、LCDのどこに何を表示するのかを決めています。
こんな感じですね。。。わかりますかね?
私はアセンブラ言語からC言語に移ってきたので割と細かいことやってしまいます。
もう少し上手にプログラムが書ければいいのですが・・・・
ま、これからお勉強です(笑)
さて今日WEBを見ていたら、10bitのADやっている記事あったので見てみました。
Cで書くと8bitマイコンでも簡単にやれそうな気がしました。。。ちょっとチャレンジします。
とりあえず明日は、AD部分貼り付けます。(解説も・・・・)
そのあとに10bitでの温度計やってみますね(^^
それでは今日はこの辺で
お休みなさ~い(^^/