pic16f886 bme280 sensor v002 温湿度気圧センサー LCD

他力本願C言語シリーズ、そろそろ終わりです
今回も秋月電子販売の部品を使いました
温湿度気圧センサーAE-BME280 です I2C BUS で動きます
これですがC言語でも大変複雑なのでアセンブラでは一体
どのくらいの時間が掛かるか、あぁ想像したくない・・・。

bandicam 2019-02-06 11-20-25-583

今回もネット検索で見つかった製作記事のコピーです、こちらのブログ
趣味を楽しむ Enjoy your hobbyさんの記事からのコピーです
そっくりそのままでは無いです、CPUが違う、LCDが違う、などで
その部分は改造しています、初日は全く画面が出ないもののセンサーは
動いている、つまりアクセスして居る様子がオシロスコープで判った
のであとはLCD表示が出来れば良いわけです、初日に全く表示しなかった
理由は
・LCDが違う
・レジスタ・アドレスが違う
等から過去の製作プログラムを引っぱってきて追加しアドレス変更
したらアッサリと動いて仕舞いました、様々な計算、補正等が行われ
て居ますのでこれを理解するには相当な時間が掛かることでしょう
ただ、出来たものの精度は一切保証無しです、そこそこ出ていると
思えば宜しいでしょう。

回路図、センサー部分
3.3V電源なのでレベル・シフトのI2C bus buffer が必要です
これ、どっちが5Vかは決まってない様子ですググってみると
両方5Vのパターンがありました
bandicam 2019-02-06 12-19-59-813

回路図LCD部分
bandicam 2019-02-06 12-20-25-583

回路図CPU部分
bandicam 2019-02-06 12-22-16-009

ソースファイル
//============================================================================
// BME280気候センサーとLCD表示器を使用した温湿度気圧計測表示器
//============================================================================
//
// BME280データ処理部分は「SWITCHSCIENCE」さんのサイトから
// 使用させていただきました
//============================================================================
//  pic16f886 I2C bme280 sensor v002 2019/02/06(水) modified by maru
// データ処理の100%部分は「趣味を楽しむ Enjoy your hobby」さんのサイトから
// 使用させていただきました、LCDとPIC内部発振、キャラクタなど改造
//------------------------
// 初期設定
//------------------------
#include 
#include 
#include 
#include 
#pragma config FOSC = HS //高速オシレーター(4MHz以上)使用
#pragma config WDTE = OFF //ウォッチドッグタイマーOFF
#pragma config CP = OFF //コードプロテクションOFF
#pragma config PWRTE = ON //パワーアップタイマーON
#pragma config LVP = OFF//
//PICのクロック設定
#define _XTAL_FREQ 8000000 //PICのクロックをHzで設定(8MHz)
//モニター確認用LED
#define RED_led             RA0         //Red LED
#define YELLOW_led          RA1         //Yelloe LED
#define GREEN1_led          RA2         //Green LED1
#define GREEN2_led          RA3         //Green LED2
#define I2C_SCL             RC3         //I2c SCL (clock)
#define I2C_SDA             RC4         //I2c SDA (data)
#define RS232_TX            RC6         //RS232 TX
#define RS232_RX            RC7         //RS232 RX
//--------------------------------------------------------
// 関数定義エリア
// i2c 基本入出力関数
//--------------------------------------------------------
void i2c_CONF(void); //i2c初期設定
void i2c_START(void); //スタートコンディション発行
void i2c_ReSTART(void); //再スタートコンディション発行
void i2c_STOP(void); //ストップコンディション発行
void i2c_WRITE(unsigned char); //1バイト書き込み
unsigned char i2c_READ(void); //1バイト読み込み
unsigned char i2c_READC(void); //1バイト連続読み込み
//---------------------------------------------------------
// LCS表示制御コマンド
//---------------------------------------------------------
void LCD_init(void); //LCDの初期設定
void LCD_Init2(); //maru
void LCD_Clear(int); //LCDクリア(0=全面、1=1行目、2=2行目)
void LCD_puts(const char *p); //LCDへ連続文字表示
void LCD_Locate(unsigned char, unsigned char); //文字表示位置の設定
void LCD_CW(unsigned char); //LCDコマンド1バイト書き込み
void LCD_DW(unsigned char); //LCDデータ1バイト書き込み
//---------------------------------------------------------
// 気圧気温湿度センサーコマンド(PTHセンサー)
//---------------------------------------------------------
unsigned char pth_IDread(void); //センサーのソフトリセットとID読み取り
void pth_BREAD(unsigned char, unsigned char, unsigned char); //ブロック読み込み
void pth_readTrim(void); //センサー補正値の取得
void pth_setup(void); //センサー初期設定
void pth_readData(void); //センサー計測値読み取り
long int calibration_T(long int); //温度補正
unsigned long int calibration_P(signed long int); //気圧補正
unsigned long int calibration_H(signed long int); //湿度補正
//------------------------------
// その他関数
//------------------------------
void PIC_init(void); //PIC初期化
void Debug_RED(void); //デバッグ用赤色LED点滅
void Hex_Out(int); //整数を16進数で表示(ゼロサプレスしない)
void FloatDisp(float); //少数を少数以下1桁で表示
//---------------------------------------------------------
// 変数定義
//---------------------------------------------------------
int i, j; //ループカウンター
int disp; //文字変換する数値を代入
//unsigned char S_ADRS1 = 0xA0; // LCD Slave Address1
unsigned char S_ADRS1 = 0x7C; // LCD Slave Address1
unsigned char S_ADRS2 = 0xEC; // Senser Slave Address2
unsigned char RDDAT; //i2c受信関数データの一時保管
char str[5]; //16進文字変換結果代入
unsigned char para;
//----- センサー関連変数定義 --------
float temp_act = 0.0, press_act = 0.0, hum_act = 0.0;
long int temp_cal;
unsigned long int press_cal, hum_cal;
int buff[32]; //補正係数バッファ
unsigned long int hum_raw, temp_raw, pres_raw;
long int t_fine;
unsigned int dig_T1;
int dig_T2;
int dig_T3;
unsigned int dig_P1;
int dig_P2;
int dig_P3;
int dig_P4;
int dig_P5;
int dig_P6;
int dig_P7;
int dig_P8;
int dig_P9;
signed char dig_H1;
int dig_H2;
signed char dig_H3;
int dig_H4;
int dig_H5;
signed char dig_H6;
//========================================
//関数定義エリア
//========================================
//--------------------------------------------
// センサーセットアップ(補正係数読み込み含む)
//--------------------------------------------
void pth_setup(void) {
unsigned int osrs_t = 3; //Temperature oversampling x 4
unsigned int osrs_p = 3; //Pressure oversampling x 4
unsigned int osrs_h = 3; //Humidity oversampling x 4
unsigned int mode = 3; //Normal mode
unsigned int t_sb = 5; //Tstandby 1000ms
unsigned int filter = 0; //Filter off
unsigned int spi3w_en = 0; //3-wire SPI Disable
unsigned int ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
unsigned int config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
unsigned int ctrl_hum_reg = osrs_h;
//---------- センサーレジスターに初期設定を書き込み(各1バイト)---------
i2c_START();
i2c_WRITE(S_ADRS2);
i2c_WRITE(0xF2);
para = ctrl_hum_reg;
i2c_WRITE(para);
i2c_WRITE(0xF4);
para = ctrl_meas_reg;
i2c_WRITE(para);
i2c_WRITE(0xF5);
para = config_reg;
i2c_WRITE(para);
i2c_STOP();
}
//-------------------------------------
// センサー補正データの取得
//-------------------------------------
void pth_readTrim(void) {
//---------------------------------------------
// h88からA1までの25バイトを配列に読み込み表示
//---------------------------------------------
pth_BREAD(0x88, 24, 0); // レジスターアドレス 88-9F  24bytes
pth_BREAD(0xA1, 1, 24); // レジスターアドレス A1      1
pth_BREAD(0xE1, 7, 25); // レジスターアドレス E1-E7   7
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 以下はデータ確認用
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LCD_Clear(0); //LCD全クリア
LCD_puts("Data read OK");
__delay_ms(500);
LCD_Clear(0); //LCD全クリア
__delay_ms(500);
//-------------------------------------------
// 読み込んだデータを順次表示する(確認表示)
//-------------------------------------------
for (i = 0; i <= 31; i++) {
LCD_Clear(0);
disp = i + 0x88;
LCD_puts("Adrs = ");
Hex_Out(disp);
disp = buff[i];
LCD_Locate(0, 1);
LCD_puts("Data = ");
Hex_Out(disp);
__delay_ms(100);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ここまでデータ確認用
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 読み込んだ補正係数を変数に代入
//-----------------------------------------
dig_T1 = (buff[1] << 8) | buff[0];
dig_T2 = (buff[3] << 8) | buff[2];
dig_T3 = (buff[5] << 8) | buff[4];
dig_P1 = (buff[7] << 8) | buff[6];
dig_P2 = (buff[9] << 8) | buff[8];
dig_P3 = (buff[11] << 8) | buff[10];
dig_P4 = (buff[13] << 8) | buff[12];
dig_P5 = (buff[15] << 8) | buff[14];
dig_P6 = (buff[17] << 8) | buff[16];
dig_P7 = (buff[19] << 8) | buff[18];
dig_P8 = (buff[21] << 8) | buff[20];
dig_P9 = (buff[23] << 8) | buff[22];
dig_H1 = buff[24];
dig_H2 = (buff[26] << 8) | buff[25];
dig_H3 = buff[27];
dig_H4 = (buff[28] << 4) | (0x0F & buff[29]);
dig_H5 = (buff[30] << 4) | ((buff[29] >> 4) & 0x0F);
dig_H6 = buff[31];
}
//-------------------------------------------------------
// センサーから生の計測データを読みだす
//-------------------------------------------------------
void pth_readData(void) {
int i = 0;
unsigned long int data[8]; //レジスタアドレス F7 - FE を読み込む
i2c_START();
i2c_WRITE(S_ADRS2);
i2c_WRITE(0xF7);
i2c_ReSTART(); //再スタート
i2c_WRITE(S_ADRS2 + 0x01);
for (i = 0; i <= 7; i++) {
data[i] = i2c_READC(); //同じ変数の型であること。連続読み込みREADC
}
data[i + 1] = i2c_READ(); //同じ変数の型であること。最後の読み込みREADC
i2c_STOP();
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
//------------------------------------------------------
// 温度補正
//------------------------------------------------------
long int calibration_T(long int adc_T) {
long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((long int) dig_T1 << 1))) * ((long int) dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((long int) dig_T1)) * ((adc_T >> 4) - ((long int) dig_T1))) >> 12) * ((long int) dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
//------------------------------------------------------
// 気圧補正
//------------------------------------------------------
unsigned long int calibration_P(long int adc_P) {
long int var1, var2;
unsigned long int P;
var1 = (((long int) t_fine) >> 1) - (long int) 64000;
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((long int) dig_P6);
var2 = var2 + ((var1 * ((long int) dig_P5)) << 1);
var2 = (var2 >> 2)+(((long int) dig_P4) << 16);
var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3)
+ ((((long int) dig_P2) * var1) >> 1)) >> 18;
var1 = ((((32768 + var1))*((long int) dig_P1)) >> 15);
if (var1 == 0) {
return 0;
}
P = (((unsigned long int) (((long int) 1048576) - adc_P)-(var2 >> 12)))*3125;
if (P < 0x80000000) {
P = (P << 1) / ((unsigned long int) var1);
} else {
P = (P / (unsigned long int) var1) * 2;
}
var1 = (((long int) dig_P9) * ((long int) (((P >> 3) * (P >> 3)) >> 13))) >> 12;
var2 = (((long int) (P >> 2)) * ((long int) dig_P8)) >> 13;
P = (unsigned long int) ((long int) P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
//------------------------------------------------------
// 湿度補正
//------------------------------------------------------
unsigned long int calibration_H(long int adc_H) {
long int v_x1;
v_x1 = (t_fine - ((long int) 76800));
v_x1 = (((((adc_H << 14) -(((long int) dig_H4) << 20) - (((long int) dig_H5)
* v_x1)) + ((long int) 16384)) >> 15) * (((((((v_x1 * ((long int) dig_H6)) >> 10)
* (((v_x1 * ((long int) dig_H3)) >> 11) + ((long int) 32768))) >> 10)
+ ((long int) 2097152)) * ((long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((long int) dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int) (v_x1 >> 12);
}
//----------------------------------
// PIC 初期設定
//----------------------------------
void PIC_init(void) {
//add maru
OSCCON = 0x70; //0x70=8MHz PIC16F886はINTOSC時最高8MHzまでしか出ない上の#define _XTAL_FREQ 8000000;と矛盾しては成らない
ANSEL = 0b00000000;
ANSELH = 0b00000000;
//
//PICのポート設定
ADCON0 = 0b10000000; //アナログ使用しない
ADCON1 = 0b00000110; //For degital I/O
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b10011000; // i2cポートは「入力モード」
//ポート初期化
PORTA = 0b11111111;
PORTB = 0b11111111;
PORTC = 0b11111111;
//割り込み不使用
INTCON = 0b00000000;
//TMRはフリーラン
OPTION_REG = 0b11000000;
TMR0 = 0;
//周辺機器割り込み不使用
PIE1 = 0;
//周辺機器割り込みフラグクリア
PIR1 = 0;
}
//------------------------------------
// i2C READ one : 受信 = RDDAT
//------------------------------------
unsigned char i2c_READ(void) {
ACKDT = 1;
RCEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
RDDAT = SSPBUF;
SSPIF = 0;
ACKEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
SSPIF = 0;
return RDDAT;
}
//------------------------------------
// i2C READ Continue : 受信 = read_data
//------------------------------------
unsigned char i2c_READC(void) {
ACKDT = 0;
RCEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
RDDAT = SSPBUF;
SSPIF = 0;
ACKEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
SSPIF = 0;
return RDDAT;
}
//-------------------------------------
// i2C WRITE (write_data)
//-------------------------------------
void i2c_WRITE(unsigned char w_data) {
//    unsigned char w_data;
while (BF == 1); //BFが0になるまで待つ。1の間繰り返す。
SSPBUF = w_data;
SSPIF = 0;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
if (ACKSTAT == 1) {
SSPIF = 0;
} else {
SSPIF = 0;
}
}
//-----------------------------------
// i2C STOP Condition
//-----------------------------------
void i2c_STOP(void) {
PEN = 1;
while (SSPIF == 0);
SSPIF = 0;
}
//----------------------------------
// i2C START Condition
//----------------------------------
void i2c_START(void) {
SEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
SSPIF = 0;
}
//----------------------------------
// i2C Re-START Condition
//----------------------------------
void i2c_ReSTART(void) {
RSEN = 1;
while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す
SSPIF = 0;
}
//----------------------------------
// i2C 設定初期化
//----------------------------------
void i2c_CONF(void) {
SSPM3 = 1;
SSPM2 = 0;
SSPM1 = 0;
SSPM0 = 0;
SMP = 1;
CKE = 0;
SSPADD = 0x3F;
SSPEN = 1;
WCOL = 0;
SSPOV = 0;
}
//-------------------------------------------------------
//  pth センサーリセットとID読み取り
//-------------------------------------------------------
unsigned char pth_IDread(void) {
//--- Soft Reset ---
i2c_START();
i2c_WRITE(S_ADRS2);
i2c_WRITE(0xDE0); // soft resetaddress
i2c_WRITE(0xB6); // reset value B6
i2c_STOP();
//--- Sensor ID read out ---
i2c_START();
i2c_WRITE(S_ADRS2);
i2c_WRITE(0xD0); //Sensor ID resister address
i2c_ReSTART();
i2c_WRITE(S_ADRS2 + 1);
i2c_READ(); // 読み取り結果はRDDAT ID shouled be h60
i2c_STOP();
return RDDAT;
}
//------------------------------------------------------------------------
// pth Block Read ブロック読み込み
//   引数(Regis_Address, No# of bytes、配列書き込み位置)
//   結果は、buff[32]に格納。 転送バイト数は、 nod、配列書き込み位置ip
//------------------------------------------------------------------------
void pth_BREAD(unsigned char r_adrs, unsigned char nod, unsigned char ip) {
unsigned char ipp;
i2c_START();
i2c_WRITE(S_ADRS2);
i2c_WRITE(r_adrs);
i2c_ReSTART(); //再スタート
i2c_WRITE(S_ADRS2 + 0x01);
if (nod >= 2) {
for (ipp = ip; ipp <= ip + nod - 2; ipp++) {
buff[ipp] = i2c_READC(); //同じ変数の型であること。連続読み込みREADC
}
buff[ipp] = i2c_READ(); //同じ変数の型であること。最後の読み込みREADC(判断条件修正)
} else {
buff[ip] = i2c_READ(); //同じ変数の型であること。最後の読み込みREADC
}
i2c_STOP();
}
//---------------------------------------------------------
// Clear LCD Screen (ACM1602)
// 引数=0 全面
// 引数=1 1行目のみ
// 引数=2 2行目のみ
// 画面をクリア。カーソルはホームポジションに。
//---------------------------------------------------------
void LCD_Clear(int para) {
if (para == 0) {
LCD_CW(0x01); //LCDクリアリセット
return;
}
if (para == 1) {
LCD_Locate(0, (para - 1));
LCD_puts("                ");
return;
}
if (para == 2) {
LCD_Locate(0, (para - 1));
LCD_puts("                ");
return;
}
}
//-----------------------------------------------------------
//  Debug Red LED (OK)
//  赤色LEDを点滅させてプログラム停止 (PORT RB7接続のLED)
//------------------------------------------------------------
void Debug_RED() {
while (1) {
RED_led ^= 1;
__delay_ms(50);
}
}
//----------------------------------------------
// LCD Initialization
// 画面クリア後カーソルはホームへセット
// RAMメモリーポインター先頭
//-----------------------------------------------
void LCD_init() {
LCD_CW(0x01); // LCDリセット
LCD_CW(0x38);
LCD_CW(0x0F);
LCD_CW(0x06);
LCD_CW(0x80); // 表示RAM領域アドレスポインターを先頭に
}
//-----------------------------------------------
//  LCD文字表示(連続)
//  現在のカーソル位置から連続して文字を書き込む
//  1行目、2行目の終端を越えた文字は無視される
//------------------------------------------------
void LCD_puts(const char *p) {
while (*p != '\0') {
LCD_DW(*p);
p++;
}
}
//-----------------------------------------
//  LCD Cursor Control (x, y))
//-----------------------------------------
void LCD_Locate(unsigned char x, unsigned char y) {
unsigned char pos;
pos = 0x40 * y + x;
pos = pos + 0x80;
LCD_CW(pos);
}
//---------------------------------------------
// LCD コマンド1バイト書き込み
//---------------------------------------------
void LCD_CW(unsigned char lcd_cmd) {
i2c_START();
i2c_WRITE(S_ADRS1);
i2c_WRITE(0x00);
i2c_WRITE(lcd_cmd);
i2c_STOP();
__delay_ms(5);
}
//---------------------------------------------
// LCD データ1バイト書き込み
//---------------------------------------------
/*void LCD_DW(unsigned char lcd_dat) {
i2c_START();
i2c_WRITE(S_ADRS1);
i2c_WRITE(0x80);
i2c_WRITE(lcd_dat);
i2c_STOP();
__delay_ms(5);
}*/////old(org)
void LCD_DW(unsigned char lcd_dat) {
i2c_START();
i2c_WRITE(S_ADRS1);
i2c_WRITE(0x40);
i2c_WRITE(lcd_dat);
i2c_STOP();
__delay_ms(5);
}
//----------------------------------------------
// 整数を16進数x4に変換表示(ゼロサプレスしない)
//----------------------------------------------
void Hex_Out(int z_hex) {
if (z_hex <= 0x0FFF) LCD_puts("0"); //頭のゼロを表示
if (z_hex <= 0x00FF) LCD_puts("0"); //'0'ではだめ
if (z_hex <= 0x000F) LCD_puts("0");
itoa(str, z_hex, 16); // 16進表示
LCD_puts(str);
}
//---------------------------------------------------
// 浮動小数を小数点以下1位で文字表示(LCD)
//---------------------------------------------------
void FloatDisp(float suji) {
int seisu;
int syousu;
seisu = suji;
syousu = suji * 10 - (float) seisu * 10;
itoa(str, seisu, 10);
LCD_puts(str);
LCD_puts(".");
itoa(str, syousu, 10); //itoa() 関数は整数 n を文字ストリングに変換します。 このストリングは、渡されたバッファーに置かれます。
LCD_puts(str);
}
//////////////////// up to  End Of Program org ///////////////////////////
// undermentioned are add by maru 2019/02/05
#define LCD_ADD 0x7C            //LCDスレーブアドレス W
void I2C_Master_Init(const unsigned long c) {
SSPCON = 0b00101000; //RC3/SCK/SCL  RC4/SDI/SDA として使用宣言
SSPCON2 = 0;
SSPADD = (_XTAL_FREQ / (4 * c)) - 1;
SSPSTAT = 0b00000000; // 標準速度モードに設定する(100kHz)
}
void I2C_Master_Wait() {
while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}
void I2C_Master_Stop() {
I2C_Master_Wait();
PEN = 1;
}
void I2C_Master_Write(unsigned d) {
I2C_Master_Wait();
SSPBUF = d;
}
void I2C_Master_Start() {
I2C_Master_Wait();
SEN = 1;
}
void writeCommand(char t_command) {
I2C_Master_Start();
I2C_Master_Write(LCD_ADD);
I2C_Master_Write(0x00);
I2C_Master_Write(t_command);
I2C_Master_Stop();
__delay_ms(10);
}
void writeData(char t_data) {
I2C_Master_Start(); //スタート・コンディション
I2C_Master_Write(LCD_ADD); //0x7C スレーブアドレス
I2C_Master_Write(0x40); //0x40  キャラクタを書くよって宣言
I2C_Master_Write(t_data); //キャラクタの送信
I2C_Master_Stop(); //ストップ・コンディション
__delay_ms(10);
}
void LCD_str(char *c) { //LCDに配列の文字を表示
unsigned char i, wk;
for (i = 0;; i++) {
wk = c[i];
if (wk == 0x00) {
break;
}
writeData(wk);
}
}
//------------------------------------------------
void trigger(){
RA0 = 1;
__delay_us(10);
RA0 = 0;
}
void LCD_Init2() { //LCDの初期化、秋月のマニュアル通り
//TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0
I2C_Master_Init(100000);
__delay_ms(400);
//TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0
writeCommand(0x38); //このプロトコルは S 0x7C 0x00 0x38 A P と成っているから下のプロトコルも全部一個ずつ送信している
__delay_ms(20);
writeCommand(0x39);
__delay_ms(20);
writeCommand(0x14);
__delay_ms(20);
writeCommand(0x73);
__delay_ms(20);
writeCommand(0x52);
__delay_ms(20);
writeCommand(0x6C);
__delay_ms(250);
writeCommand(0x38);
__delay_ms(20);
writeCommand(0x01);
__delay_ms(20);
writeCommand(0x0C);
__delay_ms(20);
}
//-------------------------------------------------------
// メインプログラム
//-------------------------------------------------------
main() {
PIC_init(); // PICの入出力ポート、割り込み、AD変換など初期設定
i2c_CONF(); // PIC設定i2c用
//LCD_init(); // LCD初期化、クリアディスプレイ
LCD_Init2();
//LCD_CW(0x0C); // LCDカーソル非表示、ブリンクなし。
//-----------------------------
// PIC 起動確認用LED点滅 4回
//-----------------------------
RED_led = 0; // RED LED on
YELLOW_led = 0;
GREEN1_led = 0;
GREEN2_led = 0;
__delay_ms(500);
RED_led = 1; // RED LED off
__delay_ms(500);
RED_led = 0; // RED LED on
__delay_ms(500);
RED_led = 1; // RED LED off
YELLOW_led = 1;
GREEN1_led = 1;
GREEN2_led = 1;
__delay_ms(500);
//------------------------
// LCD 初期メッセージ表示
//------------------------
char moji1[] = "Copy_Right@";
char moji2[] = "     VividHobby";
char moji3[] = "Ready";
char moji4[] = "   C     %   hPa";
LCD_puts(" Copy_Right@");
__delay_ms(1000);
LCD_Locate(0, 1); // カーソルセット
LCD_puts("     VividHobby");
__delay_ms(1000);
LCD_Clear(0); //LCD全クリア
LCD_puts("modified by maru"); //1行目に表示
//------------------------------------------------------------------
//  センサー読み取り、計算、表示、処理開始
//------------------------------------------------------------------
//センサーIDを読み込む
disp = pth_IDread();
itoa(str, disp, 16); // 整数dispを16進文字変換
LCD_Locate(0, 1); //カーソル移動
LCD_puts("Sensor ID = ");
LCD_puts(str);
__delay_ms(1000);
//センサーの初期設定(補正係数読み込み含む)
pth_setup(); //補正係数読み込み pth_readTrim()は以下
pth_readTrim(); //補正データの読み取り(合計32バイト)
//-------------------------------------------------------------
//計測を連続して行う
//-------------------------------------------------------------
writeCommand(0x01); //画面をクリア
__delay_ms(20);
//writeCommand(0x80); //1列目へ移動
//LCD_str(moji4);
LCD_Clear(0); //LCD全クリア
LCD_puts("  'C     %   hPa");
while (1) {
//センサーから生の計測データを読み出す
trigger();
pth_readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double) temp_cal / 100.0;
press_act = (double) press_cal / 100.0;
hum_act = (double) hum_cal / 1024.0;
//-- 温度表示--
LCD_Locate(0, 1);
FloatDisp(temp_act);
//-- 湿度表示--
LCD_Locate(6, 1);
FloatDisp(hum_act);
LCD_puts(" ");
//-- 気圧表示--
disp = press_act;
itoa(str, disp, 10); // 整数dispを16進文字変換
LCD_Locate(12, 1);
LCD_puts(str);
LCD_puts("   ");
__delay_ms(3000);
}
//------------------------- ここまでを繰り返す----------------------------
}
//-------------------- End of Main program --------------------------------

HEXファイルが45KBほど在り、PIC KIT3での転送時間もやや長めだと
感じました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です