回路図
stopwatch回路図の説明をします。
ストップウォッチを操作するスイッチは3個で、SW1が【リセットスイッチ】、SW2が【スタートスイッチ】、SW3が【ストップスイッチ】です。
PICマイコンは8bitのPIC16F1933(U1)を使用しています。
7セグメントLED用ドライバはTD62083 (U2) で、8chのダーリントンシンクドライバです。
7セグメントLEDは、4桁カソードコモンタイプを2個使用し、8桁のストップウォッチです。使用するLEDにあわせてR1~R8の抵抗値を決定します。
水晶発振子は、8MHzです。
ソフトウエア
ソースコード
/*
* File: stop_watch.c
* Author: masan
*
* Created on 2017/02/19, 19:31
*/
//--------------- ハードウエア -------------------------------------------------
// RA0(2pin) in RESET_SWスイッチ
// RA1(3pin) in START_SWスイッチ
// RA2(4pin) in STOP_SWスイッチ
// RA3(5pin) out TEST1
// RA4(6pin) out TEST2
// RA5(7pin) out TEST3
// RA6(10pin) in OSC2
// RA7(9pin) in OSC1
// RB0(21pin) out 7セグメントLED b
// RB1(22pin) out 7セグメントLED f
// RB2(23pin) out 7セグメントLED a
// RB3(24pin) out 7セグメントLED g
// RB4(25pin) out 7セグメントLED c
// RB5(26pin) out 7セグメントLED DP
// RB6(27pin) out 7セグメントLED d ICSPCLK
// RB7(28pin) out 7セグメントLED e ICSPDAT
// RC0(11pin) out 7セグメント桁表示 s1
// RC1(12pin) out 7セグメント桁表示 ms100
// RC2(13pin) out 7セグメント桁表示 ms10
// RC3(14pin) out 7セグメント桁表示 ms1
// RC4(15pin) out 7セグメント桁表示 h1
// RC5(16pin) out 7セグメント桁表示 m10
// RC6(17pin) out 7セグメント桁表示 m1
// RC7(18pin) out 7セグメント桁表示 s10
// RE3(1pin) in MCLR
// Vdd(20pin)
// Vss(8pin,19pin)
// PIC16F1933 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
//*************************** 関数 *********************************************
void shutoff_LED(void); //LEDをすべて消灯する
void display_LED(void); //LED表示する
void display_ready(void); //レディ表示
unsigned char trans_7seg(unsigned char data); //バイナリデータを7セグメントLEDの表示データに変換する
void delay(void); //チャタリング防止delay
//************************* クローバル変数設定 **********************************
unsigned char ready_flag = 0; //1でレディ 0でノーマル
unsigned char start_flag = 0; //1でスタート 0でストップ
unsigned char ms1_reg = 0;
unsigned char ms10_reg = 0;
unsigned char ms100_reg = 0;
unsigned char s1_reg = 0;
unsigned char s10_reg = 0;
unsigned char m1_reg = 0;
unsigned char m10_reg = 0;
unsigned char h1_reg = 0;
unsigned char display_degit = 0; //LED表示の位置を表す
//***************************** ポートの定義 ***********************************
#define RESET_SW PORTAbits.RA0 //RESET_SWスイッチ
#define START_SW PORTAbits.RA1 //START_SWスイッチ
#define STOP_SW PORTAbits.RA2 //STOP_SWスイッチ
#define degit_ms1 PORTCbits.RC3 //7セグメント桁表示 mSec 1桁
#define degit_ms10 PORTCbits.RC2 //7セグメント桁表示 mSec 10の桁
#define degit_ms100 PORTCbits.RC1 //7セグメント桁表示 mSec 100の桁
#define degit_s1 PORTCbits.RC0 //7セグメント桁表示 秒 1桁
#define degit_s10 PORTCbits.RC7 //7セグメント桁表示 秒 10の桁
#define degit_m1 PORTCbits.RC6 //7セグメント桁表示 分 1の桁
#define degit_m10 PORTCbits.RC5 //7セグメント桁表示 分 10の桁
#define degit_h1 PORTCbits.RC4 //7セグメント桁表示 時 1桁
#define TEST1 PORTAbits.RA3 //TEST1
#define TEST2 PORTAbits.RA4 //TEST2
#define TEST3 PORTAbits.RA5 //TEST3
//********************** チャタリング防止delay **********************************
// 入力 なし
// 処理 チャタリング防止delay
// 出力 なし
//******************************************************************************
void delay(void){ //チャタリング防止delay
unsigned int x,y;
for(x = 0; x < 500; x++){
// for(y = 0; y < 5; y++){}
}
}
//************ バイナリデータを7セグメントLEDの表示データに変換する **************
// 入力 data
// 処理 バイナリデータを7セグメントLEDの表示データに変換する
// 出力 LED表示データ
//******************************************************************************
unsigned char trans_7seg(unsigned char data){ //バイナリデータを7セグメントLEDの表示データに変換する
unsigned char x;
switch(data){
case 0: x = 0xd7; break;
case 1: x = 0x11; break;
case 2: x = 0xcd; break;
case 3: x = 0x5d; break;
case 4: x = 0x1b; break;
case 5: x = 0x5e; break;
case 6: x = 0xde; break;
case 7: x = 0x17; break;
case 8: x = 0xdf; break;
case 9: x = 0x5f; break;
}
return x;
}
//***************** Timer2 割り込み処理 *****************************************
void interrupt ISR(void){
TEST1 = 1;
//カウントする
if(start_flag == 1){
ms1_reg++; //msec+1
if(ms1_reg == 10){
ms1_reg = 0; ms10_reg++; //10msec+1
if(ms10_reg == 10){
ms10_reg = 0; ms100_reg++; //100msec+1
if(ms100_reg == 10){
ms100_reg = 0; s1_reg++; //1sec+1
if(s1_reg == 10){
s1_reg = 0; s10_reg++; //10sec+1
if(s10_reg == 6){
s10_reg = 0; m1_reg++; //1minute+1
if(m1_reg == 10){
m1_reg = 0; m10_reg++; //10minute+1
if(m10_reg == 6){
m10_reg = 0; h1_reg++; //1hour+1
}
}
}
}
}
}
}
}
if(ready_flag == 1) display_ready(); //READY 表示
else display_LED(); //カウント表示する
PIR1bits.TMR2IF = 0; //タイマー2割り込みフラグクリア
TEST1 = 0;
}
//******************* READY 表示 ***********************************************
// 入力 s1_reg
// 処理 READYの表示を行う
// 出力
//******************************************************************************
void display_ready(void){
//-------------------- レディ表示 ------------------------------
switch(display_degit){
case 0: //hour 1の桁
degit_ms1 = 0; if(s1_reg == 0) PORTB = 0xdf; else PORTB = 0; degit_h1 = 1;
display_degit = 1;
break;
case 1: //Minute 10の桁
degit_h1 = 0; if(s1_reg == 1) PORTB = 0x17; else PORTB = 0; degit_m10 = 1;
display_degit = 2;
break;
case 2: //Minute 1の桁
degit_m10 = 0; if(s1_reg == 2) PORTB = 0xde; else PORTB = 0; degit_m1 = 1;
display_degit = 3;
break;
case 3: //Sec 10の桁
degit_m1 = 0; if(s1_reg == 3) PORTB = 0x5e; else PORTB = 0; degit_s10 = 1;
display_degit = 4;
break;
case 4: //Sec 1の桁
degit_s10 = 0; if(s1_reg == 4) PORTB = 0x1b; else PORTB = 0; degit_s1 = 1;
display_degit = 5;
break;
case 5: //mSec 100の桁
degit_s1 = 0; if(s1_reg == 5) PORTB = 0x5d; else PORTB = 0; degit_ms100 = 1;
display_degit = 6;
break;
case 6: //mSec 10の桁
degit_ms100 = 0; if(s1_reg == 6) PORTB = 0xcd; else PORTB = 0; degit_ms10 = 1;
display_degit = 7;
break;
case 7: //mSec 1の桁
degit_ms10 = 0; if(s1_reg == 7) PORTB = 0x11; else PORTB = 0; degit_ms1 = 1;
display_degit = 0;
break;
}
}
//******************* LED 表示 *************************************************
// 入力 display_degit
// 処理 display_degitの桁の表示を行う
// 出力 display_degit
//******************************************************************************
void display_LED(void){
unsigned x;
//-------------------- カウント表示 ----------------------------------------
switch(display_degit){
case 0: //hour 1の桁
x = trans_7seg(h1_reg) | 0x20; //バイナリデータを7セグメントLEDの表示データに変換する
degit_ms1 = 0; PORTB = x; PORTB = x; degit_h1 = 1; //LED 表示
display_degit = 1;
break;
case 1: //Minute 10の桁
x = trans_7seg(m10_reg); //バイナリデータを7セグメントLEDの表示データに変換する
degit_h1 = 0; PORTB = x; PORTB = x; degit_m10 = 1; //LED 表示
display_degit = 2;
break;
case 2: //Minute 1の桁
x = trans_7seg(m1_reg) | 0x20; //バイナリデータを7セグメントLEDの表示データに変換する
degit_m10 = 0; PORTB = x; PORTB = x; degit_m1 = 1; //LED 表示
display_degit = 3;
break;
case 3: //Sec 10の桁
x = trans_7seg(s10_reg); //バイナリデータを7セグメントLEDの表示データに変換する
degit_m1 = 0; PORTB = x; PORTB = x; degit_s10 = 1; //LED 表示
display_degit = 4;
break;
case 4: //Sec 1の桁
x = trans_7seg(s1_reg) | 0x20; //バイナリデータを7セグメントLEDの表示データに変換する
degit_s10 = 0; PORTB = x; PORTB = x; degit_s1 = 1; //LED 表示
display_degit = 5;
break;
case 5: //mSec 100の桁
x = trans_7seg(ms100_reg); //バイナリデータを7セグメントLEDの表示データに変換する
degit_s1 = 0; PORTB = x; PORTB = x; degit_ms100 = 1; //LED 表示
display_degit = 6;
break;
case 6: //mSec 10の桁
x = trans_7seg(ms10_reg); //バイナリデータを7セグメントLEDの表示データに変換する
degit_ms100 = 0; PORTB = x; PORTB = x; degit_ms10 = 1; //LED 表示
display_degit = 7;
break;
case 7: //mSec 1の桁
x = trans_7seg(ms1_reg) | 0x20; //バイナリデータを7セグメントLEDの表示データに変換する
degit_ms10 = 0; PORTB = x; PORTB = x; degit_ms1 = 1; //LED 表示
display_degit = 0;
break;
}
}
//******************* LED 消灯 ************************************************
// 入力 degit_ms1,degit_ms10,degit_ms100,degit_s1,degit_s10,degit_m1,degit_m10,degit_h1
// 処理 LEDをすべて消灯する
// 出力 degit_ms1,degit_ms10,degit_ms100,degit_s1,degit_s10,degit_m1,degit_m10,degit_h1
//******************************************************************************
void shutoff_LED(void){
degit_ms1 = 0; degit_ms10 = 0; degit_ms100 = 0;
degit_s1 = 0; degit_s10 = 0;
degit_m1 = 0; degit_m10 = 0;
degit_h1 = 0;
}
//******************************************************************************
//************************ メインプログラム *************************************
void main(void) {
//--- システム クロック設定(32MHz)---
//入出力ポートの設定
TRISA = 0xc7; ANSELA = 0;
TRISB = 0x00; ANSELB = 0;
TRISC = 0x00;
//--- LED 消灯 ---
shutoff_LED(); //LEDをすべて消灯する
//--- タイマー2(1mSec)設定 割り込み設定 ---
T2CONbits.T2CKPS = 3; //32MHz/4=8MHz 8MHz/64=125kHz
PR2 = 124; //125kHz/(124+1)=1kHz(1mSEC)
T2CONbits.T2OUTPS = 0; //1:1
T2CONbits.TMR2ON = 1; //Timer2 ON
PIR1bits.TMR2IF = 0; //タイマー2割り込みフラグクリア
PIE1bits.TMR2IE = 1; //タイマー2割り込み可
INTCONbits.GIE = 1; //割り込み可
INTCONbits.PEIE = 1; //周辺機能割り込み可
//----------- 繰り返し処理 ----------------
while(1){
//------------ READY処理(7.92Secを検出) -----------------------
if(ready_flag == 1 && ms1_reg == 0){
if(ms10_reg == 2){
if(ms100_reg == 9){
if(s1_reg == 7){
if(s10_reg == 0){
if(m1_reg == 0){
if(m10_reg == 0){
if(h1_reg == 0){
ready_flag =0; //カウントする
ms1_reg = 0; ms10_reg = 0; ms100_reg = 0;
s1_reg = 0; s10_reg = 0;
m1_reg = 0; m10_reg = 0;
h1_reg = 0;
}
}
}
}
}
}
}
}
//------------- キー入力処理 --------------------
if(RESET_SW == 0){
ready_flag = 1; //レディにする
start_flag = 0; //1でスタート 0でストップ
ms1_reg = 0; ms10_reg = 0; ms100_reg = 0;
s1_reg = 0; s10_reg = 0;
m1_reg = 0; m10_reg = 0;
h1_reg = 0;
delay(); //チャタリング防止delay
}
else if(START_SW == 0){
start_flag = 1; //1でスタート 0でストップ
delay(); //チャタリング防止delay
}
else if(STOP_SW == 0){
start_flag = 0; //1でスタート 0でストップ
delay(); //チャタリング防止delay
}
}
}
stop_watch_2017_2_19
1 ファイル 119.32 KB