2.プログラム構造について

 PICマイコンに限らず、プログラム構造を決めてから、コーディングを開始するのが一般的ですが、一度決めたら同じ構造やスタイルでコーディングすれば迷わずスムーズに作業ができます。  以下は当工房がPIC16F系でコーディングに使用しているプログラミング構造を紹介しますので、参考にして独自の構造やスタイルを決めてください。

 

2.1 プログラミング構造の全体像

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


2.2       コーディング例

  実際のコーディング例を以下に示します。 じっくり眺めて、イメージを掴んでください。

  (この例は自動車のバッテリー電圧を監視し、バーLEDに電圧に応じたレベル表示(ダイナミック表示)を行うと共に、10.5 V以下に電圧降下すると警告ブザーを鳴らすものです。長いところは省略していますのでこのままでは使用できません。)

;

;******************************************************************

;******************************************************************

;  BATTERY MONITOR           Rev.01  (programmed 2009/x/x)

;

;******************************************************************

                            LIST                    P=PIC16F88

                     #INCLUDE         "P16F88.INC"

__CONFIG    _CONFIG1, _INTRC_IO & _BODEN_OFF & _WDT_OFF & _CP_ALL & _PWRTE_OFF & _CPD_OFF & _LVP_OFF & _MCLR_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF

                            __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

;

; PIC16F88  8 MHz  internal clock

;******************************************************************

; Pin assignment (18 pins)

;

; PORT-A

; RA7<pin 16>:  OUT                     BLED(10)

; RA6<pin 15>:  OUT                   BLED(9)

; RA5<pin  4>:  IN(Fix)                Push.SW

; RA4<pin  3>:  OUT                    (not usd)  

;

; RA3<pin  2>:  OUT                    (not usd)

; RA2<pin  1>:  OUT                    Buzzer    

; RA1<pin 18>:  IN                        CDS

; RA0<pin 17>:  IN                        BATTERY Voltage                                                                    

;  

; PORT-B

; RB7<pin 13>:  OUT                     BLED(8)

; RB6<pin 12>:  OUT                    BLED(7)

; RB5<pin 11>:  OUT                   BLED(6)

; RB4<pin 10>:  OUT                     BLED(5) 

;

; RB3<pin  9>:  OUT                    BLED(4)

; RB2<pin  8>:  OUT                    BLED(3)  

; RB1<pin  7>:  OUT                    BLED(2)

; RB0<pin  6>:  OUT                  BLED(1)

;

;******************************************************************

; difine save area

;******************************************************************

;

LCNT                  EQU                    020H     ;level counter

DL910                 EQU                    021H     ;work area(H) for display

DL18                   EQU                    022H     ;(L)

DINP910             EQU                    023H     ;input data(H) for display

DINP18               EQU                    024H     ;(L)

;

INTCH                EQU                    025H     ;int. timer value

INTCL                 EQU                    026H     ;

;

IWSAVE              EQU                    027H     ;for int.

ISSAVE               EQU                    028H     ;

IPSAVE               EQU                    029H     ;

IFSAVE               EQU                    02AH     ;

;

;

DATA1H              EQU                    035H     ;for ADC

SDATA1              EQU                    036H     ;

SDATA2              EQU                    037H     ;

DATA1L              EQU                    038H     ;

;

CNT1                   EQU                    039H     ;loop timer cnt

CNT2                   EQU                    03AH     ;

CNT3                   EQU                    03BH     ;

CNT4                   EQU                    03CH     ;

CNT5                   EQU                    03DH    ;

CNT6                   EQU                    03EH     ;

;

;*****************************************

CFLAG                EQU                    050H     ;internal control flags 0

;

TOVR                  EQU                    7                          ;time over flag

;

 

ILLU                   EQU                    5                          ;illuminate LED

RBUZZ                EQU                    4                          ;ring buzzer

LON                    EQU                    3                          ;light on

SMODE               EQU                    2                          ;selectmodeMoniter(0),Flash(1)

;

EOC                    EQU                    1                          ;end of count

DTSW                 EQU                    0                          ;detect SW. on

;

;*****************************************

;PORT-A

BLED10              EQU                    7

BLED9                EQU                    6

PUSHSW            EQU                    5

;

BUZZ                  EQU                    2

CDSS                  EQU                    1

VSNS                  EQU                    0

;

;PORT-B

BLED8                EQU                    7

BLED7                EQU                    6

BLED6                EQU                    5

BLED5                EQU                    4

;

BLED4                EQU                    3

BLED3                EQU                    2

BLED2                EQU                    1

BLED1                EQU                    0

;

;******************************************************************

; Reset Vector

;******************************************************************

;

        ORG      0

        GOTO    INIT

;******************************************************************

; Interrupt Handler

;******************************************************************

;

        ORG      4

INTPROC

              BCF                     INTCON,GIE                    ;inhibit interrupt

              MOVWF              IWSAVE                          ;save reg's at interrupt

              SWAPF                STATUS,W                        ;

              MOVWF              ISSAVE                             ;

              MOVF                 PCLATH,W                       ;

              MOVWF              IPSAVE                             ;            

              MOVF                 FSR,W                               ;

              MOVWF              IFSAVE                             ;

              CLRF                   STATUS                            ;

;Decode Interrupt element

              BTFSC                PIR1,TMR1IF                   ;check TMR1 int.flag

              GOTO                  TMR1PROC                      ;

              BTFSC                PIR1,TMR2IF                   ;check TMR2 int.flag

              GOTO                  TMR2PROC                      ;

              GOTO                  PROCE                              ;

;

;                                                      

;********************************

; 5.5 minutes timer (262 ms interval)

;********************************

TMR1PROC

              BCF                     PIR1,TMR1IF                   ;clear TMR1 flag for next

              INCF                   INTCL,F                            ;count up int.timer(L)

              BTFSS                 STATUS,Z                         ;check carry over

              GOTO                  PROCE

              INCF                   INTCH,F                           ;count up int.timer(H) (67 sec.)     

              MOVLW              .5                                       ;check int. time over( 5.5 min.)

              SUBWF               INTCH,W                          ;

              BTFSS                 STATUS,Z                         ;

              GOTO                  PROCE

;

TPROC1

              BSF                     CFLAG,TOVR                   ;set time over flag

              CLRF                   INTCH                              ;reset int. timer

              CLRF                   INTCL                               ;

              GOTO                  PROCE

;                                                      

;********************************

;Bar-LED Dynamic Driver by Timer2 (8.2ms interval)

;********************************                                         

; input(2bytes): DINP18,DINP910

;                                        

TMR2PROC

              BCF                     PIR1,TMR2IF                   ;clear TMR2 flag for next

              MOVF                 DINP18,W                        ;get 1-8 level      

              MOVWF              PORTB                              ;display 1-8 level

              MOVLW              0C0H                                 ;get 9-10 level

              ANDWF              DINP910,W                      ;           

              IORWF                PORTA,F                           ;display 9-10 level

              CALL                   ITIM200U                         ;do bright control

              CLRF                   PORTB                              ;clear all data

              BCF                     PORTA,7                                         ;

              BCF                     PORTA,6                                         ;

              GOTO                  PROCE                              ;

;

;++++++++++++++++++++++++++++++++    

;  Timer Routine for Display

; ( 8 MHz clock used only )

; 100usec Timer Subroutine at 8 MHz

; 1CYCLE = 0.5 usec -> 200 cycle

;

; 200 usec Timer Subroutine

ITIM200U                                        

              MOVLW              .80                                     ;80 times

              MOVWF              ICNT1                               ;

ILOOP1

              NOP                                                              ;

              NOP                                                              ;(2+3)*80-1= 399 cycles  

              DECFSZ              ICNT1,F                            ;

              GOTO                  ILOOP1                             ;

              RETURN                                                       ;2+399+2=403 cycles

;                                                                                   ;200 usec.           

;*********************************

PROCE

              MOVF                 IFSAVE,W                         ;restore reg's

              MOVWF              FSR                                   ;

              MOVF                 IPSAVE,W                         ;

              MOVWF              PCLATH                            ;

              SWAPF                ISSAVE,W                         ;

              MOVWF              STATUS                            ;

              SWAPF                IWSAVE,F                         ;

              SWAPF                IWSAVE,W                       ;    

              BSF                     INTCON,GIE                    ;enable interrupt

              RETFIE

;

;******************************************************************

; Initialize

;******************************************************************

INIT

              BSF                     STATUS,RP0                   ;bank1

;set internal clock

              MOVLW              070H                                 ;internal clock 8 MHz

              MOVWF              OSCCON                    ;

              MOVLW              0FFH                                 ;set FF to TMR2

              MOVWF              PR2                                   ;

              BSF                     PIE1,TMR1IE                   ;enable TMR1 interrupt                 

              BSF                     PIE1,TMR2IE                ;enable TMR2 interrupt

;initialize PORTs

              MOVLW              023H                                 ;init ports

            MOVWF              TRISA                               ;

              CLRF                   TRISB                               ;

              MOVLW              03H                                   ;select ADC

            MOVWF              ANSEL                              ;      

              BCF                     STATUS,RP0                     ;bank0

;Start TMR2

              CLRF                   TMR2                                ;set zero to TMR2

              MOVLW              01BH                               ;start TMR2 counter ( prescaler 1/4

              MOVWF              T2CON                           ;,postscaler 1:16 (8.2ms))

              BSF                     T2CON,TMR2ON             ;start TMR2

;Start TMR1

              CLRF                   INTCH                              ;reset int. timer

              CLRF                   INTCL                               ;

              MOVLW              031H                                 ;start TMR1(262 ms interval)

              MOVWF              T1CON                              ;

;

              MOVLW              0C0H                                 ;enable all interrupts

              MOVWF              INTCON                            ;

;

              CALL                   MBAV                                ;measure voltage of battery

              MOVF                 DATA1H,W                       ;

              MOVWF              SDATA2                            ;

              MOVLW              .6                                       ;adjust data - 0.5 V

              SUBWF               DATA1H,W                       ;

              MOVWF              SDATA1                            ;

;

              CLRF                   PORTA                              ;clear all ports

            CLRF                   PORTB                              ;

              CLRF                   CFLAG                              ;clear control flags

 

;Test LEDs,Buzzer

              MOVLW              0FFH                                 ;display all bar

              MOVWF              DINP18                             ;

              MOVWF              DINP910                           ;

              CALL                   T1SEC                               ;wait for 1 sec.

              CLRF                   DINP18                             ;

              CLRF                   DINP910                           ;

              CALL                   RINGB                              ;ring buzzer

              CALL                   T1SEC                               ;wait for 1 sec.

;

;******************************************************************         

; Main Routine                               

;******************************************************************

;

MAIN

              BTFSC                CFLAG,SMODE               ;check mode

              GOTO                  MAIN20                            ;

;

              BTFSS                 PORTA,PUSHSW             ;check push-SW

              BSF                     CFLAG,DTSW                  ;

              CALL                   T05SEC                             ;wait for 0.5 sec

;

;******************************************

; Battery Monitor

;***********************

MAIN1

              CALL                   STAB                                 ;do stability check routine

              BTFSS                 CFLAG,TOVR                   ;check time-over of 5.5min. timer

              GOTO                  MAIN10                            ;

              BSF                     CFLAG,SMODE               ;set flash alarm mode       

              BCF                     CFLAG,TOVR                   ;reset time over flag         

;            

MAIN10

              BCF                     CFLAG,RBUZZ                 ;reset flags

              BCF                     CFLAG,ILLU                    ;

              CALL                   MBAV                                ;measure voltage of battery

              CLRF                   LCNT                                ;set Level counter

              INCF                   LCNT,F                             ;

              MOVLW              .145                                   ;check under 10.5 V

              SUBWF               DATA1H,W                       ;

              BTFSC                STATUS,C                         ;

              GOTO                  MAIN11                            ;

;

              BSF                     CFLAG,RBUZZ                 ;set ring buzzer flag

              GOTO                  MAINEP                           ;

;

MAIN11

              BCF                     CFLAG,DTSW                  ;reset push-SW flag         

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .151                                   ;check 11.0 V

              SUBWF               DATA1H,W                       ;

              BTFSC                STATUS,C                         ;

              GOTO                  MAIN12                            ;

;

              BSF                     CFLAG,ILLU                    ;set illuminate flag

              GOTO                  MAINEP                           ;

;            

MAIN12

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .157                                   ;check 11.5 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;            

MAIN13

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .164                                   ;check 12.0 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;            

MAIN14

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .170                                   ;check 12.5 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;

MAIN15

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .177                                   ;check 13.0 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;

MAIN16

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .183                                   ;check 13.5 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;

MAIN17

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .189                                   ;check 14.0 V

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAINEP                           ;

;

MAIN18

              INCF                   LCNT,F                             ;count up Level counter(+1)

              MOVLW              .195                                   ;check 14.5 V

              SUBWF               DATA1H,W                       ;

              BTFSC                STATUS,C                         ;

              GOTO                  MAIN19                            ;

;

;             BSF                     CFLAG,ILLU                    ;set illuminate flag           

              GOTO                  MAINEP                           ;

;            

MAIN19

              INCF                   LCNT,F                             ;count up Level counter(+1)

              BSF                     CFLAG,ILLU                    ;set illuminate flag

;            

;******************************************

; display bar-LED            

MAINEP

              CLRF                   DL18                                 ;clear work area

              CLRF                   DL910                               ;

MAINEP1

              BSF                     STATUS,C                         ;

              RLF                     DL18,F                              ;

              RLF                     DL910,F                            ;

              DECFSZ              LCNT,F                             ;check end

              GOTO                  MAINEP1                         ;

;

              MOVF                 DL18,W                             ;save level data(L)

              MOVWF              DINP18                             ;

              RRF                     DL910,F                            ;save level data(H)

              RRF                     DL910,F                            ;

              RRF                     DL910,F                            ;

              MOVLW              0C0H                                 ;

              ANDWF              DL910,W                           ;

              MOVWF              DINP910                           ;

;

              BTFSC                CFLAG,DTSW                  ;check push-SW flag

              GOTO                  MAINEP2                         ;            

              BTFSS                 CFLAG,RBUZZ                 ;check buzzer flag

              GOTO                  MAINEP2                         ;

              CALL                   RINGB                              ;ring buzzer

MAINEP2

              BTFSS                 CFLAG,ILLU                    ;check illuminate flag

              GOTO                  MAIN                                ;            

              BTFSS                 DINP910,BLED10            ;check over voltage( > 15V )

              GOTO                  MAIN                                ;

              BCF                     DINP910,BLED10            ;illuminate 10th bar LED

              CALL                   T05SEC                             ;wait for 0.5 sec

              BSF                     DINP910,BLED10            ;

              GOTO                  MAIN                                ;

;

;******************************************************************

;  SUB-ROTINE  POOL

;******************************************************************

;  Stability check routine

;*******************************************

;

STAB

              CALL                   MBAV                                ;measure Battery voltage

              MOVLW              .2                                       ;check change of voltage(-0.04V)

              SUBWF               SDATA2,W                        ;

              SUBWF               DATA1H,W                       ;

              BTFSS                 STATUS,C                         ;

              GOTO                  RSTTMR1                         ;

              MOVLW              .2                                       ;check change of voltage(+0.04V)

              ADDWF              SDATA2,W                        ;

              SUBWF               DATA1H,W                       ;

              BTFSC                STATUS,Z                         ;

              RETURN                                                       ;                          

              BTFSC                STATUS,C                         ;                                                      

              RETURN                                                       ;

;reset timer

RSTTMR1

              BCF                     CFLAG,TOVR                   ;reset int. timer

              CLRF                   INTCH                              ;

              CLRF                   INTCL                               ;

              MOVF                 DATA1H,W                       ;save current voltage

              MOVWF              SDATA2                                          ;

              RETURN                                                       ;                                                                    

;

;*******************************************

;  Measure voltage of Battery

;*******************************************

;Measure Voltage of Battery from AN0

;

MBAV

        CLRF                   DATA1H                     ;clear result area

        CLRF                   DATA1L                     ;

              MOVLW              040H                         ;select AN0,1/8

;                                                                                   ;left justified

              MOVWF              ADCON0                   ;initialize AD-CONVERTER

              BSF                     ADCON0,ADON               ;A/D ready on

        CALL                   TIM100U                     ;wait(100μS)

        CALL                   TIM100U                      ;wait(100μS)

        BSF                     ADCON0,GO_DONE      ;A/D start

ADCONV1

        BTFSC                ADCON0,GO_DONE      ;check convert complete

        GOTO                  ADCONV1                        ;

        MOVF                 ADRESH,W                 ;get upper  byte

        MOVWF              DATA1H                    ;

        BSF                     STATUS,RP0                ;bank1

        MOVF                 ADRESL,W                 ;get lower byte

        BCF                     STATUS,RP0                ;bank0

              MOVWF              DATA1L          ;

              BCF                     ADCON0,ADON               ;A/D ready off      

        RETURN

;*******************************************

;  Timer Routine ( 8 MHz clock only )

;*******************************************

; 100usec Timer Subroutine at 8 MHz

; 1CYCLE = 0.5 usec -> 200cycle

;

; 100usec Timer Subroutine

TIM100U                                        

              MOVLW              .39             ;39 times

              MOVWF              CNT1          ;2 cycles

LOOP1

              NOP

              NOP                                                ;(2+3)*39-1=194 cycles  

              DECFSZ              CNT1,F

              GOTO                 LOOP1

              RETURN                                         ;2+44+2=198 cycles

; 10msec Timer Subroutine

TIM10M

              MOVLW              .99             ;99 times

              MOVWF              CNT2

LOOP2

              CALL                   TIM100U       ;(2+248+3)*99-1=25,046

              DECFSZ              CNT2,F

              GOTO                  LOOP2

              RETURN                                         ;2+25046+2=25,050 cycle

                                                                      ;25050*0.4=10.02 msec

; 0.05sec Timer Subroutine

T005SEC

              MOVLW              .5              ;5 times

              MOVWF              CNT3             ;10msec * 5

LOOP21

              CALL                   TIM10M        ;(2+25050+3)*5-1=125,274

              DECFSZ              CNT3,F         ;

              GOTO                  LOOP21

              RETURN                                         ;2+125,274+2=125,278 cycles

                                                                      ;125,278*0.4=0.0501 msec

; 0.1sec Timer Subroutine

T01SEC

              MOVLW              .10             ;10 times

              MOVWF              CNT4             ;10msec * 10

LOOP3

              CALL                   TIM10M        ;(2+25050+3)*10-1=250,549

              DECFSZ              CNT4,F         ;

              GOTO                  LOOP3

RETURN                                         ;2+250,549+2=250,553 cycles                                                                                             ;250,553*0.4=0.10022sec

; 0.5 sec Timer Subroutine

T05SEC

              MOVLW              .5              ;5 times

              MOVWF              CNT5          ;100msec * 5

LOOP4

              CALL                   T01SEC        ;(2+250,553+3)*5-1=1,252,789

              DECFSZ              CNT5,F        ;

              GOTO               LOOP4

              RETURN                                         ;2+1,252,789+2=1,252,793 cycles

                                                                      ;1,252,793*0.4=0.5011sec

;

; 1 sec Timer Subroutine

T1SEC

              MOVLW              .10             ;10 times

              MOVWF              CNT6          ;100msec * 10

LOOP5

              CALL                   T01SEC        ;(2+250,553+3)*10-1=2,505,579

              DECFSZ              CNT6,F        ;

              GOTO                  LOOP5

RETURN                                         ;2+2,505,579+2=2,505,583 cycles                                                                                       ;2,505,583*0.4=1.0022sec

;

;***************************************

;

              END