/*
* File: 4modeswitch.c
* Author: hage no ossan dame ningen
* DEVICE = 16F88
* TOOLS xc8 v2.10 MPLAB X IDE 5.25 PICKIT3 win10 core i3 LGA1150 1F DeskTopPC jitaku
* Created on 2019/09/28, 16:13(本日未使用MACアドレスPCへの新規ダウンロードなのであと60日は最適化最大?)
*/
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#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 // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB3 // CCP1 Pin Selection bit (CCP1 function on RB3)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode disabled)
#define _XTAL_FREQ 8000000
#define ButtonCurrentState RA0 // ← ***追加*** RA0の代わりに単語を使用する
void main(void) {
OSCCON = 0b01110000; // 内蔵クロックの周波数を8MHzに設定
PORTA = 0x00; // PORTAを初期化
PORTB = 0x00; // PORTBを初期化
TRISA = 0x01; // PORTA0(第17ピン)を入力に設定
TRISB = 0x00; // PORTBを全ピン(第6-13ピン)出力に設定
ANSEL = 0x00; // A/D変換を無効化
ADCON0 = 0x00;
ADCON1 = 0x00;
int i;
for (i = 0; i < 6; i++) {
PORTB = 0b00000001; //以下、プログラムがちゃんと動き出したことの確認
__delay_ms(50); //最初の4bitは2SC1815を経てメカニカルリレーへ。
PORTB = 0b00000010; //後ろの4bitは抵抗510オームを経てLED直結
__delay_ms(50); //リレーは倍率の違うOPアンプ回路の出力を一つだけ選択する
PORTB = 0b00000100; //ロータリースイッチは接点がすぐだめになるので
__delay_ms(50);
PORTB = 0b00001000;
__delay_ms(50);
PORTB = 0b00000100;
__delay_ms(50);
PORTB = 0b00000010;
__delay_ms(50);
}
PORTB = 0b00000001;
__delay_ms(50);
PORTB = 0b00001111; //合計80mAほど(<200mA)
__delay_ms(500);
PORTB = 0b10001000;
// ===============以下修正済===============
uint8_t ButtonChangeTime = 0; // int → unsigned char → uint8_t
uint8_t ModeSelect = 0;
bool ButtonPreviousState = 0; // 0 or 1 なので1ビット型でよい
while (1) {
__delay_ms(5); //←タイマーに置き換える if(timer){...}
if (ButtonCurrentState && !ButtonPreviousState) { //OFFからONの判定 !をつけると==0として扱える
//BottonCurrentStateが真かつ(&&) ButtonPreviousStateが偽の場合
//なおこの書き方は5chのスレがなぜか荒れるので注意する(荒れる !ButtonPreviousState 荒れない ButtonPreviousState==0)
ButtonChangeTime++; //ButtonChangeTime = ButtonChangeTime + 1 と同じ意味
if (ButtonChangeTime == 4) { // 20msチャタリング&ノイズ防止
ButtonChangeTime = 0;
ButtonPreviousState = 1;
ModeSelect++;
if (ModeSelect == 1) {
PORTB = 0b00000010;
} else if (ModeSelect == 2) {
PORTB = 0b00000100;
} else if (ModeSelect == 3) {
PORTB = 0b00001000;
} else if (ModeSelect == 4) {
PORTB = 0b00010000;
ModeSelect = 0; // if (ModeSelect == 5) {ModeSelect = 1;}の代わり
}
}
} else if (!ButtonCurrentState && ButtonPreviousState) { // ONからOFFの判定
// ButtonChangeTime++; 省略して↓のIF内で同様の処理を行う
if (++ButtonChangeTime == 20) { // 100msチャタリング&連続押し防止()
ButtonChangeTime = 0;
ButtonPreviousState = 0;
}
} else { //ButtonCurrentStateとButtonPreviousStateが同じ場合の処理 ONからON もしくは OFFからOFF
ButtonChangeTime = 0; //誤動作防止用のタイマーをリセットする
}
}
}