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.)
Hope your help.
— In Japanese
PIC12F629にモーメンタリースイッチを取り付けて、オン、オフしたいと考える人は多いと思う。
ずーっとコーディング例を調べていたけれども具体的なものはなかった。
私の開発したサンプルを置いておく。
以下、前提情報
- まず、PIC12F629の特性に注目する。
PORT3はリセットもしくは入力専用ポートとしてつかわれる。 - PORT3はそのため他のポートと違って、プログラムでプルアップ(抵抗を介して電圧をかける)できない
- ポートの変化による割り込みは、通常はGIEをオンにすると割り込みがかかる
- ポートの変化による割り込みは、SLEEP中はGIEをオンにしなくてもポート変化割り込みの設定をしていれば起きる。この時、割り込みルーチンには飛ばない
- 確認のために記しておくが、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.