PDA

View Full Version : PIC16F877A pwm use for IR transmission



mcbeasleyjr
- 11th July 2009, 18:51
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.



'************************************************* ***************
'* 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