Advertisement
grist

ATtiny Pulse Receiver

Nov 6th, 2014
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.96 KB | None | 0 0
  1. /*
  2.  * ATtiny85_PulseReceiver.c
  3.  *
  4.  * Created: 10/16/2014 12:48:10 PM
  5.  *  Author: grist.carrigafoyl
  6.  
  7.  A receiver for signals from a fibre optic connector for use with a Micro-brute
  8.  Tesla Coil. Will respond to pin changes on PCINT0 (PB0, pin 5), but will not
  9.  allow a pulse greater than a preset width to occur. Using an external crystal
  10.  oscillator for the clock.
  11.  
  12.  Also incorporating a guard timer to prevent pulses ocurring too often.
  13.  
  14.  
  15.  Input is on PB0, pin5
  16.  Output is on PB1, pin 6.
  17.  
  18.  */
  19.  
  20. #define F_CPU 8000000UL // 8Mhz
  21. #define MAX_PULSE_WIDTH 190 // microseconds
  22. #define MIN_GUARD_TIMER 60 // min microseconds between pulses
  23. #define OUTPUT_PIN PB1
  24.  
  25.  
  26. #include <avr/io.h>
  27. #include <avr/interrupt.h>
  28.  
  29. // Used to control the behaviour of COMPB_vect
  30. volatile char long_timer_active = 0;
  31.  
  32.  
  33. int main(void)
  34. {
  35.     // Set Output pin as output
  36.     DDRB |= _BV(OUTPUT_PIN);
  37.    
  38.     // Set up the interrupt on pin 5
  39.     GIMSK |= _BV(PCIE); // pin change interrupt enable
  40.     PCMSK |= _BV(PCINT0); // only react to changes on PCINT0, ie PB0, pin 5
  41.    
  42.     // Timer0 interrupt settings to limit the pulse width
  43.     TCCR0A = _BV(WGM01); // ctc mode
  44.     TIMSK |= _BV(OCIE0A) | _BV(OCIE0B); // Enable Timer 0 COMP A & B interrupt vectors on match
  45.     // Not setting this here as it starts the timer. That will be done by the timer 1 interrupt.
  46.     //TCCR0B|= _BV(CS01); // prescaler 8, so OCR0A is in ยตs @ 8MHz
  47.     OCR0A = MAX_PULSE_WIDTH; // should be close to microseconds with prescalar 8 and 8MHz clock
  48.     OCR0B = MIN_GUARD_TIMER; // minimum time between pulses
  49.  
  50.     sei(); // enable global interrupts 
  51.    
  52.     while(1)
  53.     {
  54.         //TODO:: Please write your application code
  55.     }
  56. }
  57.  
  58.  
  59. ISR(PCINT0_vect) {
  60. // React to changes on pin 5. Logic is reversed as the fibre optic receiver
  61. // holds the pin high until it receives a signal.
  62.     if ((PINB & _BV(PB0)) == 0) { // pin is now low, so rising edge of original pulse
  63.         PORTB |= _BV(OUTPUT_PIN); // turn it on
  64.         TCNT0 = 0; // reset the counter
  65.         TCCR0B|= _BV(CS01); // start the max pulse width timer with prescaler 8
  66.         long_timer_active = 1;
  67.     } else { // pin now high, so falling edge of original pulse
  68.         PORTB &= ~_BV(OUTPUT_PIN);
  69.         TCNT0 = 0;
  70.         PCMSK = 0; // disable pin change interrupt
  71.         long_timer_active = 0;
  72.     }
  73. }
  74.  
  75.  
  76. ISR(TIMER0_COMPA_vect)
  77. // Max pulse width timer. If we get to here then a pulse was received that exceeded the max
  78. // allowable. This could cause an over-current condition and damage to the IGBTs.
  79. {
  80.     // Turn off the pin.
  81.     PORTB &= ~_BV(PB1);
  82.     PCMSK = 0; // disable pin change interrupt
  83.     // set the prescalar to 1024 to really delay the next possible pulse.
  84.     TCCR0B = _BV(CS00) | _BV(CS02);
  85.     long_timer_active = 0;
  86. }
  87.  
  88. ISR(TIMER0_COMPB_vect)
  89. // Guard timer. No pin change interrupts are allowed until this has expired.
  90. {
  91.     if (long_timer_active == 0) {
  92.         // Turn the timer off, we're done with it for now
  93.         TCCR0B = 0;
  94.     }
  95.     // Reenable pin change interrupts on the input pin
  96.     PCMSK |= _BV(PCINT0);
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement