クロックと時間計算
中間テスト1・2の両方、そして小テストでも必ず最初に出ます。覚える式は2本だけで、あとは往復するだけです。
INSTRUCTION CYCLE Tcy = 4 × Tosc = 4 ÷ Fosc
PIC16F1827は1命令=4システムクロックで動きます。これが計算の全部です。逆に解く問題(命令時間からFoscを求める)も、式を裏返すだけ。
クロック電卓
| Fosc | Tosc(システムクロック周期) | Tcy(命令実行時間) | 出典 |
|---|---|---|---|
| 1 MHz | 1 μs | 4 μs | — |
| 2 MHz | 0.5 μs | 2 μs | 小テスト 問題1 |
| 4 MHz | 0.25 μs | 1 μs | 中間1 問3 |
| 5 MHz | 0.2 μs | 0.8 μs | 小テスト 問題4(逆算) |
| 8 MHz | 0.125 μs | 0.5 μs | PWM問題で使用 |
| 10 MHz | 0.1 μs | 0.4 μs | PWM問題で使用 |
| 16 MHz | 0.0625 μs | 0.25 μs | — |
あわせて暗記する基本スペック
| 項目 | 値 | 補足 |
|---|---|---|
| 命令長 | 14 ビット | データ幅と混同しない |
| データ幅 | 8 ビット | だから unsigned char は 0〜255 |
| 1命令の実行サイクル | 4 クロック | 「3クロック」は✕(中間1 問2) |
| 入出力ピン数 | 16 ピン | PORTA 8本+PORTB 8本 |
マイコン vs マイクロプロセッサ
〇✕問題の定番。「マイコンは全部が下」と覚えて、ピン数・性能・周波数・消費電力・値段を思い出すのが速いです。例外はメモリ量の問い方だけ。
| 観点 | マイクロプロセッサ(MPU) | マイコン(MCU) |
|---|---|---|
| 消費電力 | 数W〜数十W | 数mW(=低い) |
| コスト | 数百$ | 数百円(=安い) |
| 性能 | 1μsで数千命令 | 1μsで数十命令(=低い) |
| 動作周波数 | GHz級 | MHz級(=低い) |
| OS | あり | なし |
| ピン数 | 百個以上 | 数十個(=少ない) |
| メモリ量 | GB級 | KB級(=小さい) |
実際に出た〇✕(小テスト 問題2)
| 記述 | 正解 | 理由 |
|---|---|---|
| マイコンの周波数はMPUより高い | ✕ | MHz級 < GHz級 |
| マイコンの性能はMPUより高い | ✕ | 1μsあたり数十命令しか実行できない |
| マイコンの消費電力はMPUより高い | ✕ | mW級で圧倒的に低い |
| マイコンのメモリ量はMPUより小さい | 〇 | 唯一の〇。「小さい」なので成立 |
| マイコンのピン数はMPUより多い | ✕ | 数十ピン vs 百ピン以上 |
| マイコンのOSはMPUより早い | ✕ | そもそもマイコンにOSがない |
レジスタ・ビット盤
配点が一番大きいところ。ビットをクリックして0/1を反転させると、16進数と各ビットの意味が同時に更新されます。レジスタを切り替えれば、そのまま試験で問われる形になります。
試験で出た 0xCF を入れてみてください。
レジスタの役割を一言で
| レジスタ | 役割 | ビットの意味 |
|---|---|---|
| TRISA / TRISB | 入出力方向の設定 | 1=入力(Input) / 0=出力(Output) |
| ANSELA / ANSELB | アナログ/ディジタルの切替 | 1=アナログ / 0=ディジタル |
| PORTA / PORTB | ポートのデータそのもの | 読めば入力値、書けば出力値 |
| OSCCON | 内部オシレータの周波数設定 | SPLLEN / IRCF<3:0> / SCS<1:0> |
| #pragma config | デバイスパラメータの疑似命令 | FOSC, WDTE, MCLRE など |
手で書けるようにしておく変換
| 設問 | ビット並び(7→0) | 答え |
|---|---|---|
| RB0〜RB3を出力、他を入力(中間1 問6) | 1111 0000 | TRISB = 0xF0 |
| RA0,RA1,RA2,RA4を入力、他を出力(中間1 問7) | 0001 0111 | TRISA = 0x17 |
| RA0,RA1,RA4を入力、他を出力(中間1 問12・中間2 問1) | 0001 0011 | TRISA = 0x13 |
| Bポート全ピンがLED=全出力 | 0000 0000 | TRISB = 0x00 |
| RB1,RB2,RB4,RB5を出力、他を入力(小テスト 問題5) | 1100 1001 | TRISB = 0xC9 |
| RA1,RA2,RA4,RA5だけディジタル、他アナログ(小テスト 問題6) | 1100 1001 | ANSELA = 0xC9 |
| RA0だけアナログ(中間2 問1) | 0000 0001 | ANSELA = 0x01 |
回路図の読み方
図から読み解く問題は、判断ポイントが3つしかありません。スイッチのプルアップ、LEDの向き、電流制限抵抗の値です。
① プルアップ抵抗とスイッチ
正しい接続 中間1 問5 の(イ)
抵抗は +5V とピンの間、スイッチは ピンと GND の間。スイッチOFFで High、ONで Low になります。
よくある誤り (ア)(ウ)(エ)
スイッチが抵抗とピンの間にあると、OFF時にピンが浮いて(ハイインピーダンス)値が不定になります。これが誤答パターン。
| スイッチ | ピンの電位 | プログラムから見た値 |
|---|---|---|
| 開いている(OFF) | 高電位(High) | 1 |
| 閉じている(ON) | 低電位(Low) | 0 |
② LEDの向き ─ ここが最大の落とし穴
同じ試験の中でも図によって向きが違います。アノード(三角形の底)がどちら側かを必ず目で確認してください。
ソース型 ピン=1 で点灯
ピン → 抵抗 → LED → GND。ピンから電流を出すので、1で点灯・0で消灯。中間2 設問5の D0〜D3 がこの型(PORTB=0x0F で D0〜D3 点灯)。
シンク型 ピン=0 で点灯
+5V → LED → 抵抗 → ピン。ピンが電流を吸い込むので、0で点灯・1で消灯。中間2の LED DA がこの型(RA2=0 で点灯)。
③ LEDの電流制限抵抗
= ( 5V − 2V ) ÷ I ← LEDの順方向電圧 Vf ≒ 2V
抵抗値の電卓
| 設問 | 計算 | 答え |
|---|---|---|
| 20mA を流したい(中間1 問8) | 3V ÷ 20mA | 150 Ω |
| 15mA を流したい(小テスト 問題7) | 3V ÷ 15mA | 200 Ω |
| 10mA を流したい | 3V ÷ 10mA | 300 Ω |
7セグメントLED
対応表さえ書ければ確実に取れます。試験中はまず余白に RB7〜RB0 と DP,g,f,e,d,c,b,a の対応を書いてから、値を2進数に展開してください。
| RB7 | RB6 | RB5 | RB4 | RB3 | RB2 | RB1 | RB0 |
|---|---|---|---|---|---|---|---|
| DP | g | f | e | d | c | b | a |
| 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
上の並びが 0xCF。点灯するのは DP, g, d, c, b, a で、f と e が消えるので「3.」の形になります(中間1 問11 の答えは ア)。
0x03 のビット盤で PORTB→7SEG を選び、右下の入力欄に 0xCF と打つと、その場で形が確認できます。数字の 0〜9 を作る値も自分で探しておくと応用問題に強くなります。
XC8の文法○×
中間1 問9。C言語として正しいかではなく、このマイコンで意味を持つかを問われます。
| 記述 | 正誤 | 理由 |
|---|---|---|
| PORTA = ~PORTA; | 〇 | ビット反転して代入。左辺があるので成立 |
| PORTB << 4; | ✕ | 構文は正しいが代入先がないので何も起きない。PORTB = PORTB << 4; なら〇 |
| if(PORTA & 0x04) ==1; | ✕ | if文の書式は if(条件式){ }。==1; が余分 |
| RA8 = 1; | ✕ | PIC16F1827に RA8 は存在しない(RA0〜RA7) |
| RB1 !=0; | ✕ | 比較しているだけで代入していない |
| TRISAbits.RB4 = 1; | ✕ | TRISAはRAxしか設定できない。RB4なら TRISBbits.RB4 |
| RA6 = 0.5; | ✕ | ピンは0か1の2値。小数は指定できない |
| for(unsigned char i=0; i<300; i++) | ✕ | 8ビットなので unsigned char は最大255。300回は回せず無限ループ |
フローチャート ↔ コードの対応(中間1 問10)
手順は毎回同じです。①フローチャートの箱とコードの空欄を矢印で結ぶ → ②各箱の日本語をそのままC言語に置き換える。先に対応付けを済ませると、空欄の数だけ機械的に埋まります。
A/D変換
中間テスト2の主役。ADCON0とADCON1の2枚のビットマップを覚えるだけで、設問がまるごと取れます。
ADCON0 ─ どのチャンネルを、いつ変換するか
| bit 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| — | CHS<4:0> | GO/DONE | ADON | ||||
- CHS<4:0> 00000=AN0、00001=AN1、…、01100=AN12
- GO/DONE 1=変換開始 / 0=変換終了(修了)
- ADON 1=ADC有効 / 0=ADC無効
ADCON0 = 0x01 → 0000 0001 → チャンネル AN0、変換処理は終了状態、ADCは有効。
ADCON1 ─ 結果の形式と基準電圧
| bit 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| ADFM | ADCS<2:0> | — | ADNREF | ADPREF<1:0> | |||
- ADFM 1=右詰め / 0=左詰め
- ADCS<2:0> 000=FOSC/2、001=FOSC/8、010=FOSC/32、011=Frc、100=FOSC/4、101=FOSC/16
- ADNREF 0=VSS / 1=VREF−ピン
- ADPREF<1:0> 00=VDD、10=VREF+ピン、11=FVR
ADCON1 = 0x80 → 1000 0000 → 右詰め・FOSC/2・VREF−はVSS・VREF+はVDD。中間2の設問(エ)〜(キ)がこの1行で全部答えられます。
A/D変換の値から電圧へ
ADRESL → 電圧・LED状態
変換後の分岐は次の3段です。しきい値と PORTB の値をセットで覚えてください。
| 条件 | PORTB | 点灯するLED |
|---|---|---|
| vin ≦ 1.5V | 0x03 | D0, D1 |
| 1.5V < vin ≦ 3.5V | 0x0F | D0〜D3 |
| 3.5V < vin | 0xFF | D0〜D7(全点灯) |
| スイッチSが閉(RA1=0) | 0x00 | 全消灯、DAも消灯 |
ADCON0bits.GO = 1;)はこの後にきます。
RA2=0 で点灯し、他のLEDは電圧レベルに応じて点灯します。スイッチONなら RA2=1 で DA 消灯、PORTB=0x00 で全消灯。
割り込みとタイマー0
中間テスト2 問3。INTCON と OPTION_REG の2つを16進数から展開できれば、設問1〜6がほぼ連鎖して解けます。
INTCON ─ 割り込みの許可とフラグ
| bit 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| GIE | PEIE | TMR0IE | INTE | IOCIE | TMR0IF | INTF | IOCIF |
| 全体許可 | 周辺装置 | タイマ0許可 | INTピン許可 | 状態変化 | タイマ0フラグ | INTフラグ | 状態変化フラグ |
INTCON = 0xA0 → 1010 0000 → GIE=1(全体許可)かつTMR0IE=1。よって割り込み要因はタイマー0のオーバーフロー。
INTCON = 0x00 → 全ビット0 → 割り込みは不可能。
OPTION_REG ─ タイマー0の入力源
| bit 7 | 6 | 5 | 4 | 3 | 2:0 |
|---|---|---|---|---|---|
| /WPUEN | INTEDG | TMR0CS | TMR0SE | PSA | PS<2:0> |
| プルアップ | 0=立下り 1=立上り | 0=内部クロック 1=外部RA4 | 0=立上りで加算 1=立下りで加算 | 0=TMR0に接続 1=TMR0に接続しない | 分周比 |
OPTION_REG = 0x28 → 0010 1000 →
INTEDG=0 → 割り込みは立下り/TMR0CS=1 → 入力源は外部(RA4端子)/TMR0SE=0 → カウントするエッジは立上り/PSA=1 → プリスケーラは TMR0 に接続なし。
タイマー0のオーバーフロー周期
例:入力64Hz、プリスケーラ無し → 256 × 1/64 = 4 秒
TMR0電卓
割り込みルーチンの定型(設問5)
「禁止 → フラグクリア → 処理 → 許可」の順番。フラグは1を立てるのではなく0でクリアする点が引っかけになります(選択肢に TMR0IF = 1 が混ざっています)。
スイッチによる2つの動作モード
| スイッチS | 実行される行 | 割り込み | D8 | PORTB が示すもの |
|---|---|---|---|---|
| 閉(RA1=0) | 12〜17 | 可能(INTCON=0xA0) | 消灯(RA0=0) | タイマー0の割り込み回数値 |
| 開(RA1=1) | 18〜24 | 不可能(INTCON=0x00) | 点灯(RA0=1) | TMR0の値=パルスの周波数 |
設問6(ウ):Sが開いているとき、__delay_ms(1000) の1秒間に64Hzのパルスが64回入るので TMR0 = 64。2進数では 0100 0000 なので、点灯するのは D6 だけです。
PWM
中間テスト2 問4と小テストの記述問題。式を2本覚えて、周期→PRx、デューティ→CCPRxL の往復ができれば完成です。
DUTY TIME デューティ時間 = ( CCPRxL + 1 ) × 4 × Tosc × プリスケール値
DUTY RATIO ─ 約分すると全部消える デューティ比 = ( CCPRxL + 1 ) ÷ ( PRx + 1 )
PWM電卓
逆算:目標のPWM周波数から PRx を求める
実際に出た計算
| 条件 | 式 | 答え |
|---|---|---|
| Fosc=4MHz, PRx=255, 分周4 → PWM周期 | 256 × 4 × 0.25μs × 4 | 1.024 ms |
| Fosc=8MHz, 分周4, PWM=2kHz → PRx | 500μs ÷ (4×0.125μs×4) − 1 | 249 |
| PRx=255, デューティ比0.5 → CCPRxL | 0.5 × 256 − 1 | 127 |
・中間2 問4のスライドは PWM周期を 1.096 ms と記載(式のとおりに計算すると 256×4×0.25μs×4 = 1.024 ms)
・小テスト問題1の解答キーは CCPRxL = 117(デューティ比の式からは 0.5×256−1 = 127)
どちらも1桁だけの違いなので誤植の可能性が高いですが、記述で出た場合は式を書いて過程を示すのが安全です。選択式なら資料側の値が選択肢に並ぶこともあるので、両方の数字を頭に入れておいてください。
演習
クリックで答えが開きます。まず紙に書いてから開いてください。過去に実際に出題された問題と、同じ考え方で作った類題を混ぜています。
クロック・スペック
Q01Fosc = 2MHz のとき、システムクロックサイクル時間と命令実行サイクル時間は?開く
Q02命令実行サイクル時間が 0.8μs のマイコンの動作周波数は?開く
Q03PIC16F1827 の命令長・データ幅・1命令の実行サイクルは?開く
Q04Fosc = 16MHz のとき、1000命令を実行するのにかかる時間は?開く
レジスタとビット計算
Q05RB1, RB2, RB4, RB5 を出力、その他を入力にする。レジスタ名と16進数の値は?開く
Q06RA1, RA2, RA4, RA5 だけディジタル、その他をアナログにする。レジスタ名と値は?開く
Q07RB0〜RB3 を出力、その他を入力にするときの TRISB の値は?開く
Q08RA0, RA1, RA2, RA4 を入力、その他を出力にするときの TRISA の値は?開く
Q09内部オシレータの周波数を設定するレジスタ名は? Bポートをディジタルにするレジスタ名は?開く
Q10OSCCON = 0x62 のとき、発振器の種類・クロック周波数・4倍PLLの有無は?開く
Q11OSCCON = 0x6A のときのクロック周波数は?開く
_XTAL_FREQ 4000000 なので辻褄が合う。回路図
Q12プルアップ抵抗の値として適切なのは 100Ω / 200Ω / 300Ω / 10kΩ のどれ?開く
Q13プルアップされたスイッチが開いているとき、ピンの状態は? 閉じているときは?開く
if(PORTAbits.RA1 == 1) が「Sが開いているとき」に対応する理由。Q14電源5V、LEDの順方向電圧2V、15mA流したいときの制御抵抗は?開く
Q15LEDのアノードが+5V側、カソードが抵抗経由でピンに繋がっている。点灯させるにはピンをどうする?開く
PORTAbits.RA2 = 0; で点灯する。Q16スイッチS0が押されているとき、電源端子(+5V)からの電流はどこへ流れる?開く
7セグメントLED
Q17カソードコモン型で PORTB に 0xCF を出力した。点灯するセグメントは?開く
Q18同じ回路で「7」を表示したい(DPは消灯)。PORTB に出力する値は?開く
A/D変換
Q19ADCON0 = 0x01 のとき、チャンネル・変換処理・ADCの有効性は?開く
Q20ADCON1 = 0x80 のとき、変換結果形式・変換クロック・VREF+・VREF− は?開く
Q21可変抵抗をアナログ入力に使う回路で ANSELA に入れる値は?(RA0のみアナログ)開く
Q22ADRESL = 0xA0 のとき、入力電圧と点灯するLEDは?開く
Q23ADRESL = 0xFF のときは?開く
Q24行15の __delay_us(20) の目的は?開く
割り込み・タイマー
Q25INTCON = 0xA0 のとき、有効な割り込みは?開く
Q26OPTION_REG = 0x28 のとき、TMR0の入力源・カウントするエッジ・プリスケーラの接続は?開く
Q27同じ 0x28 で、割り込み要因のエッジ(INTEDG)は?開く
Q28TMR0の入力周波数が 64Hz、プリスケーラ無しのとき、割り込みは何秒ごとに発生する?開く
Q29入力 1kHz、プリスケール値 8 のとき、オーバーフロー周期は?開く
Q30割り込みルーチンの (a)(b)(c) に入る記述は?開く
Q31Sが開いているとき、メインループを1度実行し終えた時点の TMR0 の値と点灯するLEDは?(4MHz / 外部64Hz)開く
__delay_ms(1000) の1秒で64パルス。64 = 0100 0000 なので D6 だけ。PORTAbits.RA0 = 1 により D8 は点灯。Q32行18〜24を実行しているとき、割り込みは可能か?開く
INTCON = 0x00 にしてGIEを含む全ビットを0にしているため。PWM
Q33Fosc=8MHz、プリスケール値4で 2kHz の PWM を作りたい。PRx の値は?開く
Q34PRx=255 でデューティ比 0.5 にしたい。CCPRxL の値は?開く
Q35Fosc=4MHz、PRx=255、プリスケール値4 のときの PWM 周期は?開く
XC8の記述
Q36PORTB << 4; は正しいか?開く
PORTB = PORTB << 4; とする。Q37TRISAbits.RB4 = 1; は正しいか?開く
TRISBbits.RB4。Q38for文で300回ループさせるとき、カウンタに unsigned char を使ってよいか?開く
unsigned int を使う。Q39フローチャートの「z を1ビット左シフトした結果を PORTB に格納」に対応するC言語の記述は?開く
TRISB = 0x00;、「1秒の遅延」は __delay_ms(1000);。Q40a = PORTA & 0x03; で PORTA = 0xFA のとき、a の値は?開く
直前チェック
試験開始直後、問題を読む前に余白へ書き出しておくと迷いが減るものです。
- 1Tosc = 1/Fosc、Tcy = 4/Fosc(4倍を忘れない)
- 2TRIS は 1=入力 / 0=出力、ANSEL は 1=アナログ / 0=ディジタル
- 3ビット位置の定規:7 6 5 4 3 2 1 0 を先に書いてから0/1を埋める
- 47セグの並び:DP g f e d c b a(RB7→RB0)
- 5LEDは図で向きを確認してから点灯条件を決める
- 6LED制御抵抗 R = (5−2)/I、プルアップは10kΩ級
- 7プルアップのスイッチ:開=高電位=1、閉=低電位=0
- 8ADCON0 の下位2ビット:GO/DONE、ADON。上位が CHS でチャンネル番号
- 9ADCON1 の bit7 ADFM:1=右詰め
- 10vin = 5 × res ÷ 256、しきい値 1.5V / 3.5V → 0x03 / 0x0F / 0xFF
- 11INTCON:GIE PEIE TMR0IE INTE IOCIE TMR0IF INTF IOCIF
- 12TMR0オーバーフロー = 256 × (1/f) × プリスケール値
- 13ISR は 禁止 → フラグ0クリア → 処理 → 許可
- 14PWM周期 = (PRx+1)×4×Tosc×分周、デューティ比 = (CCPRxL+1)/(PRx+1)
- 15デューティ比の問題で Fosc と分周は使わない