SSブログ

I2C PIC16F886 LCD AQM1602XA EX_IO_PCF8574AN_c

他力本願のC言語入門で下記の制御です
・CPU  PIC16F886
・LCD AQM1602XA
・I/O PCF8574AN
アセンブラでも記事がありますのでご参考まで

動作は下記の様に成って居ます
・LCD AQM1602XA
 0 -> 1 -> 2...32768 -> -32768 -> -32767...-3 -> -2 -> -1 -> 0 の繰り返し
・I/O PCF8574AN
 0 -> 1 -> 2・・・255 -> 0 -> 1・・・の繰り返し
データは出しっ放しでスレーブアドレス側からのデータ読み込みは有りません


参考にしたと申しますか殆どパクッたプログラムです
出典元はWak-techさんです、とても丁寧で判りやすいブログです
この場を借りて御礼申し上げます。

ソースです、なにぶんど素人なのでへたくそです笑って下さい


/*
 * File:   main.c
 * Author: maru
 * PCF8574AN_pic16f886_v001
 * Created on 2019/01/09, 8:57
 * 0 -> 1 -> 2...32768 -> -32768 -> -32767...-3 -> -2 -> -1 -> 0 の繰り返し
 */

// CONFIG1 MPLAB XIDEの Production -> Set Configration bits で設定してもこのプログラムでの宣言が優先される
//#pragma config FOSC = INTRC_NOCLKOUT //RA6 = I/O          //デフォルトではRA6 = fosc/4 output
#pragma config FOSC = INTRC_CLKOUT //RA6 = fosc/4 output
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
//#pragma config CLKOUTEN = OFF
//#pragma config IESO = OFF
#pragma config FCMEN = OFF

// CONFIG2
#pragma config WRT = OFF
//#pragma config VCAPEN = OFF
//#pragma config PLLEN = ON
//#pragma config STVREN = ON
#pragma config BOR4V = BOR40V
#pragma config LVP = ON

#include 
#include 
#include 
#include 

#define _XTAL_FREQ 8000000      //PIC16F886はINTOSC時最高8MHzまでしか出ない下のOSCCON = 0x70;と矛盾しては成らない
#define LCD_ADD 0x7C            //LCDスレーブアドレス W
#define S5851A_ADR 0x90         //温度センサースレーブアドレス W
#define PCF8574AN_ADR 0x70      //Extentioned IO スレーブアドレス W
#define ToHome 0b00000010
#define shiftLeft 0b00011000
#define shiftRight 0b00011100
#define clear 0b00000001

char moji[] = " ";
char moji2[] = "counter= ";
char moji3[] = "v001";      //この文字列を長くするとカウントアップがバグる、原因不明

    void TRIGGER(){
        PORTAbits.RA0 = 1;    //for debug オシロスコープ・トリガ用 PORTA-RA0
          __delay_us(10);
        PORTAbits.RA0 = 0;
    }

    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_Start()
    {
      I2C_Master_Wait();
      SEN = 1;
    }

    void I2C_Master_RepeatedStart()
    {
      I2C_Master_Wait();
      RSEN = 1;
    }

    void I2C_Master_Stop()
    {
      I2C_Master_Wait();
      PEN = 1;
    }

    void I2C_Master_Write(unsigned d)
    {
      I2C_Master_Wait();
      SSPBUF = d;
    }
    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 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 PICinit(){
      OSCCON = 0x70;          //0x70=8MHz PIC16F886はINTOSC時最高8MHzまでしか出ない上の#define _XTAL_FREQ 8000000;と矛盾しては成らない
      ANSEL  = 0b00000000;
      ANSELH = 0b00000000;
      TRISA  = 0b00000000;
      TRISB  = 0b00000000;
      TRISC  = 0b00011000;
      PORTA  = 0b00000000;    //2進数で書いた場合
      PORTB  = 0x00;          //16進数で書いた場合
    }
    void LCD_Init(){            //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);
    }

    void LCD_str(char *c) {     //LCDに配列の文字を表示
      unsigned char i,wk;
      for (i=0 ; ; i++) {
        wk = c[i];
        if  (wk == 0x00) {break;}
        writeData(wk);
      }
    }
    
    //S5851A_ADR 温度センサー部分=========================================================================================
    void S5851A_W(char t_data){
        I2C_Master_Init(100000);
        I2C_Master_Start();             //スタート・コンディション
        I2C_Master_Write(S5851A_ADR);      //スレーブアドレス
        I2C_Master_Write(0x01);         //
        I2C_Master_Write(t_data);       //キャラクタの送信
        I2C_Master_Stop();              //ストップ・コンディション
        __delay_ms(10);
    }
    //S5851A_ADR 温度センサー部分=========================================================================================
    
    //PCF8574AN Extentioned IO 部分=========================================================================================
    void PCF8574AN_W(){
        I2C_Master_Init(100000);
        I2C_Master_Start();             //スタート・コンディション
        I2C_Master_Write(PCF8574AN_ADR);      //スレーブアドレス
        I2C_Master_Write(0xAA);         //データ送信
        I2C_Master_Stop();              //ストップ・コンディション
        __delay_ms(10);
    }
    
    void PCF8574AN_W2(char LED){
        I2C_Master_Init(100000);
        I2C_Master_Start();             //スタート・コンディション
        I2C_Master_Write(PCF8574AN_ADR);      //スレーブアドレス
        I2C_Master_Write(LED);         //データ送信
        I2C_Master_Stop();              //ストップ・コンディション
        __delay_ms(10);
    }
    //PCF8574AN Extentioned IO 部分=========================================================================================


    

    int main(void){
      PICinit();      //PICを初期化
    //  TRIGGER();
      PCF8574AN_W();
     // S5851A_W(0x00);       //温度センサー、コンフィギュレーションレジスタ書き込みプロトコル
      LCD_Init();
      writeCommand(0x01); //画面をクリア
      __delay_ms(20);
      writeCommand(0x02); //ホームへカーソル移動
      __delay_ms(2); // LCD側の処理待ち
      
      int count = 0;      //カウント初期値
      int count2 = 0;      //カウント初期値
      
      __delay_ms(1000);
      
      writeCommand(0x80); //1列目へ移動
      LCD_str(moji3);           //
      __delay_ms(100);
      
      writeCommand(0x80+0x40); //2列目へ移動
      LCD_str(moji2);           //毎回「counter」と書き込むのは無駄なのでループ外へ出した
      __delay_ms(100);
     //------------------------------------------------------      
     while(1){
      //writeCommand(ToHome);     //画面左上へカーソルを移動
      writeCommand(0x88+0x40); //カーソル移動
      count++;                  //カウントアップ
    //-----------------------
      sprintf(moji,"%d",count);     //mojiにcounter:countを代入
      LCD_str(moji);                //mojiを表示
    //-----------------------  
      TRIGGER();
      count2++;
      PCF8574AN_W2(count2);         //インクリメントした数値をPCF8574AN Extentioned IO に I2C送信
    //-----------------------  
      __delay_ms(1);               //1ms遅延
    }
      return 0;
    //------------------------------------------------------
    }


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。