PICでCの練習 2007.05.30(水)〜 LessocC_104。 RCサーボ信号を発生します。
著作者名: 中野 良知 作成開始: 2007.05.30(水)
目次 1. 目的 2. ゼネラルフローチャート 3. プログラムソースコード 4. キーワード 4.1. RCサーボ信号 4.2. CONFIGワード 4.3. WPUレジスタ 4.4. タイマ 4.4.1. OPTIONレジスタ 4.4.2. INTCONレジスタ 4.4.3. PIE1レジスタ 4.4.4. PIR1レジスタ 4.4.5. TMR1H/TMR1Lレジスタ 4.4.6. T1CONレジスタ 4.4.7. TMR0レジスタ 5. 実行結果 6. 実験回路 1. 目的 RCサーボ信号を発生します。 パルス幅は、GP4に接続した可変抵抗器の摺動子の位置で約1msecから2msecの範囲で 変化します。 2. ゼネラルフローチャート (main) ↓ クロック較正値設定 ↓ ポート入出力設定 ↓ GP4をA/Dに設定 ↓ タイマ0,1を設定 ↓ ├←─────────────────┐ ↓ no │ <A/D変換完了?> ───────────→┤ ↓yes │ A/D変換値をパルス幅カウントに変換 │ ↓ │ └──────────────────┘ (タイマ割込み) ↓ no <タイマ0割込み?> →──────┐ ↓yes │ RCパルス出力=0 │ ↓ │ タイマ0割込み禁止 │ ↓ │ ├←─────────────┘ ↓ no <タイマ1割込み?> →──────┐ ↓yes │ RCパルス出力=1 │ ↓ │ タイマ0にパルス幅カウント設定 │ ↓ │ タイマ0割込み許可 │ ↓ │ ├←─────────────┘ ↓ (終了) 3. プログラムソースコード //***************************************************************************** // タイトル : LessocC_104 // 作者 : ioio // 目的 : RCサーボ信号を出力します。 // マイコン : PIC12F675 // クロック : 4MHz。内蔵発振。 // Config : MCLR=GP3, WDTE=OFF, INTOSC // Compiler : PICC Lite(V9.6)。 HI-TEC software製。 // Compile : >picl -12f675 lesson.c // ASM List : >picl -12f675 --ASMLIST lesson.c //***************************************************************************** // 変更履歴 // 2007.05.29(火) 作成 //***************************************************************************** //----------------------------------------------------------------------------- // ヘッダーファイル #include "pic.h" // デバイス関連の定義を展開 //----------------------------------------------------------------------------- // コンフィグレーション定義 __CONFIG(0x01D4); // BandGap=0x0, MCLR=GP3, WDTE=OFF, INTOSC //----------------------------------------------------------------------------- // 関数定義 //----------------------------------------------------------------------------- // 定数定義 #define CENTER 67 // パルス幅1.5msec //----------------------------------------------------------------------------- // グローバル変数定義 unsigned char pulse_width; // RCサーボパルス幅 //----------------------------------------------------------------------------- // ビットフィールド構造体定義 //----------------------------------------------------------------------------- // ポートマップ // NAME PIN NO I/O USE // -----+--------+-----+----------------------- // GP0 7 O RCサーボ出力 // GP4 3 I パルス幅調節(AN3,A/D) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void main(void) { unsigned char adv; OSCCAL = _READ_OSCCAL_DATA(); // クロック較正値をOSCCALに設定 CMCON = 0x07; // COMPARATOR=Off(Digital I/O) ANSEL = 0x08; // Fosc/2。AN3=On。AN2,1,0=Off(Digital I/O) ADCON0 = 0x0D; // A/D ch3=Off。左詰め。 TRISIO = 0x3E; // GP5,GP4,GP3,GP2,GP1=入力。GP0=出力 OPTION = 0x52; // Pull Up=On。T0CS=Int。PSA=TIMER0。 // Prescaler=1:8 TMR0 = CENTER; // 1usec*8*256=2048usecに設定 INTCON = 0xC0; // GIE=許可。PEIE=許可。T0IE=禁止 GPIO = 0x00; // 出力を全て0に初期化 WPU = 0x36; // GP5,4,2,1=Pull Up TMR1H = (65536-2500) >> 8; // TMR1=20msecの上位 TMR1L = (65536-2500) & 0xFF; // TMR1=20msecの下位 PIE1 = 0x01; // TMR1割込み=許可 T1CON = 0x31; // プリスケール=1:8。TMR1=On ADIF = 0; // A/D完了フラグリセット GODONE = 1; // A/D変換開始 pulse_width = CENTER; // RCサーボパルス幅を1.5msecに設定 while(1){ // A/D変換。RCサーボパルス幅計算 if(ADIF){ // A/D変換済みなら adv = ADRESH; // A/D変換値取得 // VR mixからmaxのA/D値を逆順に変換 adv = 255 - adv; // A/D変換値の変化幅を17/32倍して0から135に圧縮。 // 時間調節幅=1.08msec。 pulse_width = (adv / 2) + (adv / 32); ADIF = 0; // フラグリセット GODONE = 1; // A/D変換開始 } } } //----------------------------------------------------------------------------- // 割込み処理 // 2007.05.29(火) 作成 //----------------------------------------------------------------------------- void interrupt isr(void) { if(T0IF){ // タイマ0割込み有りなら GPIO0 = 0; // RCサーボ出力=0 T0IF = 0; // TMR0割込み発生フラグをリセット T0IE = 0; // TMR0割込み禁止 } if(TMR1IF){ // タイマ1割込み有りなら GPIO0 = 1; // RCサーボ出力=1 TMR0 = pulse_width; // RCサーボパルス幅設定 TMR1IF = 0; // TMR0割込み発生フラグをリセット TMR1H = (65536-2500) >> 8; // TMR1=20msecの上位 TMR1L = (65536-2500) & 0xFF; // TMR1=20msecの下位 T0IF = 0; // TMR0割込みフラグリセット T0IE = 1; // TMR0割込み許可 } } //***************************************************************************** //***************************************************************************** 4. キーワード 4.1. RCサーボ信号 →├──┤←1msec〜2msec ┌──┐ ┌──┐ RCサーボ信号 ─┘ └───────────┘ └────── ├←────────────→┤ 20msec パルス幅: MIN =1msec CENTER =1.5msec MAX =2msec タイマ0でパルス幅を設定します。 繰返し周期: 20msec タイマ1で周期を設定します。 4.2. CONFIGワード CONFIGワード 上位6ビット 13 12 11 10 9 8 ┌───┬───┬───┬───┬───┬───┬ │ BG1 │ BG0 │ - │ - │ - │ CPD │ └───┴───┴───┴───┴───┴───┴ ? ? 1 下位8ビット 7 6 5 4 3 2 1 0 ┬───┬───┬───┬───┬───┬───┬───┬───┐ │ CP │BODEN │MCLRE │PWRTE │ WDTE │F0SC2 │F0SC1 │F0SC0 │ ┴───┴───┴───┴───┴───┴───┴───┴───┘ 1 1 0 1 0 1 0 0 BG1,BG0 :Band Gap。工場出荷時の値を使用します。 CPD :データメモリの保護を禁止します。 CP :プログラムメモリの保護を禁止します。 BODEN :ブラウンアウト検出を許可します。 MCLRE :MCLRを禁止。GP3(入力)として選択します。 PWRTE :パワーアップタイマを禁止します。 WDTE :ウォッチドッグタイマーを禁止します。 FOSC2,1,0:内蔵クロック発振(4MHz)を選択します。GP4はDigital I/Oです。 例: __CONFIG(0x01D4); // BandGap=0x0, MCLR=GP3, WDTE=OFF, INTOSC CONFIGワードはROMライターで書き込みます。 4.3. WPUレジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ - │ - │ WPU5 │ WPU4 │ - │ WPU2 │ WPU1 │ WPU0 │ └───┴───┴───┴───┴───┴───┴───┴───┘ 0 0 1 1 0 1 1 0 WPU2 :GP5,4,2,1のプルアップを許可します。 例: WPU = 0x36; // GP5,4,2,1=Pull Up 4.4. タイマ 4.4.1. OPTIONレジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ GPPU │INTEDG│ T0CS │ T0SE │ PSA │ PS2 │ PS1 │ PS0 │ └───┴───┴───┴───┴───┴───┴───┴───┘ 0 1 0 1 0 0 1 0 GPPU :WPUレジスタと組合わせてGP5,4,2,1のプルアップを許可します。 T0CS :タイマ0のクロックソースを内部命令サイクル(1usec)に設定します。 PS2,1,0 :タイマ0のプリスケーラを1:8に設定します。 例: OPTION = 0x52; // Pull Up=On。T0CS=Int。PSA=TIMER0。 4.4.2. INTCONレジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ GIE │ PEIE │ T0IE │ INTE │ GPIE │ T0IF │ INTF │ GPIF │ └───┴───┴───┴───┴───┴───┴───┴───┘ 1 1 0 0 0 0 0 0 GIE :全割込みを許可します。 PEIE :PIE1レジスタのTMR1IEビットと組合わせてタイマ1の割込みを許可します。 T0IE :タイマ1の割込み処理で、タイマ0の割込みを許可します。 例: INTCON = 0xC0; // GIE=Enable。PEIE=Enable。T0IE=Disable 4.4.3. PIE1レジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ EEIE │ ADIE │ - │ - │ CMIE │ - │ - │TMR1IE│ └───┴───┴───┴───┴───┴───┴───┴───┘ 0 0 0 0 0 0 0 1 TMR1IE :タイマ1割込みを許可します。 例: PIE1 = 0x01; // TMR1割込み=許可 4.4.4. PIR1レジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ EEIF │ ADIF │ - │ - │ CMIF │ - │ - │TMR1IF│ └───┴───┴───┴───┴───┴───┴───┴───┘ 0 0 0 0 0 0 0 0 TMR1IF :タイマ1オーバーフロー割り込みフラグをリセットします。 例: TMR1IF = 0; // TMR1割込みフラグリセット 4.4.5. TMR1H/TMR1Lレジスタ タイマ1がオーバーフローするまでのカウント値を設定します。 パルス周期の20msecに必要なカウント値=20msec/8/1usec=2500。 タイマ1の設定値=65536 - 2500=63036 です。 例: TMR1H = (65536-2500) >> 8; // TMR1=20msecの上位 TMR1L = (65536-2500) & 0xFF; // TMR1=20msecの下位 4.4.6. T1CONレジスタ 7 6 5 4 3 2 1 0 ┌───┬───┬────┬────┬────┬───┬───┬───┐ │ - │TMR1GE│T1CKPS1 │T1CKPS0 │T1OSCEN │T1SYNC│TMR1CS│TMR1ON│ └───┴───┴────┴────┴────┴───┴───┴───┘ 0 1 1 0 0 0 1 T1CKPS1 :タイマ1用のプリスケーラ1:8を選択します。 TMR1ON :タイマ1を起動します。 例: T1CON = 0x31; // プリスケール=1:8。TMR1=On 4.4.7. TMR0レジスタ RCサーボパルス幅の変化範囲を1.08msecに設定した時のカウントの幅は135です。 1usec×8×135=1.08msec 半固定抵抗のMINからMAXのA/D変換値 0から255を、255から0の逆順に変換します。 adv = 255 - adv; 255から0(VR_MIN〜VR_MAX)の変化幅を135から0に圧縮します。 pulse_width = (adv / 2) + (adv / 32); adv adv 17adv ------- + ------ = --------- → adv=0で0、adv=255で135。 2 32 32 TMR0に135を設定すると、1usec×8×(256-135)=0.968msecでパルス幅MINです。 TMR0に0を設定すると、1usec×8×256=2.048msec パルス幅MAXです。 pulse_widthは、タイマ1の割込みでTMR0に設定します。 例: TMR0 = pulse_width; 5. 実行結果 パルス幅波形 上:0.98msec(MIN) 中:1.5msec(CENTER) 下:2.04msec(MAX) パルスの繰返し周期=19.8msec 6. 実験回路 PIC12F675 ┌────┐1 │ VDD├──●────●─────●─────────← +5V │ │ │0.1u │ │ │ │ ┴ /50V │ │┴│100u/16V │ │8 ┬ │ └┬┘ │ VSS├──●────│─────●────────── GND │ │ │ │ │ │ ┌┴┐ │ │ │3 │5K│ │ │ GP4├──────┤VR│ │ │ │ │ │ │ │ │ └┬┘ │ │ │ └─────┘ │ │7 │ GP0├────────────────────→ RCサーボ信号 │ │ │ │ └────┘ 電源パスコン0.1u/50VのセラミックコンデンサーはVDDとVSSの近くに接続します。
LessonCのTopへ
サイトのTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合にのみ複製が可能です。
inserted by FC2 system