目次
前
次
食器乾燥機タイマー
15年以上使っている食器乾燥機のタイマーが
おかしくなりました。
ゼンマイを利用した、超アナログ式メカタイマーなので
カム部分が摩滅して使えなくなりました。
食器乾燥機は、3度の食事の後に使うので、マイコンを
利用して、スイッチを押すと通電し、10分後に切断と
いう仕様を考えました。
AC100Vの電源を接続、切断するのでリレーを利用し
通電の音が聞こえるようにします。
手持ちの部品をかき集めて簡単に作りたいので
ブロック図を描いて考えます。
ブロック図から回路図を作成。
回路ができたなら、基板上に部品を半田付けしました。
(リレーは接点容量が2倍以上のデバイスを利用)
ファームウエアは以下。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
#define XCOUT PORTA.F0
#define LTICK PORTA.F1
#define ITICK PORTA.F2
#define OFF 0
#define ON OFF+1
#define MASKFF 0xff
typedef union {
struct {
unsigned B7:1;
unsigned B6:1;
unsigned B5:1;
unsigned B4:1;
unsigned B3:1;
unsigned B2:1;
unsigned B1:1;
unsigned B0:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP xflags ;
#define XFLAG xflags.BIT.B0
#define EFLAG xflags.BIT.B1
#define TFLAG xflags.BIT.B2
volatile UWORD xcnt ;
volatile UBYTE ycnt ;
volatile UBYTE zcnt ;
volatile UWORD xinterval ;
volatile UBYTE ssft ;
volatile UBYTE tmp ;
/* function prototype */
void init_usr(void);
/* interrupt handler */
void interrupt(void)
{
/* generate 2ms */
if ( INTCON.TMR0IF == ON ) {
/* clear flag */
INTCON.TMR0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* increment */
xcnt++ ;
ycnt++ ;
/* impress */
if ( (ycnt & 1) ) { ITICK = ON ; }
else { ITICK = OFF; }
/* set TFLAG (2ms) */
TFLAG = ON ;
/* judge */
if ( xcnt == 500 ) {
/* set flag */
XFLAG = ON ;
/* clear */
xcnt = 0 ;
}
}
}
void main(void)
{
/* initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* timer handling (2ms) */
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* shift register */
ssft <<= 1 ;
/* mask */
ssft &= 3 ;
/* get trigger */
tmp = PORTA ;
tmp ^= MASKFF ;
/* ? click */
if ( tmp & 0x20 ) { ssft |= 1 ; }
/* judge */
if ( ssft == 1 ) {
if ( EFLAG == OFF ) {
/* set flag */
EFLAG = ON ;
/* set signal */
XCOUT = ON ;
/* 10x60 = 10 minutes */
xinterval = 600 ;
}
}
}
/* timer handling (1sec) */
if ( XFLAG == ON ) {
/* clear flag */
XFLAG = OFF ;
/* decrement */
if ( EFLAG == ON ) {
xinterval-- ;
if ( xinterval == 0 ) {
EFLAG = OFF ;
XCOUT = OFF ;
} else {
/* monitor */
zcnt++ ;
if ( (zcnt & 1) == ON ) { LTICK = ON ; }
else { LTICK = OFF ; }
}
} else {
LTICK = EFLAG ;
}
}
}
}
/* define function body */
void init_usr(void)
{
/* select 1MHz */
OSCCON = (0x0b << 3) | 0x03 ;
/* disable A/D converter */
ADCON0.ADON = OFF ;
ADCON2 = 0 ;
ANSELA = 0 ;
/* disable D/A converter */
DACCON0 = 0 ;
DACCON1 = 0 ;
/* disable compare module */
CM1CON0.C1ON = OFF ;
CM1CON0.C1OE = OFF ;
/* I/O state */
PORTA = 0x00 ;
/* I/O directions */
TRISA = 0x38 ; /* bit0,1,2 as output , others as input */
/* initialize timer 0 */
{
/*
1MHz (Fosc)
Fosc/4 = 250kHz
125kHz/4 = 125kHz prescaler = 1:2
*/
OPTION_REG = 0x00 ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* enable timer0 overflow interrupt (500Hz) */
INTCON.TMR0IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flags */
xflags.DR = 0 ;
/* initialize variables */
xcnt = 0 ;
ycnt = 0 ;
zcnt = 0 ;
xinterval = 0 ;
ssft = 0 ;
tmp = 0 ;
}
スイッチの状態は、500Hzのインターバルで取り込んでL→Hと
変化したならば、クリックと判断しています。
10分間のカウントは、変数xintervalの値を1秒ごとの
割込みで−1して実現。
スイッチと一体化されているLEDを、動作中に点滅させています。
目次
前
次