Hello all. I will be using a PIC16F877A for the project that I am currently working on. I have used this chip in the past, however, I've never programmed it in assembly language before. Right now I'm trying to learn the language as best as possible. I am going to post the code that I have so far below. I am hoping that some of you will look over my code, and give me some feedback as to if you think it will work for my application. The idea of this program is to generate a 38Khz PWM signal to be used in and IR system. It will basically be used for object detection and obstacle avoidance. The theory works because we currently do it using PBP. However, I am waiting for my next PIC to arrive and therefore don't have one to test with at this point in time. Please, take some time and read through my program and provide some feedback for me. I know its got quite a bit extra in it right now but there will be more added to it. Just testing PWM's right now.
Thank you all in advance.
Code:'**************************************************************** '* Name : TESTINGASSEMBLY.BAS * '* Author : Morris C. Beasley, Jr. * '* Notice : Copyright (c) 2009 Morris C. Beasley, Jr. * '* : All Rights Reserved * '* Date : 7/11/2009 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** ; Status register bits ; bit 7 - 1 = Bank 2, 3 and bit 7 - 0 = Bank 0, 1 ; bit 6&5 - 11 = Bank 3, 10 = Bank 2, 01 = Bank 1, 00 = Bank 0 ASM ; Put names to memory locations to make it easier to recognize ; Also identify any variables STATUS EQU 03h ; Status register location PORTA EQU 05h ; PortA register PORTB EQU 06h ; PortB register PORTC EQU 07h ; PortC register PORTD EQU 08h ; PortD register PORTE EQU 09h ; PortE register T2CON EQU 12h ; Timer2 register CCPR1L EQU 15h ; CCPR1L register CCP1CON EQU 17h ; CCP1CON register CCPR2L EQU 1Bh ; CCPR2L register CCP2CON EQU 1Dh ; CCP2CON register COUNT1 EQU 20h ; Variable for delay loop COUNT2 EQU 21h ; Variable for delay loop TRISA EQU 85h ; Tristate register (A) TRISB EQU 86h ; Tristate register (B) TRISC EQU 87h ; Tristate register (C) TRISD EQU 88h ; Tristate register (D) TRISE EQU 89h ; Tristate register (E) PR2 EQU 92h ; PR2 register ;Initialize ports BSF STATUS,5 ; Switch to Bank 1 to set up Tristates MOVLW 0Fh ; Move hex value into W register MOVWF TRISA ; Place value of W register into Tristate (A) ; Makes first 4 bits of PORTA inputs for ADC MOVLW 00h ; Move hex value into W register MOVWF TRISB ; Place value of W register into Tristate (B) MOVLW 08h ; Move hex value into W register MOVWF TRISC ; Place value of W register into Tristate (C) ; Makes PortC.3 an input for IR Receiver MOVLW 00h ; Move hex value into W register MOVWF TRISD ; Place value of W register into Tristate (D) MOVLW 00h ; Move hex value into W register MOVWF TRISE ; Place value of W register into Tristate (E) BCF STATUS,5 ; Switch back to Bank 0 ;Start outputs in low logic MOVLW 00h ; Move hex value into W register MOVWF PORTB ; Move value of W register into PORTB register MOVLW 00h ; Move hex value into W register MOVWF PORTD ; Move value of W register into PORTD register MOVLW 00h ; Move hex value into W register MOVWF PORTE ; Move value of W register into PORTE register ;Begin main loop START BCF PORTB,0 ; Turn off left signal indicator BCF PORTB,1 ; Turn off right signal indicator CALL CHECK_LEFT ; Check left side IR for objects MOVLW 00h ; Move hex value into W register MOVWF CCP1CON ; Disable PWM1 if not done so already. CALL CHECK_RIGHT ; Check right side IR for objects MOVLW 00h ; Move hex value into W register MOVWF CCP2CON ; Disable PWM2 if not done so already. GOTO START ; Do it forever ; PWM FREQ = 38461.54 Hz ; RESOLUTION BITS = 9 ; TIMER2 PRESCALER = 1:1 ; PR2 = 0b10000001 ; T2CON = 0b00000100 ; CCPR1L = 0b01000000 ; CCP1CON = 0b00111100 CHECK_LEFT LEFT MOVLW 40h ; Move hex value into W register MOVWF CCPR1L ; Sets CCPR1L register to 40h (64 decimal) ; Allows 50% duty cycle MOVLW 04h ; Move hex value into W register MOVWF T2CON ; Timer2 on = prescale value 1:1 BSF STATUS,5 ; Switch to Bank 1 MOVLW 81h ; Move hex value into W register MOVWF PR2 ; Sets PR2 register to 81h (129 decimal) BCF STATUS,5 ; Switch back to Bank 0 MOVLW 3Ch ; Move hex value into W register MOVWF CCP1CON ; Initialize (start) PWM transmission ; 38KHz signal enabled CALL DELAY ; Allow PWM signal time to stabilize BTFSC PORTC,3 ; Check PORTC bit 3 for received signal from ; the IR Receiver RETURN ; If bit is set, then no signal detected. ; Return to calling location. BSF PORTB,0 ; If bit is cleared, turn on LED CALL DELAY ; Allow time for us to see that signal has ; been received by the PIC. MOVLW 00h ; Move hex value into W register MOVWF CCP1CON ; Disable PWM1. RETURN CHECK_RIGHT RIGHT MOVLW 40h ; Move hex value into W register MOVWF CCPR2L ; Sets CCPR1L register to 40h (64 decimal) ; Allows 50% duty cycle MOVLW 04h ; Move hex value into W register MOVWF T2CON ; Timer2 on = prescale value 1:1 BSF STATUS,5 ; Switch to Bank 1 MOVLW 81h ; Move hex value into W register MOVWF PR2 ; Sets PR2 register to 81h (129 decimal) BCF STATUS,5 ; Switch back to Bank 0 MOVLW 3Ch ; Move hex value into W register MOVWF CCP2CON ; Initialize (start) PWM transmission ; 38KHz signal enabled CALL DELAY ; Allow PWM signal time to stabilize BTFSC PORTC,3 ; Check PORTC bit 3 for received signal from ; the IR Receiver RETURN ; If bit is set, then no signal detected. ; Return to calling location. BSF PORTB,1 ; If bit is cleared, turn on LED CALL DELAY ; Allow time for us to see that signal has ; been received by the PIC. MOVLW 00h ; Move hex value into W register MOVWF CCP2CON ; Disable PWM2. RETURN DELAY LOOP3 DECFSZ COUNT1,1 ; This delay loop should count down from GOTO LOOP3 ; 255 twice to allow enough time to notice DECFSZ COUNT2,1 ; anything that may be happening. GOTO LOOP3 ; RETURN ENDASM END




Bookmarks