Examples for subsystems
Introduction
Every microcontroller comprises a number of subsystems allowing for flexibility and wide range of applications. These include internal EEPROM memory, AD converters, serial or other form of communication, timers, interrupts, etc. Two most commonly utilized elements are interrupts and timers. One of these or several in combination can create a basis for useful and practical programs.
Writing to and reading from EEPROM
Program "eeprom.asm" uses EEPROM memory for storing certain microcontroller parameters. Transfer of data between RAM and EEPROM has two steps - calling macros eewrite and eeread. Macro eewrite writes certain variable to a given address, while eeread reads the given address of EEPROM and stores the value to a variable.
Macro eewrite writes the address to EEADR register and the variable to EEDATA register. It then calls the subprogram which executes the standard procedure for initialization of writing data (setting WREN bit in EECON1 register and writing control bytes 0x55 and 0xAA to EECON2).
EEWRITE MACRO ADDR,PROM
MOVLW ADDR ;Pass che parameters to subprogram E2write
MOVWF EEADR
MOVF PROM,W
MOVWF EEDATA
CALL E2WRITE ;Call E2write which initializes writing data
PAUSEMS .10 ;10ms delay
ENDM
E2WRITE
BCF IHTC0N,GIE ;disable all interrupts
BSF STATUS,RPO ;select bank 1
BSF EEC0N1,WREN ;set UREN bit in EEC0N1
MOVLW 0X55 ;write 0x55 to EEC0N2
MOVWF EEC0N2
MOVLW 0XAA ;write Oxaa to EEC0N2, as
MOVWF EEC0N2 ;writing confirmation
BSF EEC0N1,WR ;set bit WR to initialize writing
BCF STATUS,RPO
RETURN
EEREAD MACRO ADDR,PROM ;Pass the parameters to subprogram E2read
MOVLW ADDR
MOVWF EEADR
CALL E2READ ;Call E2write which initializes reading data
MOVWF PROM
ENDM
E2READ
BSF STATUS,RPO
BSF EEC0N1,RD
BCF STATUS,RPO
MOVF EEDATA,W
RETURN
For data to be actually stored in EEPROM, 10ms delay is necessary. This is achieved by using macro pausems. In case that this pause is unacceptable for any reason, problem can be solved by using an interrupt for signaling that data is written to EEPROM.
eewrite | macro addr, var |
addr | Destination address. With PIC16F84, there are 68 bytes |
of EEPROM for a total address range of 0x00 - 0x44. | |
var | Name of the variable to be stored to EPROM |
eeread | macro addr, var |
addr | Destination address. With PIC16F84, there are 68 bytes |
of EEPROM for a total address range of 0x00 - 0x44. | |
var | Name of the variable into which data read from EPROM will be stored. |
Example: Variable volume, which is set via buttons RA0 and RA1, will be stored to the address 0 of EEPROM. After reboot, when the program is started, it first loads the last known value of variable volume from EEPROM.
PROCESSOR 16F84
#INCLUDE "P16F84.INC"
__COHFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
CBLOCK 0X0C ; RAM starting address
HICNT
LOCNT
LOOPCNT
VOLUME
ENDC
ORG 0X00
GOTO MAIN
ORG 0X04
GOTO MAIN
INCLUDE "ROMUX_LIB.INC"
INCLUDE "BUTTON.INC "
INCLUDE "EEPROM.INC"
MAIN ;main program
BANKSEL TRISB
CLRF TRISB
BANKSEL P0RTB
EEREAD 0X00,VOLUME ;Read the previous value of volume movwf P0RTB
LOOP
BUTTON PORTA,0,0,INCREASE
BUTTON PORTA,1,0,DECREASE
GOTO LOOP
INCREASE
INCF VOLUME,F ;Increase volume by 1
MOVF VOLUME,W ;display on port B
MOVWF P0RTB
EEWRITE 0X00,VOLUME ;write to eeprom, address 0x00
GOTO LOOP
DECREASE
DECF VOLUME,F ;Decrease volume by 1
MOVF VOLUME, W ;display on port B
MOVWF P0RTB
EEWRITE 0X00,VOLUME ;Write to eeprom, address 0x00
GOTO LOOP
ORG 0X2100 ; Star ting value of EEPROM address zero
DE .5 ;after the microcontroller is programmed is 0x05
END
Processing interrupt caused by changes on pins RB4-RB7
Program "intportb.asm" illustrates how interrupt can be employed for indicating changes on pins RB4-RB7. Upon pushing any of the buttons, program enters the interrupt routine and determines which pin caused an interrupt. This program could be utilized in systems with battery power supply, where power consumption plays an important role. It is useful to set microcontroller to low consumption mode with a sleep instruction. Microcontroller is practically on stand-by, saving energy until the occurrence of interrupt.
Example of processing interrupt caused by changes on pins RB4-RB7
PROCESSOR 16f84
#include "P16F84.inc"
__CONFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
ORG 0X00
GOTO MAIN
ORG 0X04
GOTO ISR
MAIN
BANKSEL TRISB
MOVLW 0XF0 ;Higher four LED diodes are on
MOVWF TRISB
BANKSEL P0RTB
MOVLW OXFF
MOVWF P0RTB
BSF INTC0N,RBIE ;interrupt upon pin change enabled
BSF INTC0N,GIE ;all interrupts are enabled
LOOP ;Main loop
GOTO LOOP
ISP
BCF INTC0N,RBIF ;Clears the flag that indicates RB interrupt
;took place thus enabling detection of
;new interrupts in main program
BTFSS P0RTB,7 ;determining which button caused the interrupt
GOTO LEDO
BTFSS P0RTB,6
GOTO LEDL
BTFSS P0RTB,5
GOTO LED2
BTFSS P0RTB,4
GOTO LED3
RETFIE
LEDO
BCF P0RTB,0 ;Switch off diode LD0
RETFIE
LEDL
BCF P0RTB,1 ;Switch off diode LD1
RETFIE
LED2
BCF P0RTB,2 ;Switch off diode LD2
RETFIE
LED3
BCF P0RTB,3 ;Switch off diode LD3
RETFIE
END
Processing interrupt caused by change on pin RB0
Example "intrb0.asm" demonstrates use of interrupt RB0/INT. Upon falling edge of the impulse coming to RB0/INT pin, program jumps to subprogram for processing interrupt. This routine then performs a certain operation, in our case it blinks the LED diode on PORTB, 7.
Example of processing interrupt caused by changes on pin RB0
PROCESSOR 16f84
#include "P16F84.inc"
__CONFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
ORG 0X00
GOTO MAIN
ORG 0X04
GOTO ISR
MAIN
BANKSEL TRISB
MOVLW B'00000001' ;RB0 is input, the rest are output
MOVWF TRISB
BANKSEL OPTI0N_REG
BCF OPTI0N_REG,INTEDG ;interrupt occurs at faling edge
BSF OPTI0N_REG,N0T_RBPU ;intemal pull-up resistors are off
BANKSEL P0RTB
CLRF PORTB
BSF P0RTB,7 ;0nly LED diode P0RTB,7 is on
BSF INTC0N,INTE ;interrupt RB0 enabled
BSF INTC0N,GIE ;all interrupts enabled
LOOP
GOTO LOOP ;Main loop
ISR
BCF INTC0N,INTF ;Clears the flag that indicates RB interrupt
;took place thus enabling detection of
;new interrupts in main program
BTFSS PORTO,7 ;Is LED7 on?
GOTO LABI
BCF PORTO, 7 ;If true switch off LED7
RETFIE
LABI
BSF P0RTB,7 ;If false switch on LED7
RETFIE
END
Processing interrupt caused by overflow on timer TMR0
Program "inttmr0.asm" illustrates how interrupt TMR0 can be employed for generating specific periods of time. Diodes on port B are switched on and off alternately every second. Interrupt is generated every 5.088ms; in interrupt routine variable cnt is incremented to the cap of 196, thus generating approx. 1 second pause (5.088ms*196 is actually 0.99248s). Pay attention to initialization of OPTION register which enables this mode of work for timer TMR0.
Example of processing interrupt caused by overflow on timer TMR0
PROCESSOR 16f84
#include "P16F84.inc"
__CONFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
CNT EQU 0X0C
ORG 0X00 ;Reset vector
GOTO MAIN
ORG 0X04 ;Interrupt vector
GOTO ISR
MAIN
BANKSEL TRISB
CLRF TRISB ;Port B is output
MOVLW 0xFF
MOVWF TRISA ;Port A is input
MOVLW B'10000100' ;Set prescaler to TMRO BANKSEL 0PTI0N_REG
MOVWF OPTI0N_REG ;ps = 32 => TMRO is incremented every 32us BANKSEL P0RTB
CLRF P0RTB ;A11 the diodes are off by default
BSF INTC0N,T0IE ;Enable TMRO interrupt
MOVLW .96;initialize TMRO
;Overflow occurs
;every (255-96)*32us=5.088ms
MOVWF TMRO ;Start the counter
BSF INTC0N,GIE ;Interrupts are globally enabled
CLRF CNT
LOOP
GOTO LOOP ;Remain at this line
ISR
MOVLW .96 ;Initialize TMRO to ensure next interrupt
; in 5ms
MOVWF TMRO
BCF INTCON ;clear int. flag
INCF CNT,F
MOVLW .196 ;Has one second elapsed?(ls~196*5.088 ms
SUBWF CNT,W
BTFSS STATUS,Z
RETFIE
COMF P0RTB,F ;If true, complement the values of port B
CLRF CNT ;and set the initial value of variable cnt
RETFIE ;If false, exit the interrupt routine
END ;END of program
Processing interrupt caused by overflow on TMR0 connected to external input (TOCKI)
Counter TMR0 increments upon signal change on pin RA4/TOCKI. Prescaler is set to 4, meaning that TMR0 will be incremented on every fourth impulse. Pay attention to initialization of OPTION register which enables this mode of work for timer TMR0 (this mode is common for devices such as counters).
Example of processing interrupt caused by overflow on timer TMR0 connected to TOCKI
PROCESSOR 16f84
#include "P16F84.inc"
__CONFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
NUM_REV EQU .100 ; (1-256)
ORG 0X00
GOTO MAIN ; Reset vector
ORG 0X04
GOTO ISR ; Interrupt vector
Main BANKSEL TRISB
CLRF TRISB ; Port B is input
MOVLW TRISA ; Port A is output
MOVLW B'10100001' ; External impulses on T0CKI increment
; TMRO
MOVWF OPTI0N_REG ; ps = 4 TMRO increments every 4 impulses
BANKSEL P0RTB ; i.e. 1 revolution = 4 impulses
CLRF PORTB ; All diodes are off by default
BSF INTC0N,T0IE ; Enable TMRO interrupt
MOVLW .256 ; Initialize TMRO so that overflow
SUBLW NUM_REV ; occurs every 100 revolutions,
; i.e. TMRO is set to 156 ; 256-156=100)
MOVWF TMRO ; Start the counter
BSF INTC0N,GIE ; Interrupts are globally enabled
LOOP
MOVF TMRO,W ; Display number of remaining revolutions
; on port B
SUBLW .256
MOVWF P0RTB ; number of remaining revolutions=256-TMRO
GOTO LOOP ; Remain at this line
ISR
MOVLW .256 ; Initialize TMRO so it can count next
; 100 revolutions
SUBLW NUM_REV
MOVWF TMRO
BCF INTC0N,T0IF ; clear int. fleg
RETFIE ; return to main program
END ; END of program
User Comments
No Posts found !Login to Post a Comment.