PIC12F1822をアセンブラでいろいろ動作させてみたので、少しづつ公開していきたいと思います。
まず、今頃PICかよっ!と突っ込みたくなる方も沢山いると思います。世の中にはArduinoやmbed等、いわゆるマイコンをより簡単にプログラミングできるボードが沢山あります。その流れにPICは完全に乗り遅れているのは事実です。
では、なぜPICなの?ということに対しての答えになりますが、それは、私が使いこなしているマイコンだからです。
PICは始めての方には癖のある構造であると良く言われます。==> はい、その通りです。
一つの命令を実行するのに4clock cycleかかります(avrは1clock cycleです) ==> はい、その通りです。
このように比較すると劣る部分があります。
しかし、これらは私にとって大きな問題とは思いません。これらを理解して使用できれば問題ではないと思います。
癖のある構造であるのは、慣れましたし、4cycleも慣れました。
今から、新しいマイコンにチャレンジするのに時間をかける必要もなく実現したいことができれば、上記は何も問題ではないのです。
8ピンのPICマイコンのPIC12F1822は、特に私が使いたい機能をこの小さいマイコンで持ち合わせています。
USART
PWM
SPI
ADC
タッチセンス
これがすべて入っています。特にUSARTは昔の8ピンの12Fxxxシリーズでは持っているものがありませんでした。そのためソフトウェアUSARTを実装する必要がありました。
しかし、12F1822はその必要もなく、今までの16FxxxシリーズのようにUSARTを使うことできます。
Web上では、12F1822をアセンブラで動作させている情報があまりなかったので、できるだけアップしていきたいと思います。
以下は、単純にRA0~RA5をHigh、Lowにするプログラム。RA0~RA5に1kΩの抵抗を介してLEDをつなげばLチカになります。
内部の発振器を16MHzに設定しています。Delay関数は20MHzのときをそのまま移植したので、コメントアウトしている時間はあっていませんが、動作はします。
また、ソースコードの表示は以下のプラグインを使ってみました。アセンブラ表示用は特に見つからなかったので、htmlを[ ]でくくる形で表示させてみました。(ググれば沢山例がでてきます)
SyntaxHighlighter Evolved
;************************************************** ; ; Schematic ; ;************************************************** ; ; 12F1822 ; Internal 16MHz ; +------+ ; | |----------Vdd=5V ; | |----------RA5 ; | |----------RA4 ; | |----------RA3----4.7k---Vdd=5V ; | |----------RA2 ; | |----------RA1 ; | |----------RA0 ; | |----------Vss=GND ; +------+ ;************************************************** list p=12F1822 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF CBLOCK 0x20 ; Define GPR variable register locations COUNT COUNT1 COUNT2 COUNT3 COUNT4 ENDC ORG 0x0000 ; processor reset vector GOTO START ; When using debug header, first inst. ; may be passed over by ICD2. ;------------------------------------------------------------------------------ ; INTERRUPT SERVICE ROUTINE ;------------------------------------------------------------------------------ ORG 0x0004 ;------------------------------------------------------------------------------ ; USER INTERRUPT SERVICE ROUTINE GOES HERE ;------------------------------------------------------------------------------ ; Note the 12F1822 family automatically handles context restoration for ; W, STATUS, BSR, FSR, and PCLATH where previous templates for 16F families ; required manual restoration. Shadow registers store these SFR values, and ; shadow registers may be modified since they are readable and writable for ; modification to the context restoration. RETFIE ; return from interrupt ;------------------------------------------------------------------------------ ; MAIN PROGRAM ;------------------------------------------------------------------------------ START MOVLW B'00100' MOVWF BSR ;BANK4 MOVLW B'00000000' MOVWF WPUA ;WEAK PULL-UP PORTA REGISTER(BANK4) Disalbed :0, Enalbled :1 ;BIT5,4,3,2,1,0 ;Note 1: Global WPUEN bit of the OPTION register must be cleared for individual pull-ups to be enabled. ;Note 2: The weak pull-up device is automatically disabled if the pin is in configured as an output. MOVLW B'00011' MOVWF BSR ;BANK3 MOVLW B'00000000' MOVWF ANSELA ;PORTA ANALOG SELECT REGISTER(BANK3) DIGITAL : 0, ANALOG : 1 ;BIT4 RA4 ;BIT2 RA2 ;BIT1 RA1 ;BIT0 RA0 MOVLW B'00010' MOVWF BSR ;BANK2 MOVLW B'00000000' MOVWF APFCON ;ALTERNATE PIN FUNCTION CONTROL REGISTER(BANK2) ;BIT 7 RX/DT assign to RA1 : 0, RA5 : 1 ;BIT 6 SDO assign to RA0 : 0, RA4 : 1 ;BIT 5 /SS assign to RA3 : 0, RA0 : 1 ;BIT 3 T1G assign to RA4 : 0, RA3 : 1 ;BIT 2 TX/CK assign to RA0 : 0, RA4 : 1 ;BIT 1 P1B assign to RA0 : 0, RA4 : 1 ;BIT 0 CCP1 assign to RA2 : 0, RA5 : 1 MOVLW B'00000000' MOVWF LATA ;PORTA DATA LATCH REGISTER(BANK2) ;BIT5,4,2,1,0 MOVLW B'00001' MOVWF BSR ;BANK1 MOVLW B'00000000' MOVWF TRISA ;(BANK1) MOVLW B'01111000' MOVWF OSCCON ;(BANK1) ;OSCILLATOR CONTROL REGISTER ;BIT7 SPLLEN software pll enabled/disalbed ;BIT6~3 IRCF Osc Freq 1111=16MHz ;BIT1~0 SCS System Clock Select bits 00=Clock determined by FOSC in CONFIG1 MOVLW B'00000' MOVWF BSR ;BANK0 MOVLW B'11111111' MOVWF PORTA ;(BANK0) ;------------------------------------------------------------------------------ ; MAIN ;------------------------------------------------------------------------------ MAINLOOP MOVLW B'11111110' MOVWF PORTA CALL TIME10M MOVLW B'11111101' MOVWF PORTA CALL TIME10M MOVLW B'11111011' MOVWF PORTA CALL TIME10M MOVLW B'11101111' MOVWF PORTA CALL TIME10M MOVLW B'11011111' MOVWF PORTA CALL TIME10M GOTO MAINLOOP ;*********************************************************** ;Delays ;*********************************************************** ;100us(20MHz) ;0.2us x 500 = 100us TIME100 MOVLW D'165' ; 1cycle MOVWF COUNT ; 1cycle NOP ; 1cycle dummy NOP ; 1cycle dummy LOOP DECFSZ COUNT,F ; 1×(165-1)+2 = 166cycle GOTO LOOP ; 2×(165-1) = 328cycle RETURN ; 2cycle ; 1+1+1+1+166+328+2=500cycle ;49.2us(20MHz) ;0.2us x 246 = 49.2us TIME50 MOVLW D'81' ; 1cycle MOVWF COUNT ; 1cycle ;NOP ; 1cycle dummy ;NOP ; 1cycle dummy ;NOP ; 1cycle dummy LOOP50 DECFSZ COUNT,F ; 1×(81-1)+2 = 82cycle GOTO LOOP50 ; 2×(81-1) = 160cycle RETURN ; 2cycle ; 1+1+82+160+2=246cycle ;10ms(20MHz) ;0.2us x 50000 = 10000us(10ms) TIME10M MOVLW D'99' ; 1cycle MOVWF COUNT1 ; 1cycle NOP ; 1cycle dummy NOP ; 1cycle dummy LOOPP1 CALL TIME100 ; (2+500)×99=49698cycle DECFSZ COUNT1,F; 1×(99-1)+2 = 100cycle GOTO LOOPP1 ; 2×(99-1) = 196cycle RETURN ; 2cycle ; 1+1+1+1+49698+100+196+2 = 50000 ;1s(10MHz) ;0.2us x 5000000 =1000000 us TIME1S MOVLW 63H ; 1cycle 63H=99 MOVWF COUNT2 ; 1cycle MOVLW 62H ; 1cycle 62H=98 MOVWF COUNT3 ; 1cycle MOVLW 03H ; 1cycle 03H=3 MOVWF COUNT4 ; 1cycle NOP ; 1cycle dummy LOOPP2 CALL TIME10M ;(2+50000)×99=4950198cycle DECFSZ COUNT2,F; 1×(99-1)+2 = 100cycle GOTO LOOPP2 ; 2×(99-1) = 196cycle LOOPP3 CALL TIME100 ;(2+500)×98=49196cycle DECFSZ COUNT3,F; 1×(98-1)+2 = 99cycle GOTO LOOPP3 ; 2×(98-1) = 194cycle LOOPP4 DECFSZ COUNT4,F; 1×(3-1)+2 = 4cycle GOTO LOOPP4 ; 2×(3-1) = 4cycle RETURN ; 2cycle ; 1x7+4950198+100+196+49196+99+194+4+4+2=5000000cycle END