テクノロジー遊び

How to toggle on/off momentary pushbutton with PIC12F629

Do you think adding on/offf switch on pic12F629 ?

One of the best way is using interruption.

Many developers had made this type of question on the net.

But I have never found any sample source code. Most of all people just give suggestions.

Therefore, I put here my sample source code for other developers.

It was not easy. For example, sw_count variable is from my experience.

Switch part schematics is as follows (Xtal is not mandatory)

(9/21/2016: For long bouncing switch, wait is inserted.)

hardware

Hope your help.

— In Japanese
PIC12F629にモーメンタリースイッチを取り付けて、オン、オフしたいと考える人は多いと思う。

ずーっとコーディング例を調べていたけれども具体的なものはなかった。

私の開発したサンプルを置いておく。

以下、前提情報

  1. まず、PIC12F629の特性に注目する。
    PORT3はリセットもしくは入力専用ポートとしてつかわれる。
  2. PORT3はそのため他のポートと違って、プログラムでプルアップ(抵抗を介して電圧をかける)できない
  3. ポートの変化による割り込みは、通常はGIEをオンにすると割り込みがかかる
  4. ポートの変化による割り込みは、SLEEP中はGIEをオンにしなくてもポート変化割り込みの設定をしていれば起きる。この時、割り込みルーチンには飛ばない
  5. 確認のために記しておくが、GIEをオンにしてSLEEPすると起きてから割り込みルーチンに飛ぶ
/*
 *
*/
#include <xc.h>
// #pragma config statements should precede project file includes.
// CONFIG
#pragma config FOSC = HS        // (HS oscillator: High speed crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-Up Timer Enable bit (PWRT enabled) DO NOT ON
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled) DO NOT USE
#pragma config CP = ON          // Code Protection bit (Program Memory code protection is enabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#define _XTAL_FREQ 10000000     
#define BTN GPIO3 // Pic12F629 use this port as MCLR, but I want to use on/off switch.

volatile unsigned int sw_count;
volatile unsigned int req_sleep; // sleep request flag

// main
void main(void){
//Initialization
    
    CMCON = 7; //GPIO use all digital port

    TRISIO = 0b00001000; //GPIO port3 is input, others output
    IOC = 0b00001000; // port3 interruption enable
    GPIO = 0b00000000; //GPIO initialize
    
    GPIE = 1; // INTCON port interrupt enable
    INTEDG = 0; // pin down, raise interrupt
    GIE = 0;
    __delay_ms(500);
    LED = 0;
    req_sleep = 1;
    
    while(1){
        if (req_sleep == 1){
            GIE = 0; // After SLEEP, for waking up, you don't need GIE up.
                    // And if you GIE is off, interruption routine is not inserted.
            __delay_ms(400); // wait for chattering
            sw_count = 0;
            req_sleep = 0; // SLEEP request reset
            SLEEP();
            NOP();
            __delay_ms(300);
            GIE = 1; // for switch on detection during running. 
        }
     
     /*
      * here is main work.
      */
    }
}


void interrupt ISR(void){
    char temp;
    GIE = 0;

    if (GPIF){
       temp = GPIO; // Read for synchronize status.
       GPIF = 0; // Once off to protect interruption
        
       sw_count++; // chattering count
       if (sw_count >2){ // Tentative value 3 
                req_sleep = 1; // Enough. DO NOT allow interruption any more
        } else {
          GIE = 1; // Still allow interruption
        }
       
    }

}

If you know better code, please let me know.

関連記事

  1. IOTのセキュリティ

  2. PICでwaitのループを簡単に作る方法

  3. Arduino Firmata Visual Basic .NET…

  4. ウィルスMiraiがIOTデバイスにとり憑く?

  5. M1 Mac(Monterey)にm5stackのための開発環境を

  6. マイクロプロセッサーボード

  7. CodeIgniterの知られざる基本

  8. M5StickCを時計に

記事をプリント