PIC series microcontroller programming basics III
[Copy link]
The table lookup program of PIC microcontroller can be realized by using the feature of subroutine with value return. Specifically, in the main program, first get the table data address and put it into W, then call the subroutine. The first instruction of the subroutine puts W into PC, then the program jumps to the data address, and then the "RETLW" instruction puts the data into W and returns to the main program. The following program uses F10 to put the table header address. MOVLW TABLE ;Table header address→F10 MOVWF 10 ┋ MOVLW 1 ;1→W, prepare to get the line segment value of "1" ADDWF 10,1 ;F10+W = "1" data address CALL CONVERT MOVWF 6 ;Set the line segment value to port B, light up the LED ┋ CONVERT MOVWF 2 ;W→PC TABLE RETLW 0C0H ;"0" line segment value RETLW 0F9H ;"1" line segment value ┋ RETLW 90H ;"9" line segment value 9) "READ...DATA, RESTORE" format program "READ...DATA" program reads one data in the data table each time, then adds 1 to the data pointer, and prepares to get the next data. In the following program, F10 is used as the starting address of the data table, and F11 is used as the data pointer. POINTER EQU 11 ;Define F11 as POINTER ┋ MOVLW DATA MOVWF 10 ;Data table header address→F10 CLRF POINTER ;Data pointer cleared ┋ MOVF POINTER,0 ADDWF 10,0 ;W =F10+POINTER ┋ INCF POINTER,1 ;Pointer plus 1 CALL CONVERT ;Call subroutine, get table data ┋ CONVERT MOVWF 2 ;Data address→PC DATA RETLW 20H ;Data ┋ RETLW 15H ;Data If you want to execute "RESTORE", just execute one "CLRF POINTER". 10) PIC microcontroller delay program If the delay time is short, you can let the program simply execute several no-operation instructions "NOP" in succession. If the delay time is long, you can use a loop to implement it. The following example uses F10 to calculate and repeat the loop 100 times. MOVLW D'100' MOVWF 10 LOOP DECFSZ 10, 1; F10—1→F10, if the result is zero, jump to GOTO LOOP ┋ The delay time is the sum of the execution time of the instructions in the delay program. If a 4MHz oscillation is used, each instruction cycle is 1μS. Therefore, the single-cycle instruction time is 1μS, and the double-cycle instruction time is 2μS. In the above example, the LOOP loop delay time is: (1+2)*100+2=302 (μS). Inserting a no-operation instruction in the loop can extend the delay time: MOVLW D'100' MOVWF 10 LOOP NOP NOP NOP DECFSZ 10, 1 GOTO LOOP ┋ Delay time = (1+1+1+1+2)*100+2=602 (μS). Using several loop nesting methods can greatly extend the delay time. The following example uses 2 loops to delay: MOVLW D'100' MOVWF 10 LOOP MOVLW D'16' MOVWF 11 LOOP1 DECFSZ 11,1 GOTO LOOP1 DECFSZ 10,1 GOTO LOOP ┋Delay time = 1+1+[1+1+(1+2)*16-1+1+2]*100-1=5201(μS) 11) Use of PIC microcontroller RTCC counter RTCC is a pulse counter. Its counting pulse has two sources, one is the external signal input from the RTCC pin, and the other is the internal instruction clock signal. The program can be used to select one of the signal sources as input. RTCC can be used by the program for timing; the program reads the RTCC register value to calculate the time. When RTCC is used as an internal timer, the RTCC pin must be connected to VDD or VSS to reduce interference and current consumption. The following program uses RTCC for delay: RTCC EQU 1 ┋ CLRF RTCC; RTCC clears to 0 MOVLW 07H OPTION; selects preset multiple 1: 256 → RTCC LOOP MOVLW 255; RTCC count final value SUBWF RTCC, 0
BTFSS STATUS, Z; RTCC=255? GOTO LOOP ┋In this delay program, the RTCC register increases by 1 every 256 instruction cycles (division ratio = 1:256). Assuming the chip uses a 4MHz oscillation, then: Delay time = 256*256 = 65536 (μS) RTCC is self-oscillating. When it counts, the program can do other things. Just read it after a period of time and detect its count value. 12) Addressing of register bank (BANK) For PIC16C54/55/56, there are 32 registers and only one bank (BANK), so there is no bank addressing problem. For PIC16C57/58, there are 80 registers, divided into 4 banks (BANK0-BANK3). In the description of F4 (FSR), it can be seen that bit6 and bit5 of F4 are register bank addressing bits, and their corresponding relationship is as follows: Bit6 Bit5 | BANK | Physical Address | 0 0 | BANK0 | 10H~1FH | 0 1 | BANK1 | 30H~3FH | 1 0 | BANK2 | 50H~5FH | 1 1 | BANK3 | 70H~7FH | When the chip is powered on and reset, bit6 and bit5 of F4 are random, and non-powered reset keeps the original state unchanged. The following example writes data to the 30H and 50H registers of BANK1 and BANK2. Example 1. (Assume that the current bank is selected as BANK0) BSF 4, 5; set bit5 = 1, select BANK1 MOVLW DATA MOVWF 10H; DATA→30H BCF 4, 5 BSF 4, 6; bit6 = 1, bit5 = 0 select BANK2 MOVWF 10H; DATA→50H From the above example, we can see that to read and write registers in a bank (BANK), we must first operate the bank addressing bit in F4. In actual applications, generally after power-on reset, bit6 and bit5 of F4 are cleared to 0 first, so that it points to BANK0, and then it is pointed to the corresponding bank as needed. Note that in the example, when writing data to the 30H register (BANK1) and the 50H register (BANK2), the register address in the instruction "MOVWF 10H" is "10H", not "MOVWF 30H" and "MOVWF 50H" as expected by the reader. Why? Let's review the instruction table. In all the instruction codes related to registers of the PIC16C5X microcontroller, the register addressing bits only occupy 5 bits: fffff, and can only address 32 (00H-1FH) registers. Therefore, to address 80 registers, the two-bit body addressing bits PA1 and PA0 are used. When we set the body addressing bits PA1 and PA0 to point to a BANK, the instruction "MOVWF 10H" will put the content of W into the corresponding register in this BANK (10H, 30H, 50H, or 70H). Some designers are in contact with the concept of bank address selection for the first time, and inevitably have different understandings. The following is an example: Example 2: (assuming that the current bank address selection is BANK0) MOVLW 55H MOVWF 30H; to change the register from 55H to 30H MOVLW 66H MOVWF 50H; to change the register from 66H to 50H It is wrong to think that "MOVWF 30H" can definitely put W into 30H, and "MOVWF 50H" can definitely put W into 50H. Because the actual effect of these two instructions is "MOVWF 10H", the reason has been explained above. So the final result of this program in Example 2 is F10H=66H, and the real F30H and F50H are not operated. Suggestion: In order to make the bank address selection program clear and concise, it is recommended to use more name definition symbols to write the program, so that it is not easy to confuse. Example 3: Assume that the several registers of BANK0, BANK1, and BANK2 are used in the program as follows:
BANK0 | address | BANK1 | address | BANK2 | address | BANK3 | address | A | 10H | B | 30H | C | 50H | · | 70H | · | · | · | · | · | · | · | · | · | · | · | · | · | · | · | · | |
|