Part 3: Advanced Instructions and Practical Applications for PIC16F18875 Assembly Programming
1. Advanced Instructions
The PIC16F18875 microcontroller includes several advanced instructions that enhance its functionality and allow for more complex operations. These instructions are essential for efficient and powerful assembly programming.
1.1 Rotate and Shift Instructions
Rotate and shift instructions are used for bit manipulation, which is crucial in applications such as cryptography, data compression, and error detection.
- RLF f,d: Rotate Left through Carry
RLF PORTA, F ; Rotate PORTA left through carry, store in PORTA
- RRF f,d: Rotate Right through Carry
RRF PORTB, W ; Rotate PORTB right through carry, store in W
- SWAPF f,d: Swap Nibbles in f
SWAPF TEMP, F ; Swap nibbles in TEMP, store in TEMP
1.2 Bit-Oriented Instructions
Bit-oriented instructions allow for precise control over individual bits in registers, which is essential for tasks like setting flags, toggling LEDs, or reading sensor states.
- BSF f,b: Bit Set f
BSF STATUS, Z ; Set Zero flag in STATUS
- BCF f,b: Bit Clear f
BCF STATUS, C ; Clear Carry flag in STATUS
- BTFSC f,b: Bit Test f, Skip if Clear
BTFSC PORTA, 1 ; Test bit 1 of PORTA, skip next if clear
- BTFSS f,b: Bit Test f, Skip if Set
BTFSS PORTB, 0 ; Test bit 0 of PORTB, skip next if set
1.3 Literal and Control Instructions
These instructions are used for immediate data manipulation and controlling the flow of the program.
- MOVLW k: Move Literal to W
MOVLW 0x55 ; Move 0x55 to W
- ADDLW k: Add Literal to W
ADDLW 0x0A ; Add 10 to W
- SUBLW k: Subtract W from Literal
SUBLW 0x20 ; Subtract W from 32, store in W
- RETFIE: Return from Interrupt
RETFIE ; Return from interrupt, enable global interrupts
2. Practical Applications
Understanding how to apply these instructions in real-world scenarios is crucial for effective programming. Here are some practical applications of the PIC16F18875 instruction set.
2.1 Implementing Delays
Delays are essential in many embedded applications, such as blinking LEDs or creating time intervals for sensor readings.
; Delay subroutine (approx. 1 millisecond delay)
DELAY_MS:
MOVLW D'250' ; Load W with 250
MOVWF COUNT1 ; Move W to COUNT1
MOVWF COUNT2 ; Move W to COUNT2
DELAY_LOOP:
DECFSZ COUNT1, F ; Decrement COUNT1, skip if zero
GOTO DELAY_LOOP ; Repeat loop
DECFSZ COUNT2, F ; Decrement COUNT2, skip if zero
GOTO DELAY_LOOP ; Repeat loop
RETURN ; Return from subroutine
2.2 Reading and Writing to I/O Ports
Controlling I/O ports is fundamental in embedded systems for tasks such as reading sensor data or controlling actuators.
; Initialize PORTA as output
BANKSEL TRISA
CLRF TRISA ; Clear TRISA register (set PORTA as output)
; Set RA0 highBSF LATA, 0 ; Set bit 0 of LATA (turn on LED connected to RA0)
; Read RA1 and store result in WBANKSEL PORTA
BTFSC PORTA, 1 ; Test bit 1 of PORTA
GOTO BIT_SET
GOTO BIT_CLEAR
BIT_SET:MOVLW 0x01 ; Load W with 1
GOTO CONTINUE
BIT_CLEAR:
MOVLW 0x00 ; Load W with 0
CONTINUE:
; Continue with rest of the program
2.3 Using Interrupts
Interrupts allow the microcontroller to respond to external events promptly. Proper handling of interrupts is crucial for real-time applications.
ORG 0x0004 ; Interrupt vector location
GOTO ISR ; Jump to ISR
ISR:; Handle interrupt
BCF INTCON, INTF ; Clear interrupt flag
; Perform interrupt-specific tasks
RETFIE ; Return from interrupt
2.4 Implementing Finite State Machines
Finite State Machines (FSMs) are used to model the behavior of systems with a finite number of states. They are widely used in control systems, user interfaces, and communication protocols.
; Define states
#define STATE_IDLE 0
#define STATE_PROCESS 1
#define STATE_ERROR 2
; Initialize stateMOVLW STATE_IDLE
MOVWF STATE
FSM_LOOP:MOVF STATE, W
CPFSEQ STATE_IDLE
GOTO PROCESS_STATE
CPFSEQ STATE_PROCESS
GOTO ERROR_STATE
GOTO FSM_LOOP
PROCESS_STATE:; Processing code
GOTO FSM_LOOP
ERROR_STATE:
; Error handling code
GOTO FSM_LOOP
3. Best Practices for Assembly Programming
3.1 Code Organization and Commenting
Organize code into modules and use meaningful labels and comments to enhance readability and maintainability.
; Subroutine to initialize PORTA
Init_PORTA:
BANKSEL TRISA
CLRF TRISA ; Set PORTA as output
RETURN
; Main programMAIN:CALL Init_PORTA ; Initialize PORTA
; Other code
GOTO MAIN
3.2 Efficient Use of Registers and Memory
Minimize bank switching and optimize register usage to reduce memory access time.
BANKSEL TRISA ; Select bank containing TRISA
CLRF TRISA ; Clear TRISA register
BANKSEL PORTA ; Select bank containing PORTAMOVLW 0xFF
MOVWF PORTA ; Set all PORTA pins high
3.3 Interrupt Handling
Keep Interrupt Service Routines (ISRs) short and efficient to minimize latency.
ORG 0x0004 ; Interrupt vector location
GOTO ISR ; Jump to ISR
ISR:; Handle interrupt
BCF INTCON, INTF ; Clear interrupt flag
; Perform interrupt-specific tasks
RETFIE ; Return from interrupt
Refrences:
[1] https://ww1.microchip.com/downloads/en/DeviceDoc/31029a.pdf
[2] https://forum.microchip.com/s/topic/a5C3l000000MbYLEA0/t374413
[3] https://ww1.microchip.com/downloads/en/DeviceDoc/PIC16%28L%29F18855_75%20Data%20Sheet_DS40001802E.pdf
[4] https://www.microchip.com/en-us/product/pic16f18875
[5] https://www.instructables.com/Programming-PIC-Microcontrollers/
[6] https://www.youtube.com/watch?v=fCqq9OQmztY
[7] https://www.youtube.com/watch?v=8kA9t4Wv2Tk
[8] https://www.youtube.com/watch?v=7bZg_GzUbHI
[9] https://ww1.microchip.com/downloads/en/DeviceDoc/50002027E.pdf