Simulating a Camshaft Encoder signal

Thread Starter

Kefka

Joined Aug 1, 2011
2
Hey guys, i need some advice, i have to simulate a Camshaft encoder signal which is 24 pulses plus 1 whit the 16f876, heres the signal on the scope:


I thought of using TMR0 interrupt and then in the ISR Change the conf. of PWM then going back to the main and so on, but I'm having all sort of problems whit the timing, like this:


I was wondering if you have any tips or ideas as to how to simulate this signal.

Thanks in advance.​
 

kavli

Joined Aug 1, 2011
23
Have you disabled interrupts when you're modifying the PWM register?
Apart from that, I think I'd have solved it by just using one timer and a counter for locating the marker.
When hitting the marker, skip two toggles of the output.

-- K
 

Markd77

Joined Sep 7, 2009
2,806
I don't know if this is happening here but if the pulse is shorter than one instruction cycle then MPLAB SIM won't show it, but it will happen in real life.
 

Thread Starter

Kefka

Joined Aug 1, 2011
2
ok guys i manage to get rid of the blank spaces but still dont know how to make it count 23 pulses the double pulse, heres the code thus far:


INT_VAR UDATA_SHR
w_temp RES 1 ; variable used for context saving
status_temp RES 1 ; variable used for context saving

UDATA_SHR

;****************************************************

RESET CODE 0x0101
pagesel MAIN
goto MAIN

;****************************************************
INT_VECTOR CODE 0x0004 ; interrupt vector location

INTERRUPT
ORG 0X04

movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
bcf INTCON,T0IF

movlw B'01111100' ; period
movwf PR2
bcf STATUS,RP0
movlw B'00111110' ; setting the duty cycle time to 50%
movwf CCPR1L
bsf CCP1CON,5
bcf CCP1CON,4
bsf STATUS,RP0
bcf TRISC,2 ; pin 2 of port c is an output
bcf STATUS,RP0
movlw B'00000101'
movwf T2CON
bsf CCP1CON,3
bsf CCP1CON,2


movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
movlw 1<<GIE|1<<T0IE
movwf INTCON

retfie ; return from interrupt

;****************************************************
__config 0x393A
ORG 0X00
GOTO MAIN

code
MAIN


bcf STATUS,RP0
movlw b'110000100'
banksel OPTION_REG
movwf OPTION_REG
clrf PORTA ;clear content of port A
clrf PORTB ;clear content of port B
clrf PORTC ;clear content of port C
bsf STATUS,RP0 ;change to bank 1
movlw B'11111111'
movwf TRISA ;set port A as input
clrf TRISB ;set port B as output
clrf TRISC
movlw 1<<GIE|1<<T0IE
movwf INTCON



movlw B'11111001' ; period
movwf PR2
bcf STATUS,RP0
movlw B'00111110' ; setting the duty cycle time to 25%
movwf CCPR1L
bsf CCP1CON,5
bcf CCP1CON,4
bsf STATUS,RP0
bcf TRISC,2 ; pin 2 of port c is an output
bcf STATUS,RP0
movlw b'01001101'
movwf 12h
bsf CCP1CON,3 ;configuring CCP1 module for PWM operation
bsf CCP1CON,2

goto MAIN

END
 

kavli

Joined Aug 1, 2011
23
ok guys i manage to get rid of the blank spaces but still dont know how to make it count 23 pulses the double pulse, heres the code thus far:
Ok. I still see you're using the PWM path. I don't think it's a totally wrong path, but I don't think it's the easiest and most straight forward solution.

Here is some pseudocode for a state-machine driven approach, using only timer0.
Not tested, but should generally work.

The reason the counter is counting from 46 instead of 23 is that the state-machine is clocked in half-phase increments.

-- K

Rich (BB code):
# states:
# 1 - notch high
# 2 - notch low
# 3 - double notch

init:
  mask interrupts
  set counter = 46
  set state = 1
  set nextstate = 1
  setup timer0
  enable interrupts

on_timer_interrupt:
  mask interrupts
  if state == 1:
    set output = 1
    counter--
    if counter == 0:
      nextstate = 3
    else
      nextstate = 2
  elif state == 2:
    set output = 0
    counter--
  elif state == 3:
    counter = 46
    nextstate = 1
  else:
    # Not reached

  state = nextstate

  reset timer0
  reenable interrupts

main:
  init()
 

kavli

Joined Aug 1, 2011
23
...there should, of course be a:
Rich (BB code):
   elif state == 2:
     set output = 0
     counter--
+    nextstate = 1
-- K
 
Top