//----------------------------------------------------------------------------- // Note // サーボのPLS値による角度を確認する // PICの周波数を32Mhzに設定 //----------------------------------------------------------------------------- #include #include #include #include //#include // コンフィグレーションBIT1 設定 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #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) // コンフィグレーションBIT2 設定 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = ON // PLL Enable (4x PLL enabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) #define _XTAL_FREQ 32000000 // オシレータ周波数 32Mhzの場合 #define IO_SW_ON 0 #define IO_SW_OFF 1 #define SEVEN_SEG_IO_ON 1 #define SEVEN_SEG_IO_OFF 0 #define SEVEN_SEG_SIZE 4 #define TMR1_OFFSET 25536 #define NEUTRAL_PLS 1500 #define SERVO_PLS_MAX 3000 #define SERVO_PLS_MIN 100 #define SERVO_SKIP_CNT 1000 #define SERVO_DELAY_CNT 100 #define SEG_LED_A RB5 #define SEG_LED_B RB4 #define SEG_LED_C RC2 #define SEG_LED_D RC1 #define SEG_LED_E RC0 #define SEG_LED_F RA2 #define SEG_LED_G RA1 #define SEG_LED_DP RA0 #define SEG_DEGI_1 RC3 // 1000の位 #define SEG_DEGI_2 RC6 // 100の位 #define SEG_DEGI_3 RC7 // 10の位 #define SEG_DEGI_4 RB7 // 1の位 #define SERVO_SW1 RA5 // PLS値を減算 #define SERVO_SW2 RA4 // PLS値をニュートラルへ #define SERVO_SW3 RA3 // PLS値を加算 #define SERVO_IO RB6 const unsigned char seg_led[18] = { {0b00111111}, // 0 {0b00000110}, // 1 {0b01011011}, // 2 {0b01001111}, // 3 {0b01100110}, // 4 {0b01101101}, // 5 {0b01111101}, // 6 {0b00100111}, // 7 {0b01111111}, // 8 {0b01101111}, // 9 {0b00000001}, // a {0b00000010}, // b {0b00000100}, // c {0b00001000}, // d {0b00010000}, // e {0b00100000}, // f {0b01000000}, // g {0b10000000} // dp }; volatile unsigned char seven_seg_data[ SEVEN_SEG_SIZE ] = {0}; volatile signed short servo_pls = NEUTRAL_PLS; volatile signed short work_servo_pls = NEUTRAL_PLS; void seven_seg_ctrl( void ); void out_seven_seg(short , short ); void interrupt isr_ctrl( void ) { // タイマ1割り込み処理 if( TMR1IF ) { SERVO_IO = 1; CCPR1 = work_servo_pls; TMR1 = TMR1_OFFSET; // 20msec毎に割り込み TMR1IF = 0; } // CCP1割り込み処理 if( CCP1IF ) { SERVO_IO = 0; CCP1IF = 0; } } int main(int argc, char** argv) { bool now_sw[3] = {0}; bool old_sw[3] = {0}; bool skip_flg[3] = {0}; short skip_cnt[3] = {0}; short delay_cnt[3] = {0}; short wk; short i; OSCCON = 0b01110000 ; // 内部クロック8MHz OPTION_REG = 0b00000000 ; // プルアップ抵抗有効 ANSELA = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISA = 0b00111000 ; // ピンは全て出力に割当てる(RA3は入力のみとなる) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) WPUA = 0b00111000 ; ANSELB = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISB = 0b00000000 ; // RB5を入力,他は全て出力に割当てる PORTB = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ANSELC = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISC = 0b00000000 ; // ピンは全て出力に割当てる PORTC = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) CCP1CON = 0b00001010 ; // コンペアモード T1CON = 0b00100100 ; // 分周1/4 クロック同期有効 TMR1 = TMR1_OFFSET; work_servo_pls = TMR1_OFFSET + 3000; // 1.5msec TMR1IE = 1; // タイマ1割り込み有効 CCP1IE = 1; // コンペアマッチ割り込み有効 TMR1ON = 1; // タイマ1 開始 TMR1IF = 0; CCP1IF = 0; PEIE = 1; GIE = 1; for(;;) { // スイッチ状態の取得 if( SERVO_SW1 == IO_SW_ON ) now_sw[0] = true; else now_sw[0] = false; if( SERVO_SW2 == IO_SW_ON ) now_sw[1] = true; else now_sw[1] = false; if( SERVO_SW3 == IO_SW_ON ) now_sw[2] = true; else now_sw[2] = false; for(i=0; i<3; i++) { if( now_sw[i]|| old_sw[i] ) { if( skip_cnt[i] > 0 ) { skip_cnt[i]--; if( (!skip_flg[i]) && (skip_cnt[i] <= 0) ) { skip_flg[i] = true; skip_cnt[i] = 0; } } } else { skip_flg[i] = false; skip_cnt[i] = SERVO_SKIP_CNT; } if( skip_flg[i] ) { if( delay_cnt[i] > 0 ) { delay_cnt[i]--; if( delay_cnt[i] <= 0 ) { if( i == 0 ) { servo_pls -= 10; if( servo_pls < SERVO_PLS_MIN) servo_pls = SERVO_PLS_MIN; } else if( i == 2 ) { servo_pls += 10; if( servo_pls > SERVO_PLS_MAX) servo_pls = SERVO_PLS_MAX; } delay_cnt[i] = SERVO_DELAY_CNT; } } } else { delay_cnt[i] = SERVO_DELAY_CNT; } } for(i=0; i<3; i++) { if( !skip_flg[i] ) { if( (old_sw[i] != now_sw[i]) && (old_sw[i] == true) ) { if( i == 0 ) { servo_pls -= 1; if( servo_pls < SERVO_PLS_MIN) servo_pls = SERVO_PLS_MIN; } else if( i == 2 ) { servo_pls += 1; if( servo_pls > SERVO_PLS_MAX) servo_pls = SERVO_PLS_MAX; } else { servo_pls = NEUTRAL_PLS; } } } } // 表示桁に分割 wk = servo_pls; seven_seg_data[0] = wk % 10; wk /= 10; seven_seg_data[1] = wk % 10; wk /= 10; seven_seg_data[2] = wk % 10; wk /= 10; seven_seg_data[3] = wk; // 7seg 表示制御 seven_seg_ctrl(); // usec->タイマ1用のカウンタ用に変換 work_servo_pls = (short)TMR1_OFFSET + (short)(servo_pls * 2); for(i=0; i<3; i++) old_sw[i] = now_sw[i]; } return (EXIT_SUCCESS); } void seven_seg_ctrl( void ) { static unsigned char seq_digi = 0; unsigned char out; bool enable; switch( seq_digi ) { case 0: // 1000の位 out = seg_led[seven_seg_data[3]]; // 表示か非表示か判定する enable = false; if( seven_seg_data[3] != 0 ) enable = true; if( !enable ) out = 0; break; case 1: // 100の位 out = seg_led[seven_seg_data[2]]; // 表示か非表示か判定する enable = false; if( seven_seg_data[3] != 0 ) enable = true; if( seven_seg_data[2] != 0 ) enable = true; if( !enable ) out = 0; break; case 2: // 10の位 out = seg_led[seven_seg_data[1]]; // 表示か非表示か判定する enable = false; if( seven_seg_data[3] != 0 ) enable = true; if( seven_seg_data[2] != 0 ) enable = true; if( seven_seg_data[1] != 0 ) enable = true; if( !enable ) out = 0; break; case 3: // 1の位 out = seg_led[seven_seg_data[0]]; break; default: seq_digi = 0; out = 0; break; } out_seven_seg( out, seq_digi ); __delay_ms(1); seq_digi++; if( seq_digi > 3 ) seq_digi = 0; } void out_seven_seg(short seg, short digi) { // a点灯 if( (seg & 0x01) != 0 ) SEG_LED_A = SEVEN_SEG_IO_ON; else SEG_LED_A = SEVEN_SEG_IO_OFF; // b点灯 if( (seg & 0x02) != 0 ) SEG_LED_B = SEVEN_SEG_IO_ON; else SEG_LED_B = SEVEN_SEG_IO_OFF; // c点灯 if( (seg & 0x04) != 0 ) SEG_LED_C = SEVEN_SEG_IO_ON; else SEG_LED_C = SEVEN_SEG_IO_OFF; // d点灯 if( (seg & 0x08) != 0 ) SEG_LED_D = SEVEN_SEG_IO_ON; else SEG_LED_D = SEVEN_SEG_IO_OFF; // e点灯 if( (seg & 0x10) != 0 ) SEG_LED_E = SEVEN_SEG_IO_ON; else SEG_LED_E = SEVEN_SEG_IO_OFF; // f点灯 if( (seg & 0x20) != 0 ) SEG_LED_F = SEVEN_SEG_IO_ON; else SEG_LED_F = SEVEN_SEG_IO_OFF; // g点灯 if( (seg & 0x40) != 0 ) SEG_LED_G = SEVEN_SEG_IO_ON; else SEG_LED_G = SEVEN_SEG_IO_OFF; // DP点灯 if( (seg & 0x80) != 0 ) SEG_LED_DP = SEVEN_SEG_IO_ON; else SEG_LED_DP = SEVEN_SEG_IO_OFF; // 表示桁指定 if( digi == 0 ) SEG_DEGI_1 = SEVEN_SEG_IO_ON; else SEG_DEGI_1 = SEVEN_SEG_IO_OFF; if( digi == 1 ) SEG_DEGI_2 = SEVEN_SEG_IO_ON; else SEG_DEGI_2 = SEVEN_SEG_IO_OFF; if( digi == 2 ) SEG_DEGI_3 = SEVEN_SEG_IO_ON; else SEG_DEGI_3 = SEVEN_SEG_IO_OFF; if( digi == 3 ) SEG_DEGI_4 = SEVEN_SEG_IO_ON; else SEG_DEGI_4 = SEVEN_SEG_IO_OFF; }