Old PIC(Home) > 事例編 PIC10F222
事例編 PIC10F222  (Old PIC) 


 PIC10F222T-I/OT最も小型な SOT-23(6pin) パッケージは面白い応用ができそう
目  次内  容更新日
概要最近の傾向 ちっちゃな物が好き やってみた事2017/11/10
仕様と規格規格:調歩同期(シリアル信号) 仕様:UART、A/D、PWM
回路と基板回路図 基板パターン (基板手配は別項で)
10F222の機能と制約8MHz,512Word,23Byte,I/O:4,8bitTMR,2ch-8bitA/D
ソフトの基本構造一定間隔の時間(104μS)を作る
    ソフトUART別項に独立させました
    A/D と PWMA/D変換(平均化) と (簡易)PWM
    文字列受信UARTから文字列受信
    文字列送信UARTへ文字列送信
    A/D-->LEDA/D変換データで LEDの明るさを変える
    UART-->LEDUART受信データで LEDの明るさを変える
 [Home]へ




 概要具体事例ではなく「こんな事ができる」と言うサンプルです 

最近の傾向
  最近は「猫も杓子も 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
 片面基板でも製作可能な様にデザインしました(ピンヘッダ部のスルーホールを止める)
 
 目次へ


 10F222の機能と制約Datasheet データシート 

機能
  プログラムメモリ: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ワード程度で、
ループ内に置いた命令の半分位が毎回実行されるとすればバランスも良いと思います

 20mS1Sec を作る  (クロックが正確なら誤差 -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で点灯している信号 
 
 目次へ
ソフトウェア-UART   (別項に独立させました
 
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) 又は <E-mail> へお願いします
―Sorry! Japanese only― Copyright (c)2000 Old-Ordinary Allrights resrved  古風平凡


 
 
inserted by FC2 system