Re: C++/C programming discussion
Posted: Sun Sep 26, 2010 5:20 pm
PIC programs can be made in assembly code or C. I think there are special PIC libraries for C which at least limits the requirement of assembly when programming PIC chips. Here's my PIC program for calculating mean averages from a list of inputed numbers:
Code: Select all
; Register Definitions:
These are definitions given to the registers by the PICMicro program for ease of use.
INDF EQU 00
TMR0 EQU 01
PCL EQU 02
STATUS EQU 03
FSR EQU 04
PORTA EQU 05
PORTB EQU 06
EEDATA EQU 08
EEADR EQU 09
PCLATH EQU 0A
INTCON EQU 0B
OPSHUN EQU 81
TRISA EQU 85
TRISB EQU 86
EECON1 EQU 88
EECON2 EQU 89
TOTALA EQU 0C
The right (Least significant) byte for the running total
TOTALB EQU 0D
The left (Most significant) byte for the running total
COUNT EQU 0E
Stores the number of numbers entered
WORANS EQU 0F
Stores the count of how many times the count fits into the total. Stands for working answer.
ARITHA EQU 10
Stores the next value for total A to be used when the count is taken away.
; Constant Definitions:
Put by the PicMicro program.
W EQU 00 ; Working
F EQU 01 ; File
; Program Start:
ORG 0
GOTO 004
NOP
NOP
NOP
BSF STATUS,05
Bit 5 of the STATUS register is set. This applies following commands to page 1 of memory.
MOVLW FF
Move FF to the working register.
MOVWF TRISA
Move the FF value to TRISA. All bits on port A are set to inputs.
MOVLW C0
Move CO to the working register
MOVWF TRISB
Moves the CO value to TRISB. The first two bits on port B are then inputs and the rest are outputs.
BCF STATUS,05
Clear bit 5 on the SATUS register. Following commands apply to page 0 of memory.
START CLRF COUNT
Clear COUNT to 0
CLRF TOTALA
Clear TOTALA to 0
CLRF TOTALB
Clear TOTALB to 0
ENTRY BTFSC PORTB,07
If bit 7 on port B is clear, skip the next command.
CALL ADD
Bit 7 on port B is set, so call the ADD subroutine which is used to add a new number.
BTFSS PORTB,06
If bit 6 on port B is set, skip the next command.
GOTO ENTRY
Go back to the entry memory address, looping through it when input is needed.
LOOP BTFSS PORTB,06
Bit 6 was set on port B so now skip if it is still set.
GOTO CALC
Bit 6 was unset on port B. Now go to CALC to calculate and display the mean.
GOTO LOOP
Go back to LOOP to check if it’s still set.
ADD BTFSC PORTB,07
Skip if bit 7 on port B is not set.
GOTO ADD
If still set, go back to ADD and loop until it is unset.
GOTO ADDCAL
Go to ADDCAL to determine if another number can be added to COUNT, else calculate the mean since the numbers entered have reached the 255 limit.
ADDCAL INCFSZ COUNT,F
Increment COUNT and skip if zero (Hence arithmetic carry occurred)
GOTO ALLOW
No carry, add another number by going to ALLOW.
GOTO DCCALC
Carry occurred go to DCCALC to decrement COUNT back to 255 and then calculate the mean.
RETURN
Return to the ENTRY loop
ALLOW MOVF PORTA,W
Move PORTA to the working register. Port A should contain the number that the user wants to add to the list of numbers to calculate the mean for.
ADDWF TOTALA,F
Add this value to TOTALA
BTFSC STATUS,00
If bit 0 on the STATUS register is set there has been a carry. Skip if clear
INCF TOTALB,F
There has been a carry in TOTALA, so increment TOTALB.
RETURN
Return to the ENTRY loop
DCCALC DECF COUNT,F
COUNT had been incremented to test for a carry but now need to be decremented to it’s value beforehand to calculate the correct answer
GOTO CALC
Go to CALC to calculate and display the mean.
CALC CLRF WORANS
Clear the WORANS to 0
DECF COUNT,F
Decrement COUNT
INCF COUNT,F
Increment it back
BTFSS STATUS,02
COUNT was decremented and incremented again to test the STATUS register’s bit 2. If it is set COUNT is zero. This command will skip if the bit is set, hence when COUNT is zero.
GOTO CALTES
COUNT was not zero hence, continue with the calculation by going to CALTES
BSF PORTB,05
Set bit 5 on port B. This represents a division by zero error. The mean is total/count. If count is zero, this error should be shown.
GOTO ENTRY
Zero division error. Go back to entry where the user should hopefully add some numbers before applying input to bit 6 on port B.
CALTES BCF PORTB,05
Clear bit 5 on port B because there was no zero division error.
MOVF COUNT,W
Move COUNT to the working register
SUBWF TOTALA,W
Subtract the working register from TOTALA and leave the result in the working register.
MOVWF ARITHA
Move the working register to ARITHA. ARITHA now contains TOTALA - COUNT
BTFSC STATUS,00
Skip if bit 0 on the STATUS register is 0. The bit is set when there was no carry from the prior subtraction.
GOTO NUMSUB
No carry, so go to NUBSUB because the COUNT was able to fit inside TOTALA
DECF TOTALB,F
There was a carry so check TOTALB is zero by first decrementing.
INCF TOTALB,F
Then incrementing back.
BTFSC STATUS,02
If bit 2 on the STATUS register is set, the increment resulted in zero, hence TOTALB is zero. Skip if the bit is 0 (Not set).
GOTO EXLOOP
TOTALB is zero, hence the entire total went below zero and the count could fit inside the total no longer. Go to EXLOOP to finish the calculation by rounding the number to the correct nearest whole number and then display the result.
DECF TOTALB,F
TOTALB was not set so decrement it and continue with NUMSUB.
NUMSUB INCF WORANS,F
Increment WORANS as another count was able to fit inside the total.
MOVF ARITHA,W
Move ARITHA to the working register
MOVWF TOTALA
Move the working register value to TOTALA. TOTALA now contains the result of removing COUNT from TOTALA from previous operations.
GOTO CALTES
Go back to CALTES to continue the processing until the count can no longer fit into the total.
EXLOOP MOVF TOTALA,W
Move TOTALA to the working register.
SUBWF COUNT,W
Subtract the working register from COUNT and leave the result in the working register.
SUBWF TOTALA,W
Subtract the working register from TOTALA and leave the result in the working register. The working register now contains the result of TOTALA – (COUNT - TOTALA) which is the same as 2*TOTALA - COUNT
BTFSS STATUS,00
Skip if bit 0 on the STATUS register is set, hence a carry.
INCF WORANS,F
Increment WORANS because COUNT was not larger than twice TOTALA hence the result for the remainder division would be 0.5 or more.
MOVF WORANS,W
Move WORANS to the working register
MOVWF PORTB
Move the working register to port B hence displaying the answer.
GOTO START
Goto the start to reset COUNT and the total and then to wait for user input again.
END