FC2カウンター

現在の訪問者数

現在の閲覧者数:

カレンダー

05 | 2017/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -

プロフィール

剣菱P

Author:剣菱P
剣菱Pと申します。
性別:男
年齢:27
二兎を追って一兎も得られないタイプ

マイコンやプログラミング、ニコニコ動画、雑記等
方向性は見えずとも、ちょっとずつ更新していく予定です!

リンクフリーです。
こんなブログでよかったらよろしくお願いしま~す。

公開メール kenbishiP@gmail.com

検索フォーム

最新記事

最新コメント

カテゴリ

メールフォーム

名前:
メール:
件名:
本文:

月別アーカイブ

最新トラックバック

リンク

ブロとも一覧

ブロとも申請フォーム

ランキング

ランキング参加中です。気が向いたらクリックしてあげてください。


にほんブログ村 その他趣味ブログへ
にほんブログ村 その他趣味ブログ 趣味の工作へ

スポンサーサイト


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PIC なぜかprintfが・・・ PICの悲しみ»

コメント

コメントの投稿













管理者にだけ表示を許可する

PIC 液晶 文字列


問題のプログラムを少しだけ手直ししてみました。

といっても、制限を厳しくしただけで、根本的な最適化をしたわけではありません。

なにを変えたかというと、一度に渡せる引数の数を6にしました。
さっきの段階では21でした。 ちなみに実際に渡すことの出来る変数は6-1の5です。

重複ですが一応プログラムです。
まだ配布できるようなプログラムには程遠いわけですが、万が一にもだれかの役に立つかもしれないので、一応さらしておきます。 といっても前回とほとんど同じですがねw

lcd_v2-0.txt

↑をlcd.hという名前で保存し、プロジェクトに組み込めば使えます。

追加部分


//********** LCDに文字列を表示する関数 *****************//

void lcd_printf(char *num,...)
{
    va_list list;
    int i,k,n=0,m=0,count=0,mojisuu=0,size=0,data2=0;
    char data[5];
    char moji[20];
    char keta[5];
    for(k=0;*(num+k) != '\0' ;k++){
        if(*(num+k) == '%'){
            data[count] = k;
            count++;
        }
        mojisuu++;
    }

    va_start(list,num);

    if(count > 0){
        for(i=0;i<mojisuu;i++){
            for(k=0;k<count;k++){
                if(i==data[k]){
                    size = *(num+i+2) - '0';
                    data2 = va_arg(list,int);   

                    for(m=0;m<size;m++){
                        keta[size-m-1] = data2%10;
                        data2 = data2/10;
                    }
                    for(m=0;m<size;m++){
                        moji[n]=keta[m]+'0';
                        if(m<size-1)n++;
                    }
                    i+=3;
                    break;
                }
                else{
                    moji[n]=*(num+i);
                }
            }
            n++;
        }
    }
    else{
        n = mojisuu;
        for(i=0;i<n;i++){
            moji[i]=*(num+i);
        }
    }
   
    for(i=0;i<n;i++){
        lcd_data(moji[i]);
    }


    va_end(list);
}


赤くなってるところを削減しました。
ま、実際のところ一度に表示できる変数が一つしかなくても、関数を何度か呼べば解決できるので一つでも問題はないのですが、とりあえず5個くらいにしておきました。

さらに、プログラムのメイン部分です。

#include<pic.h>
#include"lcd.h"
#include"delay.h"
__CONFIG(HS & WDTDIS & PWRTDIS & UNPROTECT);


void main(){
    int c=0;
    TRISA = 0x00;
    TRISB = 0x00;
    PORTA = 0x00;
    PORTB = 0x00;

    lcd_init();
    lcd_clear();
    DelayMs(2);
    lcd_cmd(0x0c);                    //カーソル非表示
    while(1){
        lcd_pos(1,1);                //カーソル位置一行目の一文字目
        DelayMs(250);
        DelayMs(250);
        lcd_printf("count = %u3d",c++);       
       
    }
}



これでコンパイルしてみたら、なんとか1k wordに収まったようです。
コンパイル時のメッセージには

Memory Summary:
    Program space        used   386h (   902) of   400h words   ( 88.1%)
    Data space               used    42h (    66) of    44h bytes   ( 97.1%)
    EEPROM space       used     0h (     0) of    40h bytes   (  0.0%)
    Configuration bits    used     1h (     1) of     1h word    (100.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)
   
となっていました。ギリギリですね。
どうやら前回コンパイルが通らなかった原因はプログラムメモリよりもData spaceの容量の問題だったようです。
変数はプログラムメモリとは別の場所にあるところに格納されます。(たしか・・・)
どこかというと、TRISBやINTCONなどのレジスタさんがたが並んでいるスペースがあり、そこのフリースペースに変数を置かせていただいています。(たしかw)
そのフリースペースをデータメモリーと呼びます。
PIC 16F84Aは68byteしかそれがありません。
つまりは、char型(8 bit)の変数が68個しか収納できないわけです。
さっきのプログラムのように、 char型の配列を20と40他にint(16 bit)の変数をいくつか使ったら、
まったく足りないわけです。
削減しても97.1%も使用してしまってますので、このままではもう変数を追加できなくなってしまいます。 実際には変数には寿命があるので、常に居座るわけではありませんが、だとしてもこの数は多すぎますね。

ちなみにこの関数の使い方ですが、これまたちょっと縛りがありまして、

lcd_printf("文字列");
lcd_printf("文字列 %u3d",int型変数);

の様な感じで使います。
純粋に文字列のみを固定で表示する場合は、””の間に好きなもじ20文字以内を書けばいいのですが。
%は使えません。さらにprintfで有効な\nや\aなども使用不可です。純粋に文字だけ出力可です。

変数を混ぜて使いたい時は
printfの様に%を使いますが、今現在は%の後にuという文字をつけて、その後に1~5の数字、最後にdをつけてください。
printfの様に省略することはできません。かならずこの三文字を%の後ろにつけます。
uとdは後の拡張用につけました。
今はintのみですが、他のものを使う時にdの他にも対応できるように一応用意しました。
uは符号関係の情報です。今は符号は認識しませんが、後々対応出来るように用意しました。

数字は桁数です。最大で5桁の数字しか表示できません。実際に表示する桁よりも多い桁を指定した場合、
あまったところには0が入ります。
123を表示させたいのに5桁を指定した場合 00123と表示されます。
同様に12345を表示させたいのに3桁を指定したばあい、345しか表示されません。

とまあ、まだ幼い関数でprintf様の名前を借りることすらおこがましい限りですが、
一応この通りに使っていただけたら動作するはずです。

このフォーマット通りに使わなかった場合の安全装置等はまったく組み込まれていない状態です。
さらに、自分はあまりプログラムが得意じゃないので、見落としているバグがかなり高確率であると思います(orz)
もし使うのでしたらお気をつけください。何があっても責任はとれません(;^_^A  すみません(。-人-。)



まぁ、とりあえずはコンパイルが通ったので一応動作を確認してみます。
メインのプログラムは液晶に count = XXXと表示し、一定時間ごとにカウントアップしていくようになってます。XXXには三桁の数字が入ります。

PIC LCD3

[広告] VPS

無事動作しているようです


クリックお願いします。
スポンサーサイト

PIC なぜかprintfが・・・ PICの悲しみ»

コメント

コメントの投稿













管理者にだけ表示を許可する


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。