LPC1343のユーザーズ・マニュアル(URLは下記)も参考にしてください。 http://ics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc13xx.pdf 100 \ "MENU:-" \ // 改行して”MENU:-"表示し、更に改行 110 "[[END]]] :0" \ // "[[END]]] :0"と表示して、改行 120 "TEMP. RD :1" \ // "TEMP. RD :1"と表示して、改行 130 "LED BLINK:2" \ // "LED BLINK:2"と表示して、改行 140 "TOUCH SW :3" \ // "TOUCH SW :3"と表示して、改行 150 "RTC RD :4" \ // "RTC RD :4"と表示して、改行 160 "A/D RD :5" \ // "A/D RD :5"と表示して、改行 170 "PWMOUT :6" \ // "PWMOUT :6"と表示して、改行 180 "SELECT ?" A=? // "SELECT ?"と表示して数値入力待ち。値は変数Aに入れる 190 IF A=0 END // 0が入力されたら終了 200 IF (A<=6) GOSUB A*1000 // 6以下だったら(入力値*1000)の行番号の行に飛ぶ 210 GOTO 100 // 6より大きい値だったら再度メニュー表示(入力しなおし) 1000 '== LM75 (I2C-BUS) == // LM75(I2Cバス)テスト 1010 P=$40000000 P(6)=$6C P(4)=660 P(5)=660 //I2C0CONCLR($40000000+6*4)に$6C(I2C関連フラグクリア) //I2C0SCLH、I2CSCLLを共に660:66MHz÷(660+660)=50kHz 1020 P(0)=$40 'ENABLE I2C //I2C0CONSETのI2ENビットをセット:I2Cコントローラ動作開始 1030 '***START & SEND ADDRESS*** //*スタートコンディションとアクセス先のアドレス送出 1040 P(0)=$20 'START COND. //I2C0CONSETのSTAビットをセットしてスタートコンディション生成 1050 D=$92 W=$18 GOSUB 1800 //$92(10010010:上位7ビットはLM75のアドレス)を送る。最下位ビット='0'なのでライト方向 //ステータスが$18:SLA+W has been transmitted; ACK has been received.:になるまで待つ 1060 '***SEND REG.# *** //アクセスしたいレジスタ番号を送る 1070 P(6)=$20 'CLR START //通常のデータ伝送モードに戻す 1080 D=$00 W=$28 GOSUB 1800 //LM75のレジスタ番号$00(温度データ)を指定 //Data byte in I2DAT has been transmitted; ACK has been received.になるのを待つ 1090 '***STOP&RESTART*** //*ライト方向を終了して、再度スタート 1100 P(0)=$10 'STOP CONDITON //I2CCONSETのSTOビットをセットして、いったんSTOP 1110 P(0)=$20 'RE-START CONDITION //I2C0CNSETのSTAビットをセットしてリスタートコンディション生成 1120 P(6)=$08 W=$08 GOSUB 1810 //I2C0CONCLRのSIC(I2C割込み)フラグクリア //A START condition has been transmitted.を待つ 1130 '***WR ADDRESS*** //*再びLM75を指定 1140 D=$93 W=$40 GOSUB 1800 //$92(10010011:上位7ビットはLM75のアドレス)を送る。最下位ビット='1'なのでリード方向 1150 '***RX DATA HIGH*** //*今度はリード(さっき指定したレジスタ番号0の値が読める):温度データ上位 1160 P(6)=$20 P(0)=$04 'CLR START&SEND ACK //I2C0CONCLRのSTACビットをセットしてSTARTフラグをクリア //I2C0CONSETのAAビットをセットしてACK応答 1170 W=$50 GOSUB 1900 //I2C0CONCLRのSIC(I2C割込み)フラグをクリアして //Data byte has been received; ACK has been returned.を待つ 1180 H=P(2) //I2C0DAT(データレジスタ)を読む(上位データが先に読める) 1190 '***RX DATA LOW*** //引き続き温度データ下位バイト 1200 P(6)=$04 'SEND NAK //I2C0CONCLRのAACをセットして、NAK応答 1210 W=$58 GOSUB 1900 //Data byte has been received; NOT ACK has been returned.を待つ 1220 L=P(2) //I2C0DAT(データレジスタ)を読む(下位データが読める) 1230 '***STOP&INZ*** //読み終わったので終了 1240 P(0)=$10 'STOP CONDITION //I2CCONSETのSTOビットをたてて、STOPコンディション生成 1250 P(6)=$2C //I2C0CONCLRのSTAC、SIC、AACをクリアしてデータ伝送終了 1260 '***DISP.*** //*読み取ったデータの表示 1270 D = (H<<3) | (L >>5) //温度データはH[7:0]:L[7:5]の11ビット。下位8ビット分をDに入れてみた 1280 ?=H "." ?=(L>>5)*125 \ //0.125℃ステップなので、上位が整数部分、下位は小数点以下 1290 '***WAIT*** 1300 .%(41)=0 //割り込みカウンタを0クリア 1310 A=?? IF A>$0D RETURN //改行キーが入力されたらリターン 1320 IF .%(41)<25 GOTO .-10 //250ms(10ms割込みが25回)まではループしてキー待ち 1330 GOTO 1000 //入力が無いまま250msたったので、再度温度読み込み&表示を実行 1790 '***TX I2C DATA*** //*I2C送信ルーチン 1800 P(2)=D P(6)=$08 //I2C0DATレジスタにデータ書込み //I2C0CONCLRのSIC(割込みフラグ)クリア 1810 IF P(1)<>W GOTO . //I2C0STAT(ステータス)が変数Wになるまでループ 1820 RETURN //終了(リターン) 1890 '***RX I2C DAT*** //*I2C受信ルーチン 1900 P(6)=$08 //I2CCONCLRのSIC(割込みフラグ)クリア 1910 IF P(1)<>W GOTO . //I2C0STAT(ステータス)が変数Wになるまでループ 1920 RETURN //終了(リターン):データ取得はメイン側で行う 1990 '==LED BLINK== //*LED点滅テスト 2000 "LED BLINKING" \ //"LED BLINKING"と表示して改行 2000 P=$50008000 P(0)=P(0)|$80 //GPIO0DIRのビット7(PIO0_7)を'1'にセット(PIO0_7を出力に設定) 2010 P=$50000200 D=$80 //$50000000+(00 1000 0000 00):GPIO0のビット7だけをアクセスするポートアドレス //データはビット7以外は何でも良い(他のビットはアドレスでマスクされるため) 2020 GOSUB 2100 A=?? IF A<=$D GOTO . //ポート出力&ディレイで改行キーが入ってくるまでON/OFFを繰りかえし。 2030 RETURN //終了 2090 '***PORT OUT&DELAY*** //*ポートアクセスルーチン 2100 IF (D & $80)<>0 "ON" \ GOTO .+20 //ビット7(LEDポートがPIO0_7なので)が'1'なら'ON'表示して改行 2110 "OFF" \ //'0'だったら'OFF'表示して改行 2120 P(0)=D D=D^$80 .%(41)=0 //データ出力してビット7を反転(点滅させるため)、割込みカウンタクリア 2130 IF .%(41)<100 GOTO . //1秒(10msのタイマ割込み100回)たつまでループ 2140 RETURN //終了して戻る 2990 '=TOUCH SWITCH== //*タッチスイッチ(PCF8883):PIO2_4に接続 3000 P=$50020040 //$50020000+(00 0001 0000 00:GPIO2のビット7だけをアクセスするポートアドレス 3010 "TOUCH SWITCH TEST"\ //"TOUCH SWITCH TEST"と表示して改行 3020 A=?? IF A>$0D RETURN //改行が入力されたら終了(リターン) 3030 IF P(0)=0 GOTO .-10 //PIO2_4が'0'(タッチされていない)なら1行前(改行入力チェック)へ 3040 "TOUCH ON!"\ //"TOUCH ON!"と表示して改行 3050 A=?? IF A>$0D RETURN //改行が入力されたら終了(リターン) 3060 IF P(0)<>0 GOTO .-10 //PIO2_4が'1'(タッチされている)なら1行前(改行入力チェック)へ 3070 "TOUCH OFF!"\ //"TOUCH OFF!"と表示して改行 3080 GOTO .-60 //3020行にジャンプ 3990 '==RTC(SPI-BUS)== //*RTC(時計)アクセス:SPIバス経由 4000 P=$50008000 P(0)=$04 'SET P0_2 AS OUTPUT //GPIO0DIRのビット2(PIO0_2)を'1'にセット(PIO0_2を出力に設定) 4010 P=$50018010 P(0)=$10 //GPIO1IEのビット4を'1'にしてPIO1_4からの割込みをイネーブル 4020 P=$E000E100 P(1)=P(1) | $800000 //NVICのISER1のビット23(ISE_PIO_1)をセットしてPIO1割込みイネーブル 4030 P=$40040010 P(0)=20 //SSP0CPSRに20をセット(66MHz÷(20×(65+1))=50kHz) 4040 P=$40040000 P(0)=$4107 P(1)=$2 //SSP0CR0:SCR=$41(=65) //SSP0CR0:CHPA=CPOL=FRF=0 //SSP0CR0:DSS=0111(8bit Mode) 4050 R=$10 D=$58 GOSUB 4800 'RESET RTC //Control_1=$58:ソフトウェアリセットコマンド発行 4060 R=$10 D=$00 GOSUB 4800 '24-HOUR MODE //Control_1=$00:リセット解除、24時間モード 4070 R=$11 D=$02 GOSUB 4800 'AIE='1' //Control_2=$02:AIE='1':アラーム割込みイネーブル 4080 R=$12 D=$50 GOSUB 4800 'SEC //Seconds=$50:50秒 4090 R=$13 D=$59 GOSUB 4800 'MIN //Minutes=$59:59分 4100 R=$14 D=$23 GOSUB 4800 'HOUR //Hours =$23:23時 4110 R=$15 D=$31 GOSUB 4800 'DAY //Days =$31:31日 4120 R=$16 D=$06 GOSUB 4800 'WEEK //Weekdays=$06:週末 4130 R=$17 D=$12 GOSUB 4800 'MON //Months =$12:12月 4140 R=$18 D=$10 GOSUB 4800 'YEAR //Years =$10:10年 4150 R=$19 D=$01 GOSUB 4800 'ALM_MIN //Minute_alarm=$01:01分 4160 R=$1A D=$00 GOSUB 4800 'ALM_HOUR //Hour_alarm =$00:00時 4170 R=$1B D=$01 GOSUB 4800 'ALM_DAY //Day_alarm  =$01:1日 4180 R=$1C D=$00 GOSUB 4800 'ALM_WEEK //Weekday_alarm=$00:週始め 4190 .%(55)=0 T=0 "YY MM WW DD HH MM SS" \ //RTC割込みカウンタクリア、"YY MM WW DD HH MM SS"表示して改行 4200 P=$50000010 P(0)=$04 //$50000000+(00 0100 00):GPIO0のビット2(RTCのCE)を'1'にセット:チップイネーブル 4210 X=$92 GOSUB 4900 //レジスタ#2(Secondsレジスタ)リード要求 4220 X=$FF GOSUB 4900 S=X 'SEC //レジスタ#2(Secons) 4230 X=$FF GOSUB 4900 M=X 'MIN //レジスタ#3(Minutes) 4240 X=$FF GOSUB 4900 H=X 'HOUR //レジスタ#4(Hours) 4250 X=$FF GOSUB 4900 D=X 'DAY //レジスタ#5(Days) 4260 X=$FF GOSUB 4900 W=X 'WEEKDAY //レジスタ#6(Weekdays) 4270 X=$FF GOSUB 4900 N=X 'MONTH //レジスタ#7(Months) 4280 X=$FF GOSUB 4900 Y=X 'YEAR //レジスタ#8(Years) 4290 P=$50000010 P(0)=$00 //CEを'0'に戻す(非選択状態) 4300 IF T=S GOTO .-100 //前回の秒値から変化が無ければ再読み込み 4310 T=S //秒値をセーブ 4320 ?=(Y>>4)&$F ?=(Y & $F) " " //年表示(上位4ビット値、下位4ビット値の順に表示) 4330 ?=(N>>4)&1 ?=(N & $F) " " //月表示 4340 ?=(W>>4)&0 ?=(W & $7) " " //曜日値表示 4350 ?=(D>>4)&3 ?=(D & $F) " " //日表示 4360 ?=(H>>4)&3 ?=(H & $F) " " //時表示 4370 ?=(M>>4)&7 ?=(M & $F) " " //分表示 4380 ?=(S>>4)&7 ?=(S & $F) \ //秒表示して改行 4390 A=?? IF A>$0D RETURN //改行キーが入力されていたら終了 4400 D=.%(55) IF (D & $FFFF)=0 GOTO .-200 //RTC割込みが発生していなければ再度RTC読み込み 4410 "INTERRUPT! STATUS=" ??=D \ //RTC割込みが発生したら"INTERRUPT! STATUS="と表示して、割込みカウント値を表示 4420 RETURN //終了 4790 '*** WR RTC *** //*RTCへのライトアクセス 4800 P=$50000010 P(0)=$04 //CE(PIO0_2に接続)を'1'にする 4810 X=R GOSUB 4900 //レジスタ番号送出 4820 X=D GOSUB 4900 //データ送出 4830 P=$50000010 P(0)=$00 //CE(PIO0_2に接続)を'0'に戻す 4840 RETURN //終了 4890 '*** RD RTC *** //*RTCのリードアクセス 4900 P=$40040000 //SSPのベースアドレス 4910 IF (P(3) & $4)<>0 @=P(2) GOTO . 'DISPOSE RX DATA //SSP0SRのRNEが0ではない(何かデータが入っている)なら、SSP0DRを読み捨てる 4920 IF (P(3) & $1)<>1 GOTO . 'CHK TX_FIFO EMPTY //SSP0SRのTFEが1ではない(送信FIFOに何か入っている)なら空になるのを待つ 4930 P(2)=X 'SEND DATA //SSP0DRにデータを書き込み(データ送信) 4940 IF (P(3) & $4)=0 GOTO . //SSP0SRのRNEが0ならば(データが入っていない:送信完了していない)ならループして待つ 4950 X=P(2) 'RECEIVE DATA //送信完了していたら、SSP0DRを読み出しておく 4960 IF (P(3) & $10)<>0 GOTO . 'WAIT BSY=0 //SSP0SRのBSYビット(ビジー)が0でない(SSPが動作中)ならループして待つ 4970 RETURN //動作完了したので、終了 4990 '== ADC == //*ADCの値表示 5000 P=$40044080 P(0)=$52 P=$4001C000 //IOCON_R_PIO1_2=$52 アナログ入力ピンとして使う。AD3として使う。PをADCのベースアドレスに設定 5010 .%(41)=0 //タイマ割込みカウンタをクリア 5020 C=3 GOSUB 5900 V=1250*1024/D "VDD=" ?=V "mV " GOSUB 5800 //チャンネル#3(基準電圧)を計測。3.3V電源電圧の推定して表示した後、A/Dデータ表示 5030 C=6 GOSUB 5900 GOSUB 5800 //チャンネル#6値表示 5040 C=7 GOSUB 5900 GOSUB 5800 \ //チャンネル#7値表示 5050 A=?? IF A>$0D RETURN //改行入力されたら終了 5060 IF .%(41)<25 GOTO .-10 //250msたつまでウェイト 5070 GOTO .-60 //5010行に戻る 5790 '**DSP DAT** //*データ表示 5800 E=V*D/1024 F=E/1000 G=E%1000 //Fが整数部分、Gが小数点以下 5810 "AD" ?=C "=" ?%=D "(" ?=D "):" ?=F "." //AD値のあと”F.G”の形式で表示するため、まずF値を表示 5820 IF G<100 "0" IF G<10 "0" //Gが100未満なら0を補う 5830 ?=G "V " //G値を表示 5840 RETURN //終了 5890 '**RD ADC** //ADCの読み込み 5900 P(0)=$01000E00 + (1 << C) //AD0CR=$01000E00+チャンネルビット位置 //AD0CR:START='001':変換スタート //AD0CR:CLKDIV=$0E :4.4MHz 5910 D=P(1) IF (D & $80000000)=0 GOTO . //AD0GDR読み込み:ビット31(DONE)='0'なら変換終了していないのでループ 5920 D=(D>>6) & $3FF //AD0GDR[15:6]が変換結果なので6ビット右シフト 5930 RETURN //終了 5990 '== PWM OUT == //*PWM出力 6000 P=$40010000 S=$E000E100 R=$E000E180 B=1000000 //P:CT16B1のベースアドレス //S:ISER0 //R:ICER0 //B:ベースクロック:1MHzの意 6010 D=100 S(1)=$400 //Dは出力周波数。ISER1:ISE_CT16B1をセット(CT16B1割込みイネーブル) 6020 P(1)=2 P(6)=B/D/2 P(7)=B/D-1 .%(41)=0 .%(42)=0 P(1)=1 //TMR16B1TCR=2:カウンタリセット //TMR16B1MR0(マッチレジスタ0:パルス幅)をB/D÷2に設定 //TMR16B1MR1(マッチレジスタ1:周期)をB/D-1に設定 //タイマ割込みカウンタクリア //CT16B1割込みカウンタクリア //TMR16B1TCR=1:カウンタイネーブル 6030 ?=D "HZ" D=D+((D>=1000)*900)+100 //Dの値を表示。100Hzから順次100Hzずつふやして、1000Hz以上になったら1000Hzずつ増やす 6040 A=?? IF A>$0D \ P(1)=2 R(1)=$400 RETURN //改行が入力されたら、カウンタリセットして終了 6050 IF .%(41) <100 GOTO .-10 //100msウェイト 6060 " " ?=.%(42) \ GOTO (D<=10000)*10+6010 //タイマ割込みカウンタを表示 //10kHz以下なら6020行、10kHzを超えたら6010行に戻る