[Menu]>[Circuits Gallery]>[Radio Controlled Clock]


Processing explanation of Radio Controlled Clock

Consideration of a program address

In PIC16F series, the maximum address range which an instruction can operate directly is from 0 to 2047. PIC16F873 has 4K words program memory. Therefore, in order to access the program memory after 2048, it is necessary to set up the contents of the PCLATH register each time.

In PIC16F series, a program memory is managed by 2K words unit. This unit is called a page. The page of a program memory is specified by the 3rd and 4th bit of a PCLATH register.

In order to jump by GOTO or CALL exceeding each page, LGOTO or LCALL is used.
These are called Directive. These are not the instruction of PIC16F. It is automatically changed as follows when assembling a source code with these directions.
This is the example which jumps from page 0 to INIT (the address in the page : h'3FE") of page 1.

Source code
    LGOTO    INIT
Assembling result
158A   BSF    PCLATH,3
120A   BCF    PCLATH,4
2BFE   GOTO   h'3FE'
You can see that it set "1" to the 3rd bit of PCLATH and the page is changed to page 1.
It is automatically processed in LGOTO as mentioned above if jumping only like GOTO.

In case of LCALL, it is necessary to consider
In this case, it is necessary to set PCLATH after returning from the subroutine.
When jumping by LCALL, PCLATH is rewritten automatically like LGOTO.
This is the example which calls the subroutine (the address in a page: h'ED") in page 0 from page 1.

Source code
   LCALL   GET_TBL_DATA
Assembling result
118A   BCF    PCLATH,3
120A   BCF    PCLATH,4
20ED   CALL   h'ED"
3rd bit and 4th bit of PCLATH are cleared and it is changed to page 0.

RETURN is executed at the end of the subroutine to return to the original processing.
RETURN refers to the return address which was written at the stack memory and jumps to the original address. However, PCLATH is NOT rewritten.
Therefore, it is necessary to set up PCLATH at the point which returned. Otherwise, the program of a different page is performed. There is no directive called LRETURN.
In this program, PCLATH is set up with SETPCH macro.
setpch  macro
        if      ($ >= 0) && ($ < 0x800)
        bcf     PCLATH,3
        else
        bsf     PCLATH,3
        endif
        endm
"$" shows its address. Only the 3rd bit of PCLATH is set because it is using only page 0 and page 1 in case of PIC16F873.

SETPCH macro is always put after calling a subroutine in LCALL.
An assembly list about LCALL with the 2290th line is shown below.



M-ADR is the machine address of a hexadecimal display, M-CODE is a machine language code and S-ADR is a source code address.
In this case, because the program position is after h'800', it is the position of page 1. Therefore, with SETPCH macro, only the code which sets the 3rd bit of PCLATH as 1 is developed.



Allocation of the program

Fundamentally, a subroutine is allocated to a page 0 and the main routine and the interruption processing routine are allocated to the page 1.



Initial routine
03433 ;####################################################################
03434 ;
03435 ;                          Initial routine
03436 ;
03437 ;####################################################################
If a power supply is switched on and a program starts from the address 0, it will jump to this processing. The hardware and software environment of PIC is set up by an initialization routine.
The contents of a setting of SFR are made a list below.

RegisterInitial valueDescription
PORTA
PORTB
PORTC
00000000The contents of each port register are cleared.
RCSTA10010000A serial port is used. Continuing reception is set.
ADCON000000000A/D conversion function isn't used.
ADCON100000110All ports are used as the digital port.
TRISA00010000RA4 is set as input mode. Others are set as output mode.
TRISB00001100RB2, RB3 are set as input mode. Others are set as output mode.
TRISC11000000RC6, RC7 are set as input mode. Others are set as output mode.
OPTION_REG00000000 Inner pull up isn't used. Internal clock is used.
Prescaler is used for the TMR0 timer. Prescaler value is 1:2.
SPBRG010100109,600 bps is specified. ( Value is 82 )
TXSTA00100110 8 bits communication. Transmit enable. Asynchronous mode. High speed.
"1" is set to the TRMT bit. But it's unnecessary because it's read only.
T2CON00000110Postscaler of timer 2 is 1:1. Timer 2 is used. Prescaler is 1:16.
TMR200000000The value of timer 2 is cleared.
PR200010011 Timer 2 period is set. Set value is count value (20) - 1.
(1/12.8MHz)*(4cycle/clock)*(20count(PR2))*(16(Prescaler))
0,078125uS*4*20*16=100uS
PIE100100010USART receive interrupt is used. TMR2 to PR2 match interrupt is used.
INTCON11000000Enables all un-masked interrupts. Enables all un-masked peripheral interrupts

The following initialization processings are performed in addition to the above.
    Initialization of various work areas
    Initialization of time area
    Time display mode reading from EEPROM
    Initialization of a liquid crystal display


Main routine
03536 ;####################################################################
03537 ;
03538 ;                           Main routine
03539 ;
03540 ;####################################################################
In the main routine, the following processing is done.

Initial message display Software flow chart (1/11)
Initial message is displayed for 2 seconds immediately after the turning on.
Update of the time display Software flow chart (1/11)

A time stamp is updated every second by "clock_main" subroutine. The calling of a subroutine is cyclically done irrespective of 1 second. Update timing in 1 second is judged in the subroutine. The reason for making a subroutine is to update a time stamp while time setting is done. In case of keying-in wait, "clock_main" is always called and a time stamp update is done.
Processing of a time setting key Software flow chart (2/11), Software flow chart (3/11)

This processing is processing with most steps in a main routine.
At first, whether or not a menu key was pushed is checked. The key which should be pushed first is a menu key and the other key push is invalid.
In the waiting time of the key operation, it is set to 10 seconds. If 10 seconds pass since the last key operation, the key operation till then will become invalid.
03672         CALL    DISP_MAIN               ;Time display
Above-mentioned processing is the subroutine calling which is written in the lower right of Software flow chart (1/11). You can think that there is no necessity since "disp_main" subroutine is used also in "clock_main" subroutine. However, "clock_main" subroutine updates a display only every second. Therefore, when escaping from key processing, it is necessary to call "disp_main" subroutine, and it is necessary to display time immediately. At the time of key operation, the message of key operation is displayed on the display, and time is not displayed.
"Time stamp mode changing" or "Setting of a timer" is performed by the key to operate after the first menu key.
"clock_main" subroutine Software flow chart (4/11)

The display timing of a display and the timing of decoding are judged in this subroutine. A display is updated by "disp_main" subroutine every 0 second. Moreover, "dec_time" subroutine is executed for every 400 miliseconds. In this subroutine, processing which analyzes the information put on the electric wave and is changed into time information is performed.
"disp_main" subroutine Software flow chart (5/11)

In this subroutine, processing which displays time or a message on LCD is performed.



Interruption processing
03973 ;####################################################################
03974 ;
03975 ;                      Interruption processing
03976 ;
03977 ;####################################################################
With this equipment, two kinds of interruption, "periodic interruption by a timer 2" and "reception interruption of a serial circuit", is used. In interruption of those other than the two above-mentioned kind, the same processing as timer 2 interruption is executed by interruption judgment processing. When assuming extraordinary operation, to have made jump to "End of interruption" is safer.
03979         BTFSC   PIR1,TMR2IF     ;timer2(100uS) int ?
03980         GOTO    TIMER_INT       ;Yes.
03981         BTFSC   PIR1,RCIF       ;RX int ?
03982         GOTO    SIO_INT         ;Yes.
              GOTO    INT_VEC1        ;No. Jump to return
Periodic interruption in every 100 microseconds by a timer 2
    By interruption processing for 100 microseconds, the following processings are executed.

    * Subtraction of a 100uS counter ( Every 100uS ) Software flow chart (6/11)
      In this software, LCD etc. are controlled per 100uS. ( delay 100u subroutine )
      In order to make this time, the counter value is subtracted by interruption processing of 100uS.

    * Subtraction of a 10mS counter ( Every 10mS ) Software flow chart (6/11)
      Time is measured to 10mS based on 100uS interruption, and the counter of 10mS is subtracted.

    * LED lighting time control ( Every 10mS ) Software flow chart (6/11)
      The signal of true second, true minute, true hour, true day and true month are outputted only 100mS.

    * Information analysis of TCO(Time Code Output) ( Every 10mS ) Software flow chart (7/11), Software flow chart (8/11)
      There are three kinds of signals of TCO. They are operating by the following standards and judging standards.

        KindStandardCriterion in processing
        Marker200mS ± 5mS80mS to 280mS
        "1" signal500mS ± 5mS400mS to 600mS
        "0" signal800mS ± 5mS700mS to 880mS

      As for a TCO signal, the kind of signal is judged by the time from falling edge to rising edge of the signal.
      The detected TCO code is stored in "tco_code" and it is analyzed in the second, the minute, the hour, the week, the day, the month and the year by the time decoding processing. The information on the month and the day are not included in TCO. The leap year and the normalized day information (sum total day from January 1st) are included. The processing which changes into the information the month and the day based on them is executed with this equipment.

    * Key push detection ( Every 10mS ) Software flow chart (9/11), Software flow chart (10/11)
      The control ports of the keys(F2, F3, F4 and timer-OFF) and the LCD are sharing. Therefore, when detecting a key condition, RB4, RB5, RB6 and RB7 should be changed to the input mode from the output mode. It is again returned to the output mode when the key condition detection ends.
      When a key push was detected, the number of the key which was pushed is checked. The number of the key is stored in "key_dat".
      When a key is continuously pushed, it does the same operation when operating more than one time like a keyboard operation of the PC. This is for operation to be simplified. This operation is managed using "key_sts". When setting "key_sts" to "1", it becomes a key processing request. Because it is, when detecting continuous key operation, the effect which is the same when operating more than one time is gotten by setting "key_sts" by the specific time. On the flow chart, some of the parts of the set/clear of "key_sts" is shown. It is not all. For details, please refer to the source code.
      The update speed by the continuing push time changes as follows.

        Continuing push timeUpdate speed
        to 500mSno updat automatically
        500mS to 2400mSevery 300mS
        over 2400mSevery 100mS

      The operation of the timer time setting can be done quickly by this function.
      However, this function works by all key operation in addition to the time setting. So, when pushing Menu key continuously from the condition of the time display, it repeats the following operation.
      Time display screen -> Timer selection screen -> 12H/24H mode selection screen -> Time display screen ... (Repeat)
      This prevention processing isn't done.

Character reception interruption with the serial communication circuit Software flow chart (11/11)
      Every time the data of 1 character is received with the serial circuit, the interruption occurs.
      Reception processing itself is executed with the hardware of PIC. Even if the reception interruption occurs, it isn't always normally received. Therefore, in the beginning of the reception interruption processing, the confirmation whether or not which was normally received is done. In the malfunction in the reception operation, there are following two kinds.

        Framing error : When the stop bit can not be detected in the signal from the serial circuit
        Overrun error : When the following data is sent from the serial circuit while not reading contents in the reception buffer

      When above-mentioned error occurs, a received data is canceled and the initialization of the reception circuit is done.
      The framing error occurs with the noise. Also, it occurs to the thing except the above when the speed specification of the sender and receiving end aren't right. The overrun error occurs when the reception processing of software isn't working normally. It's when the data which was received with the hardware isn't read by the software. It doesn't occur if the software doesn't have a bug.
      When the result of above-mentioned error checking is normally, received data is stored in the memory address which "rx_ptr" shows. The reception of the command ends when receiving CR(Carriage Return : It returns a print head to the origin) information as the received data. LF(Line Feed) is the signal which proceeds with the paper for 1 line. These signals are a data format from the time when the printer of the typewriter formula was used.


Subroutine

The list of the subroutines currently used by this software is shown below.
NameFunction
lcd_initInitialization of the LCD module
lcd_e_pulseOutput 0.625uS pulse to E ternminal of LCD
printOne letter display
messoutMessage display
clsClear display
locateChange cursor location
csr_onCursor indication
csr_offCursor non-indication
lcd_iwrWrite data to LCD instruction register
lcd_dwrWrite data to LCD data register
disp_secondSecond display
disp_minuteMinite display
disp_hourHour display
disp_dayDay display
disp_monthMonth display
disp_yearYear display
disp_wdayWeek display
disp_ndayNormalized day display
disp_timeTime display
disp_dateDate display
disp_okNormal reception display
disp_ngNo reception display
disp_timer1st line of timer set display
disp_tm_setTime set value display
sio_jobSerial communication processing
cmd_checkCommand check
sout_timeSend out Time
sout_dateSend out Date
sout_stimeSet time output suspension for synchronizing with second
sout_statusSend out time adjusted status
cmd_set_timerTime setting command
sout_timerSend out set time
sout_decodeSend out decode status
cmd_timer_onTimer ON command
cmd_timer_offTimer OFF command
sout_errSend out error message
soutSend out one character to serial port
ssoutSend out characters to serial port
sout_secondSend out second
sout_minuteSend out minute
sout_hourSend out hour
sout_daySend out day
sout_monthSend out month
sout_yearSend out year
sout_wdaySend out week
cv_str2numChange two characters to binary
sout_num2dSend out two characters

NameFunction
get_tbl_dataRead data from data table
inc_timeIncrement 1 second
inc_dateIncrement 1 day
inc_dec_timeIncrement backup 1 munite
cvt_nd2dayConvert normalized day to month and day data
addwAddition [ BCCH,BCCL = BCCH,BCCL + ACCH,ACCL ]
mulibMultiplication [ BCCH,BCCL = BCCH,BCCL + (ACCL * W) ]
divbDivision [ ACCH = ACCL / W ]
us_subwSubtraction [ ACCH,ACCL = ACCH,ACCL - BCCH,BCCL ( No borrows ) ]
init_timeInitialization of date and time
init_dec_timeInitialization of decoded date and time
init_bk_dec_timeInitialization of decoded backup date and time
init_tm_chk_cntInitialization of decode check counter
chk_tm_chk_cntCheck decode check counter
adjust_0sAdjustment in 0 seconds
copy_timeCopy the decoded time to display time
dec_timeTime decoding
search_mark0 seconds marker detection
dec_time_mMinute decoding
dec_time_hHour decoding
dec_time_ndNormalized day(ND) decoding
dec_time_yYear decoding
dec_time_wdWeek decoding
delay100u100 microseconds delay
delay10m10 miliseconds delay
chk_eep_datCheck EEPROM data
eeprom_initInitialize EEPROM
rd_eepromRead EEPROM data
wr_eepromWrite EEPROM data
chk_timerCheck time of Timer
timer_offTimer OFF
comp_timerCompare Timer time and Present time
set_tmbf_dataSet timer data to EEPROM
get_tmbf_dataRead timer data from EEPROM
get_tm_dataRead designated timer data from EEPROM
set_tm_dataWrite designated timer data to EEPROM
set_tm_limSet upper limit of timer