« GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) | トップページ | MCP3425のもうちょっと詳しい使い方(ソース付き) »

2014年11月24日 (月)

I2Cのソース - PIC12F1822/16F1705/16F1938/18F26K22 - LCD(ACM1602)を例にして

いろいろ覚えるのが面倒なのでPICも一種類で済ませられればいいのですが実際はそうも行きません。
もうこれが最後と思って買ってきたのがPIC16F1938。その後I2CとSPIを同時に使いたいというのでPIC18F26K22を買ってきたのは先日のこと、そして8bitDACを使いたいということでまたPIC16F1705を買ってきました。

最近はCで書いているから__というか浮動小数点の計算や書式設定があるのでCでしか書けなくなってしまったので__PICが変わったからと言って一から書き直すことはないもののやっぱりデバイスが違うとソースもまったく同じでというわけにも行きません。

今日は“16F1705でI2C”と思ったらはまってしまいました (^^;;

同じことで悩む方も少しはいらっしゃるような気もするのでこれからはソースは一式引用するかダウンロードできるようにすることにしました。

このソースを使った例
  「MCP3425のもうちょっと詳しい使い方(ソース付き)

----

記事を書いてすぐこんなことを書くのは心苦しいのですが、クロックが8MHzじゃないときは InitI2C_Master() の SSPADD の設定を変えないとまずいようです。訂正版をあらためてアップしますが、各位ご対応のほどよろしくお願いします m(._.)m
まあ、これでも動いてはいるんですが (^^;;

  <=== 修正しました。
      

======

条件付きコンパイルでPIC12F1822/PIC16F1705/PIC16F1938/PIC18F26K22の四つで使えるのを確認したI2Cライブラリです。I2Cだけでは動いているかどうかわからないのでLCD=液晶ディスプレイ(ACM1602N1-FLW-FBW)に簡単な表示ができるようになっています。
ただI2CライブラリもLCDのライブラリもきむしげさん(きむ茶工房ガレージハウス)のものをほとんどそのまま使わせていただいています。ライブラリ内部の動きがよくわからないときはきむしげさんの記事をご覧になった方が勉強になると思います。
ただ自分なりの使いやすさを考えたりLCDの仕様の違いの対応で手直ししたところもあります。動かなかったからと言ってすぐにきむしげさんに問い合わせたりしないでください。

なお“開発”は MPLAB X IDE v2.15 、Microchip MPLAB XC8 C Compiler (Free Mode) V1.32 Part Support Version: 1.32 (A) で行っています。

-----

I2Cを別の型番のPICに移植するときのコツですが、とにかくまず最初にデータシートの

  MASTER SYNCHRONOUS SERIAL PORT (MSSP1 AND MSSP2) MODULE

などのタイトルのところの最後にある

  REGISTERS ASSOCIATED WITH I2C™ OPERATION

をよく読む(移植元と移植先でよく見比べる)ことでしょうか。

特に新しいレジスタなんかあったら要注意です。16F1705はこれではまりました (^^;;

またレジスタ名はエイリアスが切ってあったりするので、まあ一度コンパイルしてエラーが起きたところで何が原因か考えるという方針でもどうにかなったりしますが。

I2Cを使ったプログラムの場合メイン(configなどの設定)でデバイスのおおまかな違いというかアーキテクチャ(?)の違いみたいな吸収し、I2Cライブラリで細かな入出力の違いみたいなのを吸収しますから、LCDの制御のような上位のライブラリはPICの型番が変わっても変更する必要はなくなります。もっともPIC18F26K22にしたらインクルードがpic.hじゃダメでxc.hにする必要がありました。こういうのは要するに勉強が足りないというだけの話なんでしょうがPICはあまりにも勉強しなきゃならないことが多くてたいへんです。

------

関連
  「PICでI2C - LCD(液晶)ディスプレイによる違い
  「PICでI2C - 液晶(LCD)ディスプレイ(ACM1602N1-FLW-FBW)に表示する

  「I2Cデバイス・アドレス一覧

  「PICでI2C - ADコンバーター・MCP3425の使い方
  「PICで平方根 - 白金薄膜抵抗で温度を測る
  「PICでI2C - 1 (温度計を作る)
  「I2C大気圧温度センサーLPS331の驚くべき分解能
  「海面更生気圧を気象庁とくらべてみた - I2C大気圧温度センサーLPS331
  「サーミスタによる温度測定の精度
  「サーミスタ温度計の精度を調べる - 1
  「ミニ恒温槽の作成に向けて - 1
  「炭素皮膜抵抗の温度係数を測定する話

-----

参考

  「きむ茶工房ガレージハウス - PICの動かせ方入門はこちら - 16F1938覚書
  「きむ茶工房ガレージハウス - I2C通信の実験
  「きむ茶工房ガレージハウス - 気圧センサーで大気圧と標高を測定して見ます(MPL115A1)(MPL115A2)」
  「きむ茶工房ガレージハウス - 秋月電子I2C接続小型LCDモジュールに表示を行う

-------

MyDef.h

/* 
* File:   MyDef.h
* Author: Seppina
*
* Created on 2014/11/22, 14:38
*/
#ifndef MYDEF_H
#define MYDEF_H
// http://www.microchip.jp/docs/41406B_JP.pdf
#ifdef _12F1822
#define _XTAL_FREQ 16000000
#define MySSPADD    0x27
#define SSPIE   SSP1IE
#define SSPIF   SSP1IF
#define BCLIE   BCL1IE
#define BCLIF   BCL1IF
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/40001729A.pdf
// http://ww1.microchip.com/downloads/jp/DeviceDoc/40001722A_JP.pdf
// (下は16F1703のものですが参考になります。これもきむしげさん情報です)
#ifdef _16F1705
#define _XTAL_FREQ 8000000
#define MySSPADD    0x13
#define SSPIE   SSP1IE
#define SSPIF   SSP1IF
#define BCLIE   BCL1IE
#define BCLIF   BCL1IF
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/40001574C.pdf
#ifdef _16F1938
#define _XTAL_FREQ 8000000
#define MySSPADD    0x13
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
#ifdef _18F26K22
#define _XTAL_FREQ 16000000
#define MySSPADD    0x27
#endif
#endif /* MYDEF_H */
--------

main.c

#include <xc.h>
#include "MyDef.h"
#include "I2CLib.h"
#include "ACM1602lib.h"
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\12f1822.html
#ifdef _12F1822
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\16f1705.html
#ifdef _16F1705
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\16f1938.html
#ifdef _16F1938
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\18f26k22.html
#ifdef _18F26K22
#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF
#endif
void interrupt InterFunction( void )
{
     // I2C関連の割り込み処理
     InterI2C() ;
}
void main()
{
    unsigned short i=0;
    int j;
#ifdef _12F1822
    OSCCON = 0b01111010 ;  // 16MHz
    ANSELA = 0b00000000 ;
#endif
#ifdef _16F1705
    OSCCON = 0b01110010 ;  // 8MHz
    ANSELC = 0b00000000 ;
    RC0PPS = 0x10;
    RC1PPS = 0x11;
#endif
#ifdef _16F1938
    OSCCON = 0b01110010 ;  // 8MHz
#endif
#ifdef _18F26K22
    OSCCON = 0b01110010 ;  // 16MHz
    ANSELC = 0b00000000 ;
#endif
    InitI2C_Master() ;
   
    LCD_Init() ;
    LCD_Clear();
    while(1) {
      LCD_SetCursor(i & 0x0F, (i >> 4) & 0x01);
        LCD_Putc((i & 0x3f) + 0x30);
        i++;
        for( j=0; j < 12; j++ ) __delay_ms(40);
        if(( i & 0x1f ) == 0 ) {
            LCD_Clear();
        }
    }
}
----------

I2Clib.h

// I2Clib.h
// I2C関数ライブラリ用インクルードファイル
// ソースは次のサイトもものを参考にさせていただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
#ifndef _I2CLIB_H_
#define _I2CLIB_H_
#define ACK   0
#define NOACK 1
#define RW_0  0
#define RW_1  1
void InterI2C( void ) ;
void InitI2C_Master() ;
int  I2C_Start(int adrs,int rw) ;
int  I2C_rStart(int adrs,int rw) ;
void I2C_Stop() ;
int  I2C_Send(char dt) ;
char I2C_Receive(int ack) ;
#endif

--------------------------

I2Clib.c

/*******************************************************************************
*  I2Clib - I2C関数ライブラリ(PIC 16F19xxシリーズ用)                      *
*          このライブラリはI2Cデバイス(RTC/EEPROM等)と接続を行う為の関数集です */
// ソースは次のサイトもものを参考にさせていただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
/*                                                                              *
*    InterI2C       - I2C関連の割り込み処理                                 *
*    InitI2C_Master - I2C通信のマスターモードで初期化を行う処理             *
*    I2C_Start      - スレーブにスタートコンディションを発行する処理           *
*    I2C_rStart     - スレーブにリピート・スタートコンディションを発行する処理 *
*    I2C_Stop       - スレーブにストップコンディションを発行する処理           *
*    I2C_Send       - スレーブにデータを1バイト送信する処理                   *
*    I2C_Receive    - スレーブからデータを1バイト受信する処理                 *
*                                                                              *
*    メモ:SDA/SCLピンは必ず「デジタル入力ピン」に設定を行って下さい。         *
*                                                                              *
*  PIC 16F1938/19xx  (12F1822/16F18xxシリーズはレジスタ名を変更すればOKです) *
*  MPLAB IDE(V8.84)                                                            *
*  MPLAB(R) XC8 C Compiler Version 1.00                                        *
*******************************************************************************/
#include <xc.h>
#include "I2Clib.h"
#include "MyDef.h"


int AckCheck ;
// アイドル状態のチェック
// ACKEN RCEN PEN RSEN SEN R/W BF が全て0ならOK
void I2C_IdleCheck(char mask)
{
     while (( SSPCON2 & 0x1F ) | (SSPSTAT & mask)) ;
}
/*******************************************************************************
*  InterI2C( void )                                                            *
*    I2C関連の割り込み処理                                                  *
*     この関数はメインプログラムの割込み関数で呼びます                         *
*******************************************************************************/
void InterI2C( void )
{
     if (SSPIF == 1) {        // SSP(I2C)割り込み発生か?
      if (AckCheck == 1) AckCheck = 0 ;
          SSPIF = 0 ;         // フラグクリア
     }
     if (BCLIF == 1) {        // MSSP(I2C)バス衝突割り込み発生か?
          BCLIF = 0 ;         // 今回はフラグのみクリアする(無処理)
     }
}
/*******************************************************************************
*  InitI2C_Master()                                                            *
*    I2C通信のマスターモードで初期化を行う処理                              *
*                                                                              *
*    注)クロック8MHzでの設定です、他のクロックはSSPADDを変更する必要が有ります *
*******************************************************************************/
void InitI2C_Master()
{
     __delay_ms(40);
     SSPSTAT= 0b10000000 ;    // 標準速度モードに設定する(100kHz)
     SSPCON1= 0b00101000 ;    // SDA/SCLピンはI2Cで使用し、マスターモードとする
     SSPADD = MySSPADD ;      // クロック=FOSC/((SSPADD + 1)*4) 8MHz/((0x13+1)*4)=0.1(100KHz)
     SSPIE = 1 ;              // SSP(I2C)割り込みを許可する
     BCLIE = 1 ;              // MSSP(I2C)バス衝突割り込みを許可する
     PEIE   = 1 ;             // 周辺装置割り込みを許可する
     GIE    = 1 ;             // 全割り込み処理を許可する
     SSPIF = 0 ;              // SSP(I2C)割り込みフラグをクリアする
     BCLIF = 0 ;              // MSSP(I2C)バス衝突割り込みフラグをクリアする
}
/*******************************************************************************
*  ans = I2C_Start(adrs,rw)                                                    *
*    スレーブにスタートコンディションを発行する処理                            *
*                                                                              *
*    adrs : スレーブのアドレスを指定します                                     *
*    rw   : スレーブに対する動作の指定をします                                 *
*           0=スレーブに書込みなさい要求 1=スレーブに送信しなさい要求         *
*    ans  : 0=正常 1=異常(相手からACKが返ってこない)                          *
*******************************************************************************/
int I2C_Start(int adrs,int rw)
{
     // スタート(START CONDITION)
     I2C_IdleCheck(0x5) ;
     SSPCON2bits.SEN = 1 ;
     // [スレーブのアドレス]を送信する
     I2C_IdleCheck(0x5) ;
     AckCheck = 1 ;
     SSPBUF = (char)((adrs<<1)+rw) ;    // アドレス + R/Wを送信
     while (AckCheck) ;                 // 相手からのACK返答を待つ
     return SSPCON2bits.ACKSTAT ;
}
/*******************************************************************************
*  ans = I2C_rStart(adrs,rw)                                                   *
*    スレーブにリピート・スタートコンディションを発行する処理                  *
*                                                                              *
*    adrs : スレーブのアドレスを指定します                                     *
*    rw   : スレーブに対する動作の指定をします                                 *
*           0=スレーブに書込みなさい要求 1=スレーブに送信しなさい要求         *
*    ans  : 0=正常 1:異常(相手からACKが返ってこない)                          *
*******************************************************************************/
int I2C_rStart(int adrs,int rw)
{
     // リピート・スタート(REPEATED START CONDITION)
     I2C_IdleCheck(0x5) ;
     SSPCON2bits.RSEN = 1 ;
     // [スレーブのアドレス]を送信する
     I2C_IdleCheck(0x5) ;
     AckCheck = 1 ;
     SSPBUF = (char)((adrs<<1)+rw) ;    // アドレス + R/Wを送信
     while (AckCheck) ;                 // 相手からのACK返答を待つ
     return SSPCON2bits.ACKSTAT ;
}
/*******************************************************************************
*  I2C_Stop()                                                                  *
*    スレーブにストップコンディションを発行する処理                            *
*******************************************************************************/
void I2C_Stop()
{
     // ストップ(STOP CONDITION)
     I2C_IdleCheck(0x5) ;
     SSPCON2bits.PEN = 1 ;
}
/*******************************************************************************
*  ans = I2C_Send(dt)                                                          *
*    スレーブにデータを1バイト送信する処理                                    *
*                                                                              *
*    dt  : 送信するデータを指定します                                          *
*    ans  : 0=正常 1=異常(相手からACKが返ってこない又はNOACKを返した)         *
*******************************************************************************/
int I2C_Send(char dt)
{
     I2C_IdleCheck(0x5) ;
     AckCheck = 1 ;
     SSPBUF = dt ;                      // データを送信
     while (AckCheck) ;                 // 相手からのACK返答を待つ
     return SSPCON2bits.ACKSTAT ;
}
/*******************************************************************************
*  ans = I2C_Receive(ack)                                                      *
*    スレーブからデータを1バイト受信する処理                                  *
*                                                                              *
*    ack  : スレーブへの返答データを指定します                                 *
*           0:ACKを返す 1:NOACKを返す(受信データが最後なら1)                  *
*    ans  : 受信したデータを返す                                               *
*******************************************************************************/
char I2C_Receive(int ack)
{
char dt ;

     I2C_IdleCheck(0x5) ;
     SSPCON2bits.RCEN = 1 ;        // 受信を許可する
     I2C_IdleCheck(0x4) ;
     dt = SSPBUF ;                 // データの受信
     I2C_IdleCheck(0x5) ;
     SSPCON2bits.ACKDT = ack ;     // ACKデータのセット
     SSPCON2bits.ACKEN = 1 ;       // ACKデータを返す
     return dt ;
}

----------------
ACM1602lib.h

// ACM1602lib.h
// I2C接続LCD関数ライブラリ用インクルードファイル
// ソースは次のサイトもものを参考にさせていただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
// 秋月電子通商 ACM1602N1-FLW-FBW
// 16文字x2行LCDモジュール バックライト付
#ifndef _ACM1602_H_
#define _ACM1602_H_
#define LCD_ADRES 0x50
void LCD_Clear(void) ;
void LCD_SetCursor(int col, int row) ;
void LCD_Putc(char c) ;
void LCD_Puts(const char * s) ;
void LCD_CreateChar(int p,char *dt) ;
void LCD_Init() ;
#endif

--------------------

ACM1602lib.c

// ソースは次のサイトのものを使わせいただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
// 気圧センサーで大気圧と標高を測定して見ます(MPL115A1)(MPL115A2)
// http://www.geocities.jp/zattouka/GarageHouse/micon/MPLAB/16F1938/Pressure/Pressure2.htm
// PIC16F1938
// 秋月電子通商 ACM1602N1-FLW-FBW
// 16文字x2行LCDモジュール バックライト付
// S1.01  http://seppina.cocolog-nifty.com/blog/
/*******************************************************************************
*  skI2CLCDlib - I2C接続LCD関数ライブラリ                                *
*             このライブラリは、秋月電子16文字x2行LCDモジュール バックライト付用です。 *
*                                                                              *
*    LCD_Init      - LCDの初期化を行う処理                                  *
*    LCD_Clear     - LCDモジュールの画面を消す処理                          *
*    LCD_SetCursor - LCDモジュール画面内のカーソル位置を移動する処理        *
*    LCD_Putc      - LCDにデータを1バイト出力する処理                      *
*    LCD_Puts      - LCDに文字列データを出力する処理                        *
*    LCD_CreateChar - オリジナルのキャラクタを登録します                       *
*                                                                              *
*    メモ:__delay_us() and __delay_ms() を使用しているので "MyDef.h" に *
*         "#define _XTAL_FREQ 8000000"が記述されています、                     *
*         8MHz以外のCPUクロックにする人は書き換えましょう。                    *
* ============================================================================ *
*  VERSION DATE        BY                    CHANGE/COMMENT                    *
* ---------------------------------------------------------------------------- *
*  1.00    2013-07-25  きむ茶工房(きむしげ)  Create                            *
*  2.00    2013-09-21  for ACM1602 by Seppina                              *
* ============================================================================ *
*  PIC PIC16F1938 (このライブラリ自体は他のPICでもOKと思います)      *
*  MPLAB IDE(V8.84)                                                            *
*  MPLAB(R) XC8 C Compiler Version 1.00                                        *
*******************************************************************************/
#include <xc.h>
#include "MyDef.h"
#include "I2Clib.h"
#include "ACM1602lib.h"
// LCDにコマンドを発行する処理
void command(unsigned char c)
{
     int  ans ;
     ans = I2C_Start(LCD_ADRES,RW_0);     // スタートコンディションを発行する
     if (ans == 0) {
          // command word の送信
          I2C_Send(0b00000000) ;             // control byte の送信(コマンドを指定)
          I2C_Send(c) ;                      // data byte の送信
     }
     I2C_Stop() ;                            // ストップコンディションを発行する
     __delay_us(26) ;
}
/*******************************************************************************
*  LCD_Clear( )                                                                *
*    LCDモジュールの画面を消す処理                                          *
*******************************************************************************/
void LCD_Clear(void)
{
     command(0x01) ;     // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
     __delay_ms(5) ;  // LCDが処理(2.16ms)するのを待ちます
}
/*******************************************************************************
*  LCD_SetCursor(col,row)                                                      *
*    LCDモジュール画面内のカーソル位置を移動する処理                        *
*                                                                              *
*    col : 横(列)方向のカーソル位置(0-7)                                       *
*    row : 縦(行)方向のカーソル位置(0-1)                                       *
*******************************************************************************/
void LCD_SetCursor(int col, int row)
{
     int row_offsets[] = { 0x00, 0x40 } ;
     command(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-07H,40H-47H
}
/*******************************************************************************
*  LCD_Putc(c)                                                                 *
*    文字列は、NULL(0x00)まで繰返し出力します。                                *
*                                                                              *
*    c :  出力する文字データを指定                                             *
*******************************************************************************/
void LCD_Putc(char c)
{
     int  ans ;
     ans = I2C_Start(LCD_ADRES,RW_0);     // スタートコンディションを発行する
     if (ans == 0) {
          // command word の送信
          I2C_Send(0b10000000) ;             // control byte の送信(データを指定)
          I2C_Send(c) ;                      // data byte の送信
     }
     I2C_Stop() ;                            // ストップコンディションを発行する
     __delay_us(26) ;
}
/*******************************************************************************
*  LCD_Puts(*s)                                                                *
*    LCDに文字列データを出力する処理                                        *
*    文字列は、NULL(0x00)まで繰返し出力します。                                *
*                                                                              *
*    *s :  出力する文字列のデータを格納した場所のアドレスを指定                *
*******************************************************************************/
void LCD_Puts(const char * s)
{
     int  ans ;
     while(*s) {
          LCD_Putc(*s++);
     }
}
/*******************************************************************************
*  LCD_CreateChar(p,*dt)                                                       *
*    オリジナルのキャラクタを登録します                                        *
*                                                                              *
*    p   : 登録する場所の指定(0〜5の6ヶ所のみ)                              *
*    p   : 登録する場所の指定(0〜5の6ヶ所のみ)                              *
*    *dt : 登録したいキャラクタのデータを格納したバッファを指定                *
********************************************************************************/
// **** ACM602では未検証です ****
void LCD_CreateChar(int p,char *dt)
{
    command(0x40 | p << 3 );
    __delay_ms(5) ;
    for (int i=0; i < 8; i++) {
         LCD_Putc(*dt++);
    }
}
/*******************************************************************************
*  LCD_Init( )                                                                 *
*    LCDの初期化を行う処理                                                  *
*******************************************************************************/
void LCD_Init()
{
 
    command(0x01);      // Clear Diplay.
    __delay_ms(5) ;     // 5ms待ちます。
    command(0x38);      // Function Set.
    __delay_ms(5) ;     // 5ms待ちます。
                        // 0b000x0000; DL; Interface Data length. 8bits/4bits
                        // 0b0000x000; N;  Numbers of display line. 2-line/1-line
                        // 0b00000x00; F;  Display font type. 5x10dots/5x8dots
    command(0x0c);      // Display ON/OFF Control.
    __delay_ms(5) ;     // 5ms待ちます。
                        // 0b00000x00; D;  Set display on/off.
                        // 0b000000x0; C;  Set curthor on/off.
                        // 0b0000000x; B;  Set blinking of curthor on/off.
    command(0x06);      // Entry Mode Set.
    __delay_ms(5) ;     // 5ms待ちます。
                        // 0b000000x0; I/D;Assign curthor moving direction.
                        // 0b0000000x; I/D;Enable the shift of entire display.
     LCD_Clear() ;       // Clear Display          : 画面を消去する
}

------------------------------

 

// 12F1822
// 01 VDD....(2)
// 02 RA5/CLKIN/OSC1/T1OSI/T1CKI/SRNQ/P1A/CCP1/DT/RX
// 03 RA4/AN3/CPS3/OSC2/CLKOUT/T1OSO/C1IN1-/CLKR/SDO/CK/TX/P1B/T1G/MDCIN2
// 04 RA3/SS/T1G/VPP//MCLR....(1)
// 05 RA2/AN2/CPS2/C1OUT/SRQ/T0CKI/CCP1/P1A/FLT0/SDA/SDI/INT/MDCIN1
// 06 RA1/AN1/CPS1/VREF+/C1IN0-/SRI/RX/DT/SCL/SCK/MDMIN/ICSPCLK/ICDCLK....(5)
// 07 RA0/AN0/CPS0/C1IN+/DACOUT/TX(1)/CK/SDO/SS/P1B/MDOUT/ICSPDAT/ICDDAT....(4)
// 08 VSS....(3)
// 16F1075
// 01 VDD....(2)
// 02 RA5/T1CKI/SOSCI/CLCIN3/OSC1/CLKIN
// 03 RA4/AN3/T1G/SOSCO/OSC2/CLKOUT
// 04 RA3/MCLR/VPP....(1)
// 05 RC5/OPA2IN+/CCP1/RX
// 06 RC4/OPA2IN-/CK/CLCIN1
// 07 RC3/AN7/C1IN3-/C2IN3-/OPA2OUT/CCP2/SS/CLCIN0
// 08 RC2/AN6/C1IN2-/C2IN2-/OPA1OUT
// 09 RC1/AN5/C1IN1-/C2IN1-/OPA1IN-/SDI/SDA/CLCIN2
// 10 RC0/AN4/C2IN+/OPA1IN+/SCK/SCL
// 11 RA2/AN2/DAC1OUT2/ZCD/T0CKI/COGIN/INT
// 12 RA1/AN1/VREF+/C1IN0-/C2IN0-/ICSPCLK....(5)
// 13 RA0/AN0/VREF-/C1IN+/DAC1OUT/ICSPDAT....(4)
// 14 VSS....(3)
// PIC16F1938
// 01 VPP//MCLR .....(1)
// 02 RA0/AN0
// 03 RA1/AN1
// 04 RA2/AN2/DACOUT
// 05 RA3/AN3
// 06 RA4
// 07 RA5/AN4
// 08 VSS
// 09 RA7
// 10 RA6/OSC2/CLKO
// 11 RC0
// 12 RC1
// 13 RC2
// 14 RC3/SCL
// 15 RC4/SDA
// 16 RC5/SDO
// 17 RC6/TX
// 18 RC7/RX
// 19 VSS .....(3)
// 20 VDD .....(2)
// 21 RB0/INT
// 22 RB1
// 23 RB2
// 24 RB3
// 25 RB4
// 26 RB5
// 27 RB6/PGC .....(5)
// 28 RB7/PGD .....(4)
// PIC18F26K22
// 01 /MCLR .....(1)
// 02 RA0/AN0
// 03 RA1/AN1
// 04 RA2/AN2/DACOUT
// 05 RA3/AN3
// 06 RA4
// 07 RA5/AN4
// 08 VSS
// 09 RA7
// 10 RA6/OSC2/CLKO
// 11 RC0
// 12 RC1
// 13 RC2
// 14 RC3/SCL1
// 15 RC4/SDA1
// 16 RC5/SDO1
// 17 RC6/TX1
// 18 RC7/RX1
// 19 VSS .....(3)
// 20 VDD .....(2)
// 21 RB0/INT0
// 22 RB1/SCL2
// 23 RB2/SDA2
// 24 RB3/SDO2
// 25 RB4
// 26 RB5
// 27 RB6/TX2/PGC .....(5)
// 28 RB7/RX2/PGD .....(4)

« GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) | トップページ | MCP3425のもうちょっと詳しい使い方(ソース付き) »

趣味の電子工作」カテゴリの記事

コメント

こんばんは
I2Cのマルチマスターを記事にして置きました。

16F1705が届いたのでぼちぼち眺めています。
SPI/I2C/USART/CCP等の入出力が好きなピンに割り付け可能(PPS機能)な様ですね。
入力はデフォルトが有るようですが、
出力が設定を行わないとダメなようですね注意しましょう。

マルチマスター、記事にされましたか (^^)
楽しみです。のちほど拝見させていただきます。
おっしゃる通りでこの四つのなかでは16F1705がいちばん手ごわかったです。
何が必要で何が不要か判別するのにけっこう時間がかかってしまいました (^^;;

この記事のプログラムをコピペして16F1705に書き込みました。
初めてのI2CでLCDがAQM0802(8桁2行の超小型のやつです)だったのでハマりました^^;
コマンド送信もデータ送信もACM1602とは違うことにしばらく気が付きませんでした;;
セッピーナさんのほかの記事に書いてあったのを発見してやっとこさ動きました^^。
とてもためになります。

秋月のLCDも一つ一つ微妙に(あるいは、けっこう)使い方がちがいますよね(取説、サンプルソースがわかりにくにというのもあるかも)
私もはまってググりまくりました (^^;;
この手のソースは(記事にもリンクがありますが)きむしげさんのが信頼性が高く説明も詳しいと思います。

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1994983/58073225

この記事へのトラックバック一覧です: I2Cのソース - PIC12F1822/16F1705/16F1938/18F26K22 - LCD(ACM1602)を例にして:

« GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) | トップページ | MCP3425のもうちょっと詳しい使い方(ソース付き) »

フォト

サイト内検索

  • 記事を探されるんでしたらこれがいちばん早くて確実です。私も使ってます (^^;; 検索窓が表示されるのにちょっと時間がかかるのはどうにかしてほしいです。

新着記事

リンク元別アクセス数

  • (アクセス元≒リンク元、原則PCのみ・ドメイン別、サイト内等除く)

人気記事ランキング

  • (原則PCのみ、直近2週間)
無料ブログはココログ