最近のお買い物

February 17 [Fri], 2017, 21:49
アジアンマーケットを利用するメリットは言うまでもなくその価格ですが、デメリットは、(品質におけるリスクをさておくとすれば)やはりその納期の長さではないでしょうか。

概ね、2週間を見込まねばならないわけですが、この2週間というのが曲者で、よほど準備万端でなければ発注の動機そのものを忘れてしまったり、ずっと待ってるわけじゃないので、物が到着する前に代替案で問題が解決してしまって発注の意味そのものが無くなってしまったり〜などなど。
次にマイブームが来た時のために置いてはいるんですが、なんとなく使えそうで確たる目的も無く、ただ値段につられて買ったものも数知れず。
これらはそんな一例です。(デッドストック言うな

以下のほとんどをHiLetgoで購入しました。
1/16発注。同日 ChinaPost にて発送の連絡。1/30と配達予告。
17TRACK で追跡できました。
予告より早い到着でした。
梱包には問題ありません。

PICのテストをブレッドボードで行う際に、5Vと3.3Vの電源を都度用意するのが面倒くさかったので、便利そうな電源を購入。
このままブレッドボードに突き刺せばコモンラインに5Vと3.3Vが供給されます。
7805などのシリーズレギュレータ使って作るより安いです。
出力側にバルクコンデンサが入っていないので、適当なコンデンサを追加して使うと良いでしょう。
ピンヘッダがブレッドボード用にやや細身のタイプが使われているようなので、上から電源を取る場合は接触不良を起こしやすいかもしれません。
そちらが電源取り出しのメインになる場合は、ピンヘッダを交換しておきましょう。
購入時の価格は¥115でした。


件の順次電源投入回路をArdinoでやったらどうなるのかなと。
ただ、手持ちの正規版unoでやるのはもったいないので、互換品を購入してみました。
ピンヘッダが取り付けられていないので、自分ではんだ付けする必要がありますが、中華製でスルーホールにまともにはんだ付けされているものを未だ見たことがないので、この方が二度手間かけなくて済みます。
LチカOKでした。
購入時の価格は¥330でした。


nano用のIOシールド使えばユニバーサル基板で一から組むよりより安いよねと。
これも基板にはんだ付けされていませんので、安心(?)です。
基板の裏にゴム足を貼り付けて使ってます。
購入時の価格は¥150でした。



するってーと、あんなものやこんなものまで、こんな値段で!と、勢いで購入。
いずれもピンヘッダが付属していませんので安心(?)です。
私はブレッドボード用のスリムピンヘッダを取り付けました。
購入時の価格は¥250でした。


購入時の価格は¥190でした。


購入時の価格は¥195でした。


リボンケーブルの両端にコネクタピンを圧着しただけのものですが、普通に使えます。
購入時の価格は¥120でした。


購入時の価格は¥110でした。


レーザーポインタ式猫じゃらし作ろうかなと思いまして。
購入時の価格は¥250でした。
不良品が1こだけ混ざってました。


DIN規格では”黒”ですが。
ラインナップにはあるのに、何故か検索に引っかからないのでみとりあえず緑色。
購入時の価格は¥496でした。


テクテックで購入しました。
購入時の価格は¥537でした。
発注後翌々日に到着。
さすが、国内発送です。
消耗品につき、そこそこのクオリティがあればいいです。


テクテックで購入しました。
購入時の価格は¥465でした。


United TiffanyJP で購入しました。
購入時の価格は¥146でした。
ChanaPostでしたが予定よりも5日も早い到着。やればできる子。
というか、追跡してみると日本の税関で止まっている期間が長いです。
商品に異常は無く、数量も正確でした。
ただし、普通郵便扱いであったにもかかわらず、過剰梱包でポストイン出来ず、郵便屋さんに迷惑をかけてしまいました。

XC8:並列処理のタイマ回路(その2)

February 12 [Sun], 2017, 18:08
TMR0,1,2を併用して複数の割り込みタイミングを作ろうとしたらなかなかまともに動かない。
色々試行錯誤はしてみたが、面倒くさくなったので、一つのタイマで周期の異なるクロックビットを作って、それをカウントする方法を考えてみた。
これは三菱シーケンサのQシリーズでいうところの特殊レジスタSM4**に相当するもの。
その中でもよく使う0.01,0.1、1秒周期のものを作ってみた。
で、フリッカ回路なんかはこれ一発で実現出来る。

このプログラムだとmainの実行周期は1msec以下なので、それ以下の周期で割り込みが発生しなければSV−1カウント以内の誤差で動くと思う。
数時間とか数日のロングタイマの制作も、大雑把な精度でよければ同じ手法で出来ると思う。
実際に走らせた様子がこちら。
設定値とスタートのタイミングが同じであるにも関わらず、タイマのクロックの差が出てる。
これでも、タイマ割り込みを複数もたせた場合よりずっと安定しているんだから面白い。


尚、特記事項として、ソース朱書きのところ。
1.データメモリを節約するため、構造体の一部にbit型を使用した。
→ちょっとだけ効果があった。
2.定常プログラムでビットの立ち上がりをカウントするために工夫した。
→シーケンサでやる定石回路の応用。
3.静的ローカル変数を使って、割り込み処理の中でループさせないようスキャン分割を試みた。
→割り込み処理が入った時のオーバーヘッドがかなり改善した。

判ったのは次のようなもの。
1.複数のタイマを併用する場合よりも安定する。
→タイマ定数を変更すると割り込みのタイミングの変わるので、実行順序の管理がとってもめんどくさい。
2.タイマの長時間化を狙ってカウンタにlong型を使うと、スキャンが異様に遅くなる。
→割り込みクロックに影響が出るレベル?見た目にもかなり遅くなった。

/* 割り込みを使った並列(風)タイマ回路習作
 * File:   PG2-0a.c
 * Author: http://yaplog.jp/kazuikazui/
 * Device: PIC12F683
 * Created on 2017/02/11, 22:11
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe CLK Monitor Enabled bit (Fail-Safe CLK Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

/*** システムクロック  ****/
#define _XTAL_FREQ 8000000  //8MHz Internal OSC
bit SM409;                  // 0.01秒クロック
bit SM410;                  // 0.1秒クロック
bit SM412;                  // 1秒クロック

/*** グローバル変数定義  ****/
struct {                    //10msタイマ(SM409使用)最大655.35秒
    unsigned int PV[3];     //タイマ現在値
    unsigned int SV[3];     //タイマ設定値
    unsigned CLK : 1;       //タイマクロック
} TimH;

struct {                    //0.1sタイマ(SM410使用)最大6553.5秒
    unsigned int PV[3];     //タイマ現在値
    unsigned int SV[3];     //タイマ設定値
    unsigned CLK : 1;       //タイマクロック
} TimM;

struct {                    //1sタイマ(SM412使用)最大65535秒
    unsigned int PV[3];     //タイマ現在値
    unsigned int SV[3];     //タイマ設定値
    unsigned CLK : 1;       //タイマクロック
} TimL;

bit M1;
char C1;

void main(void) {
    /* I/O 設定 */
    OSCCON = 0b1110000;         // Internal Fosc=8MHz=125nsec(最速値)
    ANSEL  = 0b0000000;         // アナログ入力 無し
    CMCON0 = 0b00000111;        // コンパレータ無効化
    TRISIO = 0b111000;          // GP3,4,5が入力、他は出力設定
    WPU    = 0b110000;          // プルアップビット GP4,5
    nGPPU  = 0b000000;          // GPIOプルアップ有効化
    
    /* TMR2初期設定 5msec周期  PIC12F683 Data Sheet による */
    /* TMRsec =(PR2+1) * PreScara * PostScara * 4 / FOSC[Hz] */
    /* = (249+1) * 4 * 10 * 0.5μsec = 5msec */
    PR2 = 249;                  // TMR2目標値セット
    T2CON = 0b01001101;         // ポストスケーラ10回、プリスケーラ1/4

    /* 割り込み許可 PIC12F683 Data Sheet による */
    TMR2IE = 1;                 // TMR2割り込み許可
    PEIE = 1;                   // Peripheral Interrupt Enable bit
    GIE = 1;                    // Global Interrupt Enable bit
    
    /* グローバル変数初期化 */
    GPIO=0;
    M1 = 0;
    C1 = 0;
    TimH.PV[0] = 0;
    TimM.PV[0] = 0;
    TimL.PV[0] = 0;

    TimH.SV[0] = 1000;  // タイマ設定値 10ms*1000=10sec
    TimM.SV[0] = 100;   // タイマ設定値 100ms*100=10sec
    TimL.SV[0] = 10;    // タイマ設定値  1sec*10=10sec
    
    while(1) {
        
        if (GP5 == 0){      // SET M1
            M1 = 1;
        }
        if (GP4 == 0){      // RST M1
            M1 = 0;
        }
        
        if (M1 == 1) {
            
            if (TimH.PV[0] >= TimH.SV[0]){      // タイムアップ判定     
                GP0 = 1;
            }
            if (SM409 == 1 && TimH.CLK != SM409){ // SM409クロックの立ち上がりをカウントする
                if (TimH.PV[0] < TimH.SV[0]){       // オーバーフローしてゼロになってしまわないように
                    TimH.PV[0]++;
                }
            }
            TimH.CLK = SM409;

            if (TimM.PV[0] >= TimM.SV[0]){          // タイムアップ判定     
                GP1 = 1;
            }
            if (SM410 == 1 && TimM.CLK != SM410){ // SM410クロックの立ち上がりをカウントする
                if (TimM.PV[0] < TimM.SV[0]){       // オーバーフローしてゼロになってしまわないように
                    TimM.PV[0]++;
                }
            }
            TimM.CLK = SM410;
            
            if (TimL.PV[0] >= TimL.SV[0]){          // タイムアップ判定     
                GP2 = 1;
            }
            if (SM412 == 1 && TimL.CLK != SM412){ // SM412クロックの立ち上がりをカウントする
                if (TimL.PV[0] < TimL.SV[0]){       // オーバーフローしてゼロになってしまわないように
                    TimL.PV[0]++;
                }
            }
            TimL.CLK = SM412;

        }
        else{
            TimH.PV[0] = 0;
            TimM.PV[0] = 0;
            TimL.PV[0] = 0;
            GP0 = 0;
            GP1 = 0;
            GP2 = 0;
        }
        
        /* スキャン周期測定用 */
/*
        C1 = C1 * -1 + 1;
        GP0 = C1;
*/
    }
}

/**************************************
*  割り込み処理関数
***************************************/
void interrupt ISR(void) {          //関数名は任意で可
    
    static char count0,count1;      //静的なローカル変数
    static unsigned char count2;
    
    /* TMR2:5msec周期の割り込み */
    if(TMR2IF) {
        TMR2IF = 0;                 //割り込みフラグクリア
        
        /* SM409の処理(0.01secクロック) */
        count0 = count0 * -1 + 1;   // 割り込みの都度0/1反転
        SM409 = count0;
        
        /* SM410の処理(0.1secクロック) */
        count1++;
        if (count1 >= 10){          // カウンタ0(20)〜9:LOW、10〜19:HIGH
            SM410 = 1;
        }
        if (count1 >= 20){
            count1 = 0;
            SM410 = 0;
        }
        
        /* SM412の処理(1secクロック) */
        count2++;
        if (count2 >= 100){          // カウンタ0(200)〜99:LOW、100〜199:HIGH
            SM412 = 1;
        }
        if (count2 >= 200){
            count2 = 0;
            SM412 = 0;
        }
        
    }
}

XC8:モーメンタリ→オルタネイト化

February 08 [Wed], 2017, 20:20
こちらの本にモーメンタリスイッチをオルタネイト化するプログラムの作例があった。
これ、実戦でもよく使う大事な回路。
が、ちょっと残念なことになっている。(´・ω・`)



サンプルソースここから

/* たのしくできるPIC12F実用回路作例より改変
 * File:   PG2-2.c
 * Author: http://yaplog.jp/kazuikazui/
 * Device: PIC12F683
 * Created on 2017/02/05, 21:06
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Tim Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Tim Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include 

/*** システムクロック  ****/
#define _XTAL_FREQ 8000000      //8MHz Internal OSC

void main(void) {
    /* I/O 設定 */
    OSCCON = 0b1110000;         // Internal Fosc=8MHz=125nsec(最速値)
    ANSEL  = 0b0000000;         // アナログ入力 無し
    CMCON0 = 0b00000111;        // コンパレータ無効化
    TRISIO = 0b111000;          // GP3,4,5が入力、他は出力設定
    WPU    = 0b110000;          // プルアップビット GP4,5
    nGPPU  = 0b000000;          // GPIOプルアップ有効化

    /* グローバル変数初期化 */
    GPIO=0;
    
    if(GP5==0){
        GP0 = 1;
  __delay_ms(300);
  while(1)
  {
   if(GP5 == 0){
    GP0 = 0;
    __delay_ms(300);
    break;
   }
  }
    }
}


ここまで

これだと、プログラムは簡単でいいのだけれど、例によってLEDがONしている間(すなわちオルタネートスイッチがONしている間)、何も出来ない。
〜delayは使いやすいが、その間プログラムが停止しているということを忘れてはならない。

次に、スイッチが押し続けられていたらフリッカ回路になってしまう。
〜ユーザーに何かを期待してはいけない。

そして、スキャンが遅い。
〜スイッチを押し続けた場合、トータルで600msもの間、止まっている。

結論:これではオルタネイトとは呼べない。

そこで、1.確実にワンプッシュ毎にON/OFFが切り替わり、かつ、2.長押ししても点滅せず、かつ、3.点灯中も他の処理が出来る回路を考えてみた。

一応、この3点は満たしている。
チャタリング対策の遅延回路にはdelayに代えて割り込みを使用したタイマにしたので、スキャン速度はそこそこ早く、並列処理っぽくなったと思う。


/* モメンタリ→オルタネイト変換回路
 * File:   PG2-2b.c
 * Author: http://yaplog.jp/kazuikazui/
 * Device: PIC12F683
 * Created on 2017/02/05, 21:06
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Tim Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Tim Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

/*** システムクロック  ****/
#define _XTAL_FREQ 8000000      // 8MHz Internal OSC

/*** グローバル変数定義  ****/
bit Pls1,PlsFlg1;               // ワンスキャンオンパルス
char M1;                        // 内部補助リレー
struct {                    //構造体と配列変数の例
    unsigned int PV[10];    //タイマ現在値
    unsigned int SV[10];    //タイマ設定値
    unsigned char In[10];   //タイマ入力
    unsigned char Out[10];  //タイマ出力
    } Tim;

void main(void) {
    /* I/O 設定 */
    OSCCON = 0b1110000;         // Internal Fosc=8MHz=125nsec(最速値)
    ANSEL  = 0b0000000;         // アナログ入力 無し
    CMCON0 = 0b00000111;        // コンパレータ無効化
    TRISIO = 0b111000;          // GP3,4,5が入力、他は出力設定
    WPU    = 0b110000;          // プルアップビット GP4,5
    nGPPU  = 0b000000;          // GPIOプルアップ有効化

    /* TMR2初期設定 10msec周期  PIC12F683 Data Sheet による */
    /* TMRsec =(PR2+1) * PreScara * PostScara * 4 / FOSC[Hz] */
    /* = (249+1) * 16 * 5 * 0.5μsec = 10msec */
    PR2 = 249;                  // TMR2目標値セット
    T2CON = 0b00101110;         // ポストスケーラ5回、プリスケーラ1/16

    /* 割り込み許可 PIC12F683 Data Sheet による */
    TMR2IE = 1;                 // TMR2割り込み許可
    PEIE = 1;                   // Peripheral Interrupt Enable bit
    GIE = 1;                    // Global Interrupt Enable bit

    /* グローバル変数初期化 */
    GPIO = 0;
    PlsFlg1 = 0;
    M1 = 0;
    Tim.SV[0] = 5;              // Tim0設定値

    while(1) {
        /* GP5入力→PLS化 */
        if(GP5 == 0){
            Tim.In[0] = 1;      // チャタリング対策タイマ
            if (Tim.Out[0] == 1){
                if (PlsFlg1 == 0){
                    Pls1 = 1;
                }
                else {
                    Pls1 = 0;
                }
                PlsFlg1 = 1;
            }
        }
        else {
            Tim.In[0] = 0;
            Pls1 = 0;
            PlsFlg1 = 0;
        }
        
        /* 実行する都度反転 */
        if (Pls1 == 1){         // 1スキャンのみ実行
            M1 = M1 * -1 + 1;   // 0/1反転
        }
        
        GP0 = M1;
        
        /* 並列処理確認用 */
        GP2 = 0;
        if (GP4 == 0) {
            GP2 = 1;
        }
    }
}

/**************************************
*  割り込み処理関数
***************************************/
void interrupt ISR(void) {          //関数名は任意で可   
    /* TMR2:10msec周期の割り込み */
    unsigned int n;
    if(TMR2IF) {
        TMR2IF = 0;                 //割り込みフラグクリア
        /* Tim[n]処理 */
        for (n=0;n<=9;n++){
            Tim.Out[n] = 0;
            if (Tim.In[n] == 1) {
                Tim.PV[n]++;
                if (Tim.PV[n] >= Tim.SV[n]) {
                    Tim.Out[n] = 1;                
                }
            }
            else {
                Tim.PV[n] = 0;
            }
        }
    }
}



ちなみに、ハードはこちらです。


※参考図書

XC8:並列処理のタイマ回路(その1)

February 06 [Mon], 2017, 21:36
何がやりたいかというと。

シーケンサ(三菱電気の場合)だとタイマはこんなかんじ。


要するにハードのタイマーをシミュレートしたもので、デバイス番号(T0)と設定値(K10)を渡してトリガ(X30)を立てるとバーチャルコイルが励磁され、タイムアップでそのデバイス番号のフラグ(T0)が立つというもの。
この例では入出力を3組書いているが、基本、並列処理なのでタイマカウント中も他の処理をしながら待つことが出来る。
回路はスキャンで上から順にナメていき、最後まで行って先頭に戻る際に入出力のバッファ書込みが行われるので、各タイマは並列で動き、出力は独立して動作している(ように見える)。
タイマのカウントはバックグラウンドでやってるイメージ。
こんなふうに簡単に動いてくれるのは、OSさまさまだ。

PICでタイマというとまず紹介されるのが_delay()とか。
例えばこんなかんじ。

/* たのしくできるPIC12F実用回路作例より改変
 * File:   PG2-1.c
 * Author: http://yaplog.jp/kazuikazui/
 * Device: PIC12F683
 * Created on 2017/01/29, 22:11
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Tim Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Tim Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

/*** システムクロック  ****/
#define _XTAL_FREQ 8000000      //8MHz Internal OSC

void main(void){
    /* I/O 設定 */
    OSCCON = 0b1110000;         // Internal Fosc=8MHz=125nsec(最速値)
    ANSEL  = 0b0000000;         // アナログ入力 無し
    CMCON0 = 0b00000111;        // コンパレータ無効化
    TRISIO = 0b111000;          // GP3,4,5が入力、他は出力設定
    WPU    = 0b110000;          // プルアップビット GP4,5
    nGPPU  = 0b000000;          // GPIOプルアップ有効化

    /* グローバル変数初期化 */
    GPIO=0;
    
    while(1){
    
        if (GP5 == 0) {
            while(1) {

                GP0=1;
                GP1=0;
                __delay_ms(500);

                GP0=0;
                GP1=1;
                __delay_ms(500);

                GP2 = 0;
                if (GP4 == 0) {
                    GP2 = 1;
                }

                if (GP3 == 0) {
                    GPIO=0;
                    break;
                }
            }
        }
    }
}


PICはOSがないので、書かれた通りにベタに動く。
これだと、タイムアップするまで処理が止まるので面白くない
この例でも、GP3のスイッチを押して点滅を止めることが出来るのは1秒に1回のワンチャンス
判定部が実行されているタイミング以外でスイッチが押されても無視されるということになる。
途中で止まらないのはいかがなものか。

なので、割込を使って並列処理っぽく動くタイマを作ってみた。

きっと、とっくの昔に誰かが作っているのだろうけど。
「PIC タイマ」とかで検索してもなかなか思ったような回路が出てこないのでしかたなく。

以下ソース

/* 割り込みを使った並列(風)タイマ回路習作
 * File:   PG2-1a.c
 * Author: http://yaplog.jp/kazuikazui/
 * Device: PIC12F683
 * Created on 2017/02/13, 22:11
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Tim Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Tim Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include 

/*** システムクロック  ****/
#define _XTAL_FREQ 8000000      //8MHz Internal OSC

/*** グローバル変数定義  ****/
struct {                        //構造体と配列変数の例
    unsigned int PV[10],SV[10]; //タイマ現在値・設定値
    char In[10],Out[10];        //タイマ入・出力
    } Tim;

char C1;                        //スキャン周期計測用
    
void main(void) {
    /* I/O 設定 */
    OSCCON = 0b1110000;         // Internal Fosc=8MHz=125nsec(最速値)
    ANSEL  = 0b0000000;         // アナログ入力 無し
    CMCON0 = 0b00000111;        // コンパレータ無効化
    TRISIO = 0b111000;          // GP3,4,5が入力、他は出力設定
    WPU    = 0b110000;          // プルアップビット GP4,5
    nGPPU  = 0b000000;          // GPIOプルアップ有効化
                
    /* TMR2初期設定 10msec周期  PIC12F683 Data Sheet による */
    /* TMRsec =(PR2+1) * PreScara * PostScara * 4 / FOSC[Hz] */
    /* = (249+1) * 16 * 5 * 0.5μsec = 10msec */
    PR2 = 249;                  // TMR2目標値セット
    T2CON = 0b00101110;         // ポストスケーラ5回、プリスケーラ1/16

    /* 割り込み許可 PIC12F683 Data Sheet による */
    TMR2IE = 1;                 // TMR2割り込み許可
    PEIE = 1;                   // Peripheral Interrupt Enable bit
    GIE = 1;                    // Global Interrupt Enable bit

    /* グローバル変数初期化 */
    GPIO=0;
        
    while(1) {
        if (GP5 == 0) {
            GP0 = 1;
            GP1 = 0;
            Tim.SV[0] = 50; // Tim0設定値
            Tim.In[0] = 1;
            while(1) {
                if (Tim.Out[0] == 1) {
                    GP0 = 0;
                    Tim.SV[1] = 50; // Tim1設定値
                    Tim.In[1] = 1;
                    Tim.In[0] = 0;
                }
                if (Tim.Out[1] == 1) {
                    GP0 = 1;
                    Tim.SV[0] = 50; // Tim0設定値
                    Tim.In[0] = 1;
                    Tim.In[1] = 0;
                }
                    
                GP1 = 0;            // SW2をonにすればいつでも点灯
                if (GP4 == 0) {
                    GP1 = 1;
                }
                    
                C1 = C1 * -1 + 1;   // スキャン周期測定用
                GP2 = C1;
                
                if (GP3 == 0) {
                    GPIO=0;
                    Tim.In[0] = 0;
                    Tim.In[1] = 0;
                    break;
                }
                
            }
        }
    }
}

/**************************************
*  割り込み処理関数
***************************************/
void interrupt ISR(void) {          //関数名は任意で可   
    /* TMR2:10msec周期の割り込み */
    char n;
    if (TMR2IF) {
        TMR2IF = 0;                 //割り込みフラグクリア
        /* Tim[n]処理 */
        for (n = 0; n < sizeof(Tim.SV) / sizeof(Tim.SV[0]); n++){   //配列要素数自動計算
            Tim.Out[n] = 0;
            if (Tim.In[n] == 1){
                Tim.PV[n]++;
                if (Tim.PV[n] >= Tim.SV[n]){
                    Tim.Out[n] = 1;                
                }
            }
            else {
                Tim.PV[n] = 0;
            }
        }
    }
}


使い方は簡単で、Tim.SV[n]に設定値を入れておいて、Tim.In[n]をセット。
タイムアップするとTim.Ou[n]が1になる。

汎用化を狙って配列変数でメモリを確保したのは良かったが、タイマたった10個分でPIC12F683のデータメモリが50%以上食われてしまう。
.Inと.Outはフラグなので、型はbitでいいのだけれど、デバイスの間接指定の方法がわからんのでやむをえず char型。

delayを使った場合と違って、いつでも点滅を止めることが出来るし、点滅させながら任意のタイミングで赤LEDを点灯できます。

動作確認に使ったハードはこちら。
後の回路でも使うので保存版。

なお、今回の部品は全て秋月電子通商さんで調達しました。
いつもお世話になってます。m(_ _)m

※参考図書は次の2冊

ADVANTEST R6551 デジタルマルチメーター(その1)

January 25 [Wed], 2017, 23:29
ジャンク品を購入しました。
例によって勉強用です。

据え置き型のテスター。
取説が入手できることを確認した上で落札。(メーカーサイトでユーザー登録すれば日本語版の取説も無料で入手可能です)


5・1/2桁と、今となってはさほど高分解能でもないが、4線式の抵抗測定が出来るらしい。
スペックは次のようなもの。(いずれも英文版取説の抜粋)






GP-IBインターフェイスを標準で実装している本格派。
このインターフェイスを使ってリモート操作することも今後の課題の一つ。

さて、初見。
外観的にはくたびれているものの、致命的な損傷があるようには見えない。
物理的に衝撃を加えたような痕も見られないので、壊れているとしたら基板か電子部品ということになる。

出品者によると通電は可能だそうなので、電源ケーブルを繋いで通電してみた。
一見正常に表示されているようだが。。。いや、むしろ正常そのものだ。
どうやら電圧測定モードでプローブ短絡せずに表示を確認。→ランダムな数字が出ることから、故障していると勘違いしていたらしい。
らきーっ!
キャリブレーションすればこのまま使えそうだ。

だが、ここで一つ問題が。

〜ジャンクな電子工作&徒然落書き帳さまより〜
「さて、R6551デジボルの厄介な問題とは、内部にハンダ付けされている、バックアップ・リチューム電池だ。
なんと、動作に欠かせないファーム・ソフトなどの内部ソフトがこのバック・アップ・リチューム電池で賄われている、ということに起因する。
すなわち、このリチューム電池が無くなれば、本体全体が動かなくなってしまう。
簡単に電池交換などしない方が良い。
メーカー送りとなってしまう事になる。」



加えてメーカーでは既に修理も公正も受付終了
つまり、バッテリの寿命=メーターの寿命ってこと???




一方、取説にはこんな一文が。
そのまま解釈すると、「設定パラメータ 内蔵バッテリで保持されている。」
”もまた” とは書いてない。
これは逆を言えばバッテリの状態如何に関わらず、プログラムは消えないってことじゃないの?


よくよく見れば基板上にEP-ROMらしきものが載っており、電源喪失時に消えちゃまずいデータはこちらに書かれているように見える。


トリマ等の調整機構も見当たらないことから、バッテリでバックアップしているのはキャリブレーションの結果等ではないだろうか?と予想。
バックアップ用バッテリの寿命は約5年とのことなので、デッドストックで腐りかけてたバッテリも手元にあることだし、せっかくだから交換してみよう。
うまくいっても行かなくても、全て自己責任でやるしかなさそうだ。
(それ故、”ジャンク品”ということなのだが)

取説によるとプローブがちょっと特殊な仕様になっているようなので、メーカーさんに単品販売してもらえるかどうか問合せ中。
これがダメでも、HIOKIの4線式プローブを利用できるようにアタッチメントを作る予定。(´∀`)

※参考にさせていただいたページ
メーカー:株式会社エーデーシー(アドバンテストのOEM元)
ジャンクな電子工作&徒然落書き帳
snj_roseのホームページへようこそ










P R
Find more about Weather in Kobe, JP
Click for weather forecast
Find more about Weather in Kluang, MS
Click for weather forecast
Find more about Weather in Penang, MS
Click for weather forecast
プロフィール
  • プロフィール画像
  • アイコン画像 ニックネーム:かずい
  • アイコン画像 性別:男性
  • アイコン画像 現住所:兵庫県
読者になる
since 2006.11
無料で使えるプチアクセスカウンター中古マンション地図姫
カスタム検索

ご来訪ありがとうございました。
お帰りはぜひこちらからどうぞ。
↓↓↓↓↓↓↓

  にほんブログ村 バイクブログ カワサキへ
にほんブログ村
2017年02月
« 前の月    |    次の月 »
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
最新コメント
アイコン画像たろ餅
黙祷 (2017年01月18日)
アイコン画像通りすがり
怪しいLCRメータを買ってみた(その1) (2017年01月02日)
アイコン画像機械工作野郎
マイクロメータを修理してみる (2016年12月12日)
アイコン画像ンガゴー
PIC12F683を使った調光器 (2016年11月27日)
アイコン画像かずい
PIC12F683を使った調光器 (2016年11月25日)
アイコン画像ンガゴー
PIC12F683を使った調光器 (2016年11月25日)
アイコン画像高圧パルス発生器
パルス充電器の製作(その1) (2016年11月13日)