配列と構造体の使い方


【配列の作り方】

MPLAB-C18の配列の作り方はANSI標準に順じています。
そして下記のようにデータとして確保されます。

 ・配列の最初のインデックスは [0] となる。
 ・連続したメモリエリアに配置されインデックス0が最も若いアドレスになる
 ・全ての要素は同じ型となる。
 ・配列名はポインター変数となる。
 ・初期値も一緒に定義することが出来る。
 ・文字列を配列として取ることが出来る。このときには1文字が1要素となる。
  また文字列の最後には0が自動追加されるので要素数は1個余分に必要。

 《例1》 数値定数の配列の初期値セット方法
    int i[5] = {1,2,3,4,5};
      (このときは i[0] が1で i[4] が5となる)
 《例2》 文字定数の配列の初期値セット方法
    char str[4] = {'a', 'b', 'c', 0};
   
    char name[5] = "John";
      (要素はname[0]がJで name[4]は0となる)

 《例3》 配列のコピー
    配列は全ての要素をそれぞれコピーする必要がある。
     
    for (i=o; i<10; i++)
      b[i] = a[i];


【プログラムメモリ内の配列定数】

PICにはデータメモリとプログラムメモリがあり、定数であればプログラムメモリ
の中にも配列定数を格納することが出来ます。
これを明確に区別するために、 rom と ram という宣言追加が出来ます。
デフォルトはramとなっているのでデータメモリ内の配列には特に指定は不要。

 《例4》 プログラムメモリに文字定数を確保する例
   rom const char table1[20] = {"string 1", "string 2", "string 3", "string4 "};
     (この場合は20バイトづつ4個の文字定数を確保するので40ワードが
      必要です。)
   rom const char table2[ ] = {"string 1", "string 2", "string 3", "string4 "};
     (この場合には9+2バイトづつ4個の文字定数を確保するので22ワード
      が必要です。+2バイトはポインターアドレスです)

 《例5》 配列のromからramへのコピー関数
   
    void str2ram ( staic char *dest, static char rom *src )
    {
       while( (*dest++ = *src++)  != '\0' )
    }

 《例6》 str2ram関数の使用例
    ROM内の文字列をUSARTに出力する例。USARTに出力する関数はデータ
    がRAMエリアにあることを前提に作られているのでRAMにコピーが必要。

    rom char mystring[ ] = ”Send me to the USART";
    void foo(void)
    {
       char strbuffer[21];
       str2ram ( strbuffer, mystring );
       putsUSART1( strbuffer );
    }

【構造体の作り方】

構造体(UNION)とは変数をグループで扱うようにしたもので、変数の集合体です。
複数の異なる型を混在させることも出来ます。

構造体の書式は下記とします。

  型宣言 構造体型名
  {
    型宣言 変数名;
    型宣言 変数名;
     ・・・・・・・
  } 構造体変数名;


 《例7》 構造体の定義例
    下記例ではcardという構造体変数を定義している。catalog_tagは新しい
    構造体の型名であり変数名では無い。

   struct catalog_tag
   {
    char author[40];
    char title[40];
    char pub[40];
    unsigned int date;
    unsigned char rev;
   } card;

上記の各要素変数は下記のようにピリオッドで区切って指定する。

   構造体変数名.要素変数名

 《例8》
   card.rev = 'a';
   ThirdChar = card.title [2];

【ビット変数の構造体の作り方】

ビット変数の構造体は下記のフォーマットとします。

  型宣言 構造体名
  {
    int 要素名 : ビット幅;
    int 要素名 : ビット幅;
    ・・・・・
  }


 《例9》 PORTBのビット定義
     下記でPORTBの各ビットは PORTBbits.RB1 のように指定
     できます。(下位ビットから順番です)
     同じビットに複数の要素名をつけることが可能です。

    extern volatile near unsigned char PORTB;
    extern volatile near union {
     struct {
       unsigned RB0:1;
       unsigned RB1:1;
       unsigned RB2:1;
       unsigned RB3:1;
       unsigned RB4:1;
       unsigned RB5:1;
       unsigned RB6:1;
       unsigned RB7:1;
     } ;
     struct {
       unsigned INT0:1;
       unsigned INT1:1;
       unsigned INT2:1;
       unsigned CCP2:1;
     } ;
    } PORTBbits ;


  《例10》 PORTAのビット定義例
     ビットをスキップするには要素名を省略します。
    extern volatile near unsigned char PORTA;
    extern volatile near union {
     struct {
       unsigned RA0:1;
       unsigned RA1:1;
       unsigned RA2:1;
       unsigned RA3:1;
       unsigned RA4:1;
       unsigned RA5:1;
       unsigned RA6:1;
       unsigned RA7:1;
     } ;
     struct {
       unsigned AN0:1;
       unsigned AN1:1;
       unsigned AN2:1;
       unsigned AN3:1;
       unsigned T0CKI:1;
       unsigned SS:1;
       unsigned OSC1:1;
       unsigned OSC2:1;
     } ;
     struct {
       unsigned :2;
       unsigned VREFM:1;
       unsigned VREFP:1;
       unsigned :1;
       unsigned AN4:1;
       unsigned CLKIN:1;
       unsigned CLKOUT:1;
     } ;
     struct {
       unsigned :5;
       unsigned LVDIN:1;
     } ;
   } PORTAbits ;


   目次ページへ