Question
Task: Using two seven-segment displays connected on the CADET board, display a counter that starts from 00 until 99. Once it hits 99, it resets
Task:
Using two seven-segment displays connected on the CADET board, display a counter that starts from 00 until 99. Once it hits 99, it resets and goes back to zero. While it is counting, also display the number in the upper right LCD screen on the microcontroller, while the lower LCD shows the binary of the number.
Note:
1) We are using the PIC18F452 Microcontroller
2) There are two seven-segment displays, one on the left and one on the right. The left shows the first digit and the right shows the second digit (ex: 01, 02, 03...99). The left one is connected to PORTC (bit 0,1,2, and 3) on the microcontroller, while the right one is connected to PORTB (bit 0,1,2, and 3) on the microcontroller.
3) We are using MPLAB IDE v8.30, Microcontroller SASM (to compile), and Tera Term Pro (to run)
4) Use the template below
;;;;;;; P2 for QwikFlash board ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Use 10 MHz crystal frequency ; Use Timerg for ten milisecond loopt ime ; Blink "Alive" LED every two and a half seconds ; Display PORTD as a binary number ; Toggle C2 output every ten m1114seconds for measuring 1ooptime precisely. ;;;;;;;Program hierarchy ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Mainline ; Initial ; InitLCD ; LoopTime ; B1inkAlive ; ByteDisplay (DISPLAY macro) ; DisplayC ; T40 ; Displayv ; T40 ; LoopTime ;;;;;;; Assembler directives;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
list P=PIC18F452, F=INHX32, C=160, N=0, ST=OFF, MM=OFF, R=DEC, X=ON #include P18F452.inc __CONFIG _CONFIG1H, _HS_OSC_1H ;HS oscillator __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_42_2L ;Reset __CONFIG _CONFIG2H, _WDT_OFF_2H ;Watchdog timer disabled __CONFIG _CONFIG3H, _CCP2MX_ON_3H ;CCP2 to RC1 (rather than to RB3) __CONFIG _CONFIG4L, _LVP_OFF_4L ;RB5 enabled for I/O
;;;;;;; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cblock 0x000 ;Beginning of Access RAM TMR0LCOPY ;Copy of sixteen-bit Timer0 used by LoopTime TMR0HCOPY INTCONCOPY ;Copy of INTCON for LoopTime subroutine COUNT ;Counter available as local to subroutines ALIVECNT ;Counter for blinking "Alive" LED BYTE ;Eight-bit byte to be displayed BYTESTR:10 ; Display string for binary version of BYTE endc
;;;;;;; Macro definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF macro literal,dest movlw literal movwf dest endm
POINT macro stringname MOVLF high stringname, TBLPTRH MOVLF low stringname, TBLPTRL endm
DISPLAY macro register movff register,BYTE call ByteDisplay endm
;;;;;;; Vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x0000 ;Reset vector nop goto Mainline
org 0x0008 ;High priority interrupt vector goto $ ;Trap
org 0x0018 ;Low priority interrupt vector goto $ ;Trap
;;;;;;; Mainline program ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mainline rcall Initial ; Initialize everything LOOP_ btg PORTC, RC2 rcall BlinkAlive DISPLAY PORTD rcall LoopTime ENDLOOP_
;;;;;;; Initial subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; This subroutine performs all initializations of variables and registers.
Initial MOVLF B'10001110',ADCON1 ;Enable PORTA & PORTE digital I/O pins MOVLF B'11100001',TRISA ;Set I/O for PORTA MOVLF B'00000000',TRISB ;Set I/O for PORTB MOVLF B'11010001',TRISC ;Set I/0 for PORTC MOVLF B'00001001',TRISD ;Set I/O for PORTD MOVLF B'00000000',TRISE ;Set I/O for PORTE MOVLF B'10001000',T0CON ;Set up Timer0 for a looptime of 10 ms MOVLF B'00010000',PORTA ;Turn off all four LEDs driven from PORTA bsf RCON, IPEN bsf INTCON, GIEL ;Enable all interrupts (low & high priority) bsf INTCON, TMR0IE bcf INTCON2,TMR0IP rcall InitLCD
return ;;;;;;; InitLCD subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Initialize the Optrex 8x2 character LCD. ; First wait for 0.1 second, to get past display's power-on reset time.
InitLCD MOVLF 10, COUNT ;Wait 0.1 second REPEAT_ rcall LoopTime ;Call LoopTime 10 times decf COUNT, F UNTIL_ .Z.
bcf PORTE,0 ;RS=0 for command POINT LCDstr ;Set up table pointer to initialization string tblrd* ;Get first byte from string into TABLAT REPEAT_ bsf PORTE,1 ;Drive E high movff TABLAT, PORTD ;Send upper nibble bcf PORTE,1 ;Drive E low so LCD wi11 process input rcall LoopTime ;Wait ten milliseconds bsf PORTE,1 ;Drive E high swapf TABLAT, W ; Swap nibbles movwf PORTD ; Send lower nibble bcf PORTE,1 ;Drive E low so LCD wil1 process input rcall LoopTime ;Wait ten milliseconds tblrd+* ;Increment pointer and get next byte movf TABLAT,F ;Is it zero? UNTIL_ .Z. return ;;;;;;; T40 subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Pause for 40 microseconds or 40/0.4 = 100 clock cycles. ; Assumes 10/4 = 2.5 MHz internal clockrate
T40 movlw 100/3 ; Eash REPEAT loop takes 3 cycles movwf COUNT REPEAT_ decf COUNT,F UNTIL_ .Z. return
;;;;;;; DisplayC subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This subroutine is called with TBLPTR containing the address of a constant ; display string. It sends the bytes of the string to the LCD. The first ; byte sets the cursor position. The remaining bytes are displayed, begining ; at that position. ; This subroutine expects a normal one-byte cursor-positioning code, xhh, or ; an occasionally used two-byte cursor-positioning code of the form 0x0hh
DisplayC bcf PORTE,0 ;Drive RS pin low for cursor-positioning code tblrd* ;Get byte from string into TABLAT movf TABLAT, F ;Check for leading zero byte IF_ .Z. tblrd+* ;If zero, get next byte ENDIF_ REPEAT_ bsf PORTE,1 ;Drive E pin high movff TABLAT, PORTD ;Send upper nibble bcf PORTE, 1 ;Drive E pin low so LCD wi1l accept nibble bsf PORTE,1 ;Drive E pin high again swapf TABLAT, W ; Swap nibbles movwf PORTD ;Write lower nibble bcf PORTE,1 ;Drive E pin low so LCD will process byte rcall T40 ;Wait 40 usec bsf PORTE,0 ;Drive RS pin high for displayable characters tblrd+* ; Increment pointer, then get next byte movf TABLAT, F ;Is it zero? UNTIL_ .Z. return
;;;;;;; DisplayV subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This subroutine is called with FSR0 containting the address of a variable ; display string. It sends the bytes of the string to the LCD. The first ; byte sets the cursor position. The remaining bytes are displayed, begining ; at that position.
DisplayV bcf PORTE,0 ; Drive RS pin low for cursor-positioning code REPEAT_ bsf PORTE, 1 ; Drive E pin high movff INDF0, PORTD ; Send upper nibble bcf PORTE, 1 ; Drive E pin 1ow so LCD wi11 accept nibble bsf PORTE,1 ; Drive E pin high again swapf INDF0,W ; Swap nibbles movwf PORTD ; Write lower nibble bcf PORTE, 1 ; Drive E pin 1ow so LCD wi11 process byte rcall T40 ; Wait 40 usec bsf PORTE,0 ; Drive RS pin high for displayable characters movf PREINC0,W ; Increment pointer, then get next byte UNTIL_ .Z. return
;;;;;;;BlinkATive subroutine;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; This subroutine briefly blinks the LED next to the PIC every two-and-a-half ; seconds.
BlinkAlive bsf PORTA, RA4 ;Turn off LED decf ALIVECNT, F ;Decrement loop counter and return if not zero IF_ .Z. MOVLF 250, ALIVECNT ;Reinitialize ALIVECNT bcf PORTA, RA4 ;Turn on LED for ten milliseconds every 2.5 sec ENDIF_ return
;;;;;;; LoopTime subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; This subroutine waits for Timer0 to complete its ten millisecond count ; sequence. It does so by waiting for sixteen-bit Timer0 to roll over. To obtain ; a period of precisely 10000/0.4 = 25000 clock periods, it needs to remove ; 65536-25000 or 40536 counts from the sixteen-bit count sequence. The ; algorithm below first copies Timer0 to RAM, adds "Bignum" to the copy ,and ; then writes the result back to Timer0. It actually needs to add somewhat more ; counts to Timer0 than 40536. The extra number of 12+2 counts added into ; "Bignum" makes the precise correction.
Bignum equ 65536-25000+12+2
LoopTime btfss INTCON,TMR0IF ;Wait until ten milliseconds are up bra LoopTime movff INTCON,INTCONCOPY ;Disable all interrupts to CPU bcf INTCON,GIEH movff TMR0L,TMR0LCOPY ;Read 16-bit counter at this moment movff TMR0H,TMR0HCOPY movlw low Bignum addwf TMR0LCOPY,F movlw high Bignum addwfc TMR0HCOPY,F movff TMR0HCOPY,TMR0H movff TMR0LCOPY,TMR0L ;Write 16-bit counter at this moment movf INTCONCOPY,W ;Restore GIEH interrupt enable bit andlw B'10000000' iorwf INTCON,F bcf INTCON,TMR0IF ;Clear Timer0 flag return
;;;;;;; ByteDipslay subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Displat whatever is in BYTE as a binary number
ByteDisplay POINT BYTE_1 rcall DisplayC ;Display "BYTE-" lfsr 0, BYTESTR+8 REPEAT_ clrf WREG rrcf BYTE,F ;Move bit into carry rlcf WREG,F ;and from there into WREG iorlw 0x30 ;Convert to ASCII movwf POSTDEC0 ; and move to string movf FSR0L,W ; Done? sublw low BYTESTR UNTIL_ .Z.
lfsr 0,BYTESTR ; Set pointer to display string MOVLF 0xc0, BYTESTR ;Add cursor-positioning code clrf BYTESTR+9 ;and end-of-string terminator rcall DisplayV return
;;;;;;; Constant strings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCDstr db 0x33,0x32,0x28,0x01,0x0c,0x06,0x00 ;Initialization string for LCD BYTE_1 db "\x80BYTE= \x00" ;write "BYTE-' to first line of LCD BarChars ; Bargraph user-defined characters db 0x00,0x48 ;CGRAM-positioning code db 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 ;Column 1 db 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98 ;Columns 1,2 db 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c ;Columns 1,2,3 db 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e ;Columns 1,2,3,4 db 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f ;Column 1,2,3,4,5 db 0x00 ; End-of-string terminator
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end
****This is our microcontroller*****
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started