// ハニービー用赤外線3ch受信機 // 26k1031rx3hb.c // PIC12F683PWMメインロータ、テールロータ、エレベータ制御 #include<12f683.h> #fuses INTRC_IO,NOWDT,PUT,NOPROTECT,NOMCLR,NOBROWNOUT //ウオッチドックタイマ無し、パワーアップタイマ使用 //プロテクト無し、MCLRなし #use delay(CLOCK=8000000) //8MHz駆動 #byte GP=5 #bit IRSIG=GP.3 #define ON 1 #define OFF 0 #define HI 1 #define LOW 0 #define el_on 0x31//エレベータON #define el_off 0x0e//エレベータOFF #define rd_on 0x02//テールモータON #define rd_off 0x35//テールモータOFF signed long th_count,rd_count,el_count; signed long rev_mix,rd_duty,al_count,rd_trim;//パルスカウント用 int cycl_count,el_duty; byte gp_now; // テールモータ、エレベータコイル駆動PWM #int_rtcc void soft_pwm() { set_timer0(156); if(cycl_count < rd_duty){//ラダーモータON gp_now=gp_now | rd_on; GP=gp_now; } else{//ラダーモータOFF gp_now=gp_now & rd_off; GP=gp_now; } if(cycl_count < el_duty){//エレベータON gp_now=gp_now | el_on; GP=gp_now; } else{//エレベータOFF gp_now=gp_now & el_off; GP=gp_now; } cycl_count++; cycl_count %=99;//PWM分解能 0〜99:100段階 } //メインルーチン main(){ int gcount; setup_oscillator(OSC_8MHz); setup_comparator(NC_NC); //デジタル入力切り替え setup_ccp1(CCP_PWM); //PWMモード使用宣言 setup_adc_ports(NO_ANALOGS); //アナログ未使用 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4);// マグネットアクチュエータ周期 set_timer0(246); //0.5us*4*(255-246+1)=0.00002s(=0.02ms)・・100分割なので、 //0.02ms*100=2ms:500Hz setup_timer_2(T2_DIV_BY_4,255,1); //CCP1 PWMモードセット //PWM周期=(255+1)*4*(1/8E6)*4=0.512ms=1.95KHz enable_interrupts(INT_RTCC); //timer0割り込み許可 enable_interrupts(GLOBAL); //割り込み全体許可 set_tris_a(0x08);//GP3入力、他は出力 /* GP 5 4 3 2 1 0 el3 el2 SG MTR MTT el1 0 0 1 0 0 0 */ cycl_count=rd_duty=el_duty=0; th_count=0; rd_trim=0; gp_now=OFF; while(1){//ギャップ検出ルーチン gcount=0; while(gcount < 30){ if(IRSIG==HI){ delay_us(100); gcount++; } else{ gcount=0; } } While(IRSIG==HI){ } //**************** timer0割り込み禁止開始 ****************** disable_interrupts(INT_RTCC); // 1ch(エルロン):未使用 al_count=0; while(IRSIG==LOW){//Low、Hiループは1回10μSに調整済み delay_us(6); al_count=al_count+1; } while(IRSIG==HI){ delay_us(6); al_count=al_count+1; } // 2ch(エレベータ) el_count=0; while(IRSIG==LOW){ delay_us(6); el_count=el_count+1; } while(IRSIG==HI){ delay_us(6); el_count=el_count+1; } // 3ch(スロットル) th_count=0; while(IRSIG==LOW){ delay_us(6); th_count=th_count+1; } while(IRSIG==HI){ delay_us(6); th_count=th_count+1; } // 4ch(ラダー): rd_count=0; while(IRSIG==LOW){ delay_us(6); rd_count=rd_count+1; } while(IRSIG==HI){ delay_us(6); rd_count=rd_count+1; } //************** timer0割り込み禁止終了 ****************** enable_interrupts(INT_RTCC); //エルロン(ラダートリム)の処理 if(al_count > 180){ delay_ms(100); rd_trim=rd_trim+2; } if(al_count < 130){ delay_ms(100); rd_trim=rd_trim-2; } //エレベータの処理 if(el_count<105){ el_count=100; } if(el_count>180){ el_count=205; } if(el_count > 160){ el_duty=(el_count-155)*2; } else{ el_duty=0; } //スロットルの処理 rev_mix=th_count; if(th_count<110){//最スロー th_count=0; } else if(th_count>190){//フルスロットル th_count=1023; } else{ th_count=(th_count-100)*10;//PWM100段階 } set_pwm1_duty(th_count); //テールモータの処理 rev_mix=rev_mix-100; if(rd_count<110){ rd_count=100; } if(rd_count>200){ rd_count=200; } if(150 <= rd_count && rd_count <=160){ rd_count=155; } if(rev_mix < 45){ rd_duty=rev_mix+(rd_count-155)+rd_trim; } else{ rd_duty=rev_mix/10*7+14+(rd_count-155)+rd_trim;//14はオフセット値 } } }