PIC10F222T-I/OT | 最も小型な SOT-23(6pin) パッケージは面白い応用ができそう |
概要 | 具体事例ではなく「こんな事ができる」と言うサンプルです | |
| | | |
最近の傾向 |
|
最近は「猫も杓子も Arduino」の様ですが、 Arduinoは GCCコンパイラが吐き出した大きな
コード(実行プログラム)を動かすために AVRマイコンの豊富な資源が必要です
大量の文字や画像情報を処理する場合は、それに見合ったメモリや処理能力が必要ですが
たかが LED点滅や、リレー ON/OFF 程度の処理では、全く「鶏を割くに焉んぞ牛刀を用いん」
の如くです
|
ちっちゃな物が好き |
|
PICの中で規模的にも物理的にも一番小さな機種である PIC10F222T-I/OTを使って
「何ができるだろう」と考えていましたが、良い考えが浮かばずとにかく、色々な機能を
詰め込んだサンプルを作ってみました (最近は具体的な物も試作を始めました)
|
やってみた事 |
|
前提条件(制約)は、割込みを使わない(割込機能が無いので使えない) |
| (1) | (なるべく正確な)一定間隔の時間(ここでは 104μS)を作る |
| (2) | (一定間隔の時間を使って)ソフトウェア-UART を実現する
|
| (3) | (短い時間の繰り返しループの中で) A/D変換を行う |
| (4) | (短い時間の繰り返しループの中で) UARTへ文字列送信(約33mS)を行う |
| (5) | (短い時間の繰り返しループを使って)簡易 PWMを生成し LEDの明るさを変えてみる |
| (6) | (ポテンショの電圧をA/D変換したデータで)LEDの明るさを変えてみる |
| (7) | (UARTで受信したデータで)LEDの明るさを変えてみる |
|
|
|
| |
暗い側でLEDがチラつくのは、動画のコマ数と PWM制御の周波数が近いためで
肉眼では気になりません
|
|
| 目次へ |
| | | |
規格:
調歩同期
(シリアル通信) |
|
RS-232C の
シリアルポート
(昔のパソコンには標準装備) と通信するための規格です
UART (Universal Synchronous Asynchronous Receiver/Transmitter) を介して接続します
現在のパソコンでは USBポートに「USB-シリアルユニット」を介して接続して
専用のドライバーソフトの働きでシリアルポートに接続したのと同様に通信できます
|
|
仕様 |
(1) | 全体仕様(ハードウェア、ソフトウェア)
| |
RA0ピンに(可変抵抗を接続し) 0〜5Vの電圧を入力して A/D変換する
RA1ピンに LEDを接続して PWM制御で明るさ調整する
明るさ調整の指令値は、(a)A/D変換した値を用いる (b)通信で受信した値を用いる
RA2ピンは UARTの送信信号(TXD)に割り当てる
RA3ピンは URATの受信信号(RXD)に割り当てる(RA3はデジタル入力しか割り当てできない)
A/D変換した値(8bit)を 16進 2桁の文字に変換して、1秒毎に UARTから送信する
(PC側のソフト)
PICから送信された A/D変換値を、ターミナルソフトで受信する
受信したデータを通信ログとしてタイムスタンプを付けてテキストファイルに記録する
記録されたテキストデータは、Excelなどで読み込めばデータ加工やグラフ化が出来る
|
(2) | CPU設定 |
|
リセットピン:使用せず(GP3:digital I/O)
コードプロテクト:使用せず
ウォッチドッグタイマ:使用せず
マスタークリヤプルアップイネーブル:使用せず
クロック:8MHz
|
|
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _MCPU_OFF & _IOSCFS_8MHZ
|
(3) | 通信 |
|
10F222 には UARTは内臓されていないので、ソフトウェアで UARTエミュレータを作成します
ソフト-UART の制約で、通信速度:1200bps(以下)、データ:8bit、Stop:1bit とします
通信は一応、全二重で出来ます
全二重通信の用途としては、 PICからの連続送信中に制御コードを送る等が考えられます
例えば「Ctrl-C (0x03:ETX)」は,
プログラムに割り込むための「ブレーク・キャラクタ」として
用いられます
|
|
(4) | A/D |
|
A/D変換は 13命令サイクルで実行されますが、ここでは 104μSのループで 1回の変換を行い
ノイズの影響を減らす目的で、256回平均します
8bitの A/D値を 256回加算すると結果は 16bitとなりますので上位 8bitを利用する事で
割算しなくても 1/256の結果が得られます
104μS×256=26,624μS 26mS毎に 1回( 1秒間に約37回) の測定(A/D変換)が行えます
例えば 16回平均したい場合は、16回加算した結果を右に 4bitシフトすれば得られます
|
|
(5) | PWM |
|
10F222 には PWMユニットも内臓されていないので、ソフトウェアで作成します
繰返周波数は(104μSを 256分周した)約37Hz、分解能は 256段階とします
(LEDの明るさを制御するには十分な繰返周波数と分解能です)
|
|
| 目次へ |
| | | |
回路図 Schematic(Circuit Diagram) |
|
(最上段の写真の)回路にはパターンで用意した LEDや抵抗を記載していますが、実際には
CPUとバイパスコンデンサのみ実装して、ブレークアウトボードとして使用しました
|
|
黄色:ブレッドボードで結線 白色:ブレークアウトボードに実装 灰色:未実装部品 |
(結線の注意点)
USB-Serial ユニットとの接続は、RXD-TXD、TXD-RXD となっています
|
|
基板パターン Pattern |
| 片面基板でも製作可能な様にデザインしました(ピンヘッダ部のスルーホールを止める) |
|
|
| 目次へ |
| | | |
機能 |
|
プログラムメモリ:512ワード、データメモリ:23バイト
内臓 CRクロックオシレータ:4/8MHz(OSC校正値がメモリ最終番地に記録されている)
入出力ポートは 3ピン、入力ポートが 1ピン
タイマーは 8ビット長が 1本
A/Dコンバータは 8bitが 2CH
|
|
制約 |
|
割込機能は無し(いつ起こるか分からない事象は常に監視する必要あり)
スタックは 2レベル(サブルーチンの使い方に工夫が必要)
命令数は全33個と少ない(特殊用途の OPTON、TRIS命令を除くと 31命令相当)
|
| |
SUBLW、ADDLW は他の命令に置き換える必要がありる
RETURN 命令の代わりに RETLW 命令で代用しなければならないので
W レジスタによるパラメータの受け渡しができない(ワーキングメモリで受け渡し)
|
|
| 目次へ |
|
|
| | | |
一定間隔の時間(104μS)を作る |
(1) | なぜ 104μS にするのか? ( 104(μS)が正確ならビットレートとの誤差 +0.16% ) |
|
シリアル通信の基準クロックとする
クロックは通信ビットレートの 1/(2のべき乗) にします
例えば 1200bps の 1bit の時間は 1(sec)/1200(bps)≒833(μS)
833(μS)/8≒104(μS) (2のべき乗)は 8以上にする理由は次の項で
104μSの間に実行できるプログラム命令数は、 104(μS)/0.5(μS)=208(命令)
プログラムメモリの総容量は 512ワードなので、初期化部分に 16ワード程度で、
ループ内に置いた命令の半分位が毎回実行されるとすればバランスも良いと思います
|
| 20mS と 1Sec を作る (クロックが正確なら誤差 -0.16% の正確な時間を作れます) |
|
104(μS)*192=19968(μS)≒20(mS) (分周は 1/256(1BYTE)以内が処理し易い)
104(μS)*192*50=998400(μS)≒1(Sec)
かなり正確な時間を作れます
20mS は、スイッチやリレーなどの接点入力時のチャター回避に用います
1Sec(1/4〜2Sec) は、LED点滅などに用います
|
|
(2) | 処理時間のイメージ |
| |
|
(3) | 概略の処理フロー |
|
; タイマーをゼロにセットする
; 必要な処理を行う
; 104μS以内に処理が終わる様にする
; タイマー値が 200(104μS)になったかチェックする
; 200(104μS)になるまで [タイマーチェック] を繰り返す
; 200(104μS)になったら [TMR0=0] へ、ループする
|
|
(4) | サンプルコード例 |
| |
;---------------------------------------------------------------
; 定数の設定
;---------------------------------------------------------------
_TMR0 EQU 200 ; タイマ設定値(104μS)
;
;---------------------------------------------------------------
; リセットスタート
;---------------------------------------------------------------
ORG 0x000 ; Reset vector
MOVWF OSCCAL ; oscillator calibration
;
; ここに初期化処理を記述
;
;---------------------------------------------------------------
; メインループ(初め)
;---------------------------------------------------------------
LOOP CLRF TMR0 ; TMR0を 0にする
;
;***** BSF GPIO,GP2 ;【DEBUG】信号発生 GP2:ON
;
; ここにメイン処理を記述
;
;---------------------------------------------------------------
; TMR0が設定値になるまで時間調整する(時間潰し)
;---------------------------------------------------------------
;***** BCF GPIO,GP2 ;【DEBUG】信号発生 GP2:OFF
;
CKTM0L MOVLW _TMR0
SUBWF TMR0,W ; TMR0 - _TMR0
BTFSS STATUS,C
GOTO CKTM0L ; TMR0 < _TMR0
GOTO LOOP ; TMR0 >= _TMR0
;
; 以下にサブルーチンを記述
| |
|
|
|
(5) | メインループの時間を測ってみた (正確に 104μS間隔です) |
|
テストパルス(赤)
(GP2に信号を出力して記録)
タイマーをゼロにした直後に ON、
時間潰しループ直前に OFFする
中央の波形の幅が広いのは、実行
命令数が多く時間がかかったため
まだかなり余裕がある事がわかる
LED点灯信号(黄)
PWMで点灯している信号
|
|
| 目次へ |
| | | |
|
A/D変換 と 簡易 PWM |
|
;---------------------------------------------------------------
; ; PWM処理
;---------------------------------------------------------------
INCFSZ WPWMCT,F
GOTO AD_SUM ;><0
; ; =0
BSF GPIO,GP1
; ;-------------------------------
; ; A/Dデータ平均化処理 (1/256)
MOVF WADRSH,W ;-------------------------------
MOVWF WADRES ;平均値を保存
CLRF WADRSH ;初期化(H)
MOVF ADRES,W
MOVWF WADRSL ;初期化(L)
BSF ADCON0,GO ;(Next) A/D Start
GOTO PWMCHK
; ;-------------------------------
; ; A/Dデータ加算
AD_SUM ;-------------------------------
BTFSC ADCON0,GO_NOT_DONE
GOTO PWMCHK ;NOT_DONE
; ;DONE
BSF ADCON0,GO ;(Next) A/D Start
MOVF ADRES,W
ADDWF WADRSL,F ;(WADRSL)+(W)-->(WADRSL)
BTFSS STATUS,C
GOTO PWMCHK ;桁上がり無
INCF WADRSH,F ;桁上がり有
;
; ;-------------------------------
PWMCHK ; PWM処理
MOVLW 0xFF ;-------------------------------
SUBWF WPWMCT,W ;(WPWMCT) - (W)
BTFSC STATUS,Z
GOTO PWMEND ; 0xFF
;
MOVF WADRES,W ;A/D data
SUBWF WPWMCT,W ;(WPWMCT) - (W)
BTFSC STATUS,C
BCF GPIO,GP1 ; > 0 (負)
; ; =< 0 (正)
PWMEND
| |
8bit(256)カウンタ
256回に 1回の処理
カウントが0の時パルスONする
(1/256)平均化のために
A/Dデータ加算結果(16bit)の
上位(8bit)だけを使用する
毎回の処理(104μS毎)
一応A/D完了をチェックするが
104μS毎では必ず完了している
A/Dデータ(8bit)の読取と加算
8bitデータを256回加算すると
結果は最大16bitとなる
PWMパルス幅を決める
カウントがパルス幅指令値に
達した時パルスOFFする
|
|
| 目次へ |
| | | |
|
UARTから文字受信する手順 |
|
;---------------------------------------------------------------
; ; 受信データ処理
;---------------------------------------------------------------
BTFSS WTRSTS,RXBFUL ;RX Done ?
GOTO RXPEND ;Not done 次の処理へ
;Done
BTFSC WTRSTS,RXOVFE ;RX Over run Err Flag ?
GOTO RXFLCL ;受信Err エラー:データを捨てる
; ;受信OK
MOVF WRXDTB,W
MOVWF TXBF_3 ;バッファへ
;
MOVLW ":"
MOVWF TXBF_2 ;バッファへ
;
SWAPF WRXDTB,W ;Hi側 (HHHHxxxx)
CALL TXHEXL ;Lo側 (xxxxHHHH)-->(HEX)
MOVF WXHEXL,W
MOVWF TXBF_1 ;バッファ上位へ
;
MOVF WRXDTB,W
CALL TXHEXL ;Lo側 (xxxxHHHH)-->(HEX)
MOVF WXHEXL,W
MOVWF TXBF_0 ;バッファ下位へ
;
MOVLW 6
MOVWF TXBFCT ;文字数(CR,LF含)カウントセット
;
RXFLCL ;-----------------------;Control Flag clear
BCF WTRSTS,RXOVFE ;RX Over run Err Flag clear
NOP ;avoidance of behavior "Read-modify-write"
BCF WTRSTS,RXBFUL ;RX Done flag
RXPEND ;-----------------------;RX Data Process END
| |
|
|
|
| 目次へ |
| | | |
|
UARTへ文字列送信 |
|
;---------------------------------------------------------------
; ; 文字送信処理
;---------------------------------------------------------------
BTFSS WTRSTS,TXDNST
GOTO TXPEND ; 0: TX Busy(Start)
; ; 1: TX Done
MOVF TXBFCT,W
BTFSC STATUS,Z
GOTO TXPEND ; =0: No data
; ; ><0:
;
MOVLW 1 ;----- 1文字目[LF]の処理 ------
SUBWF TXBFCT,W ;(TXBFCT)-1
BTFSS STATUS,Z
GOTO TXCHR2 ; ><1
MOVLW 0x0A ; =1
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
GOTO TXPEND
;
TXCHR2 MOVLW 2 ;----- 2文字目[CR]の処理 -------
SUBWF TXBFCT,W ;(TXBFCT)-2
BTFSS STATUS,Z
GOTO TXCHR3 ; ><2
MOVLW 0x0D ; =2
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
GOTO TXPEND
;
TXCHR3 MOVLW 3 ;----- 3文字目(TXBF_0)の処理 --
SUBWF TXBFCT,W ;(TXBFCT)-3
BTFSS STATUS,Z
GOTO TXCHR4 ; ><3
MOVF TXBF_0,W ; =3
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
GOTO TXPEND
;
TXCHR4 MOVLW 4 ;----- 4文字目(TXBF_1)の処理 --
SUBWF TXBFCT,W ;(TXBFCT)-4
BTFSS STATUS,Z
GOTO TXCHR5 ; ><4
MOVF TXBF_1,W ; =4
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
GOTO TXPEND
;
TXCHR5 MOVLW 5 ;----- 5文字目(TXBF_2)の処理 --
SUBWF TXBFCT,W ;(TXBFCT)-5
BTFSS STATUS,Z
GOTO TXCHR6 ; ><5
MOVF TXBF_2,W ; =5
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
GOTO TXPEND
;
TXCHR6 MOVLW 6 ;----- 6文字目(TXBF_3)の処理 --
SUBWF TXBFCT,W ;(TXBFCT)-6
BTFSS STATUS,Z
GOTO TXPEND ; ><6
MOVF TXBF_3,W ; =6
MOVWF WTXDTB
BCF WTRSTS,TXDNST ;TX Done/Start
DECF TXBFCT,F ;(TXBFCT)-1 -->(TXBFCT)
;***** GOTO TXPEND
;
TXPEND
| |
|
|
|
| 目次へ |
| | | |
|
UART受信データで LEDの明るさを変える |
|
(製作中! しばらくお待ち下さい)
|
|
| 目次へ |
お詫び:新しい記事は制作が間に合っていません (しばらくお待ち下さい) |
リンクの貼ってある(下線の有る)項目のみご覧頂けます |
【お礼 と お願い】
・ ホームページで情報公開している方々の貴重な体験を活用させて頂きました
オリジナルがある場合は参照出来る様に場所を示し詳細は省いています
・ 内容はありのままを記載していますが、間違いや誤解があるかもしれません
試す場合は全てご自身の責任で行って下さい
・ リンクは自由ですが、商用への写真・図の転載等全て禁止です
|
ご意見、ご感想、間違い指摘 ..... 等は
掲示板(BBS) 又は
<> へお願いします
|
―Sorry! Japanese only― |
Copyright (c)2000 Old-Ordinary Allrights resrved |
古風平凡 |
|
|