Device 16F876A
Declare XTAL 4
'_______________________________________________________
' ADC compiler settings / declares
DECLARE ADIN_RES 10 ' 10-bit result required
DECLARE ADIN_TAD 8_FOSC ' RC OSC chosen
DECLARE ADIN_STIME 50 ' Allow 50us sample time
'_______________________________________________________
' Define program variables
Dim ADC_Result As Float
Dim ADC_Total As Float
Dim ADC_Channel as Byte
Dim ADC_Loops as Byte
Dim Temp as Byte
Dim First_Result As Word
Dim Second_Result As Word
Dim Difference As Word
Dim Last_Difference As Word
Symbol Max_Deviation = 10 ' Set the max deviation (i.e. acceleration)
Symbol mS_Time_Sample = 50 ' Set the interval for sampling (mS)
Symbol LED1_Control = PORTB.0 ' Assign the outputs for the LED's
Symbol LED2_Control = PORTB.1 '
'_______________________________________________________
' TMR0 Settings
Dim uS as Word
Dim mS as Word
Symbol GIE = INTCON.7
Symbol TMR0_uS = 512 ' Set time interval of TMR0 with 4Mhz Osc
Symbol TMR0_Enable = INTCON.5
Symbol TMR0_Overflow = INTCON.2
'_______________________________________________________
' Start of program
ON_INTERRUPT Goto Interrupt_Sub
Goto Initialize
Initialize:
INTCON = %00100000 ' Config the Interrupt Register
OPTION_REG = %00000000 ' Config the OPTION_REG
TRISA = %11111111 ' Set porta/b pins
TRISB = %00000000
PORTB = %00000000
ADC_Loops = 100 ' This controls the accurracy
' of the ADC routine
ADC_Channel = 1
ADCON1 = %10000000 ' Set analogue input, Vref is Vdd
Main:
' Grab a 10-Bit value (0-1023) of what the voltage is on PORTA.0
Gosub ADC_Average
' Store the value
First_Result = ADC_Result
' Zero the timer settings
uS = 0
mS = 0
TMR0 = 0
GIE = 1
' Loop until the specified time is reached
Repeat
Until mS = mS_Time_Sample
GIE = 0
' Check what the new value of PORTA.0 is
Gosub ADC_Average
' Store it
Second_Result = ADC_Result
' Check which direction it has moved,
' then calculate its amount of movement
If First_Result > Second_Result Then
Difference = First_Result - Second_Result
Else
Difference = Second_Result - First_Result
Endif
' Check which direction it has moved,
' and determine if its to fast
If Difference > Last_Difference Then
If Difference - Last_Difference >= Max_Deviation Then
LED1_Control = 0
LED2_Control = 1
Else
LED1_Control = 0
LED2_Control = 1
Endif
Else
If Last_Difference - Difference >= Max_Deviation Then
LED1_Control = 0
LED2_Control = 1
Else
LED1_Control = 0
LED2_Control = 1
Endif
Endif
' Store the last difference to compare with next time
Last_Difference = Difference
Goto Main
ADC_Average: ' Grab an average of the ADC value, increases
' accuracy greatly
ADC_Total = 0
For Temp = 1 To ADC_Loops
ADC_Result = ADIN ADC_Channel
ADC_Total = ADC_Total + ADC_Result
Next Temp
ADC_Result = ADC_Total / ADC_Loops
Return
Interrupt_Sub:
Context Save
If TMR0_Overflow = 1 And TMR0_Enable = 1 Then
TMR0_Overflow = 0
uS = uS + TMR0_uS
If uS >= 1000 Then
uS = uS - 1000
mS = mS + 1
EndIf
EndIf
GIE = 1
CONTEXT RESTORE