Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * ATtiny85_PulseReceiver.c
- *
- * Created: 10/16/2014 12:48:10 PM
- * Author: grist.carrigafoyl
- A receiver for signals from a fibre optic connector for use with a Micro-brute
- Tesla Coil. Will respond to pin changes on PCINT0 (PB0, pin 5), but will not
- allow a pulse greater than a preset width to occur. Using an external crystal
- oscillator for the clock.
- Also incorporating a guard timer to prevent pulses ocurring too often.
- Input is on PB0, pin5
- Output is on PB1, pin 6.
- v1.00 First working version. Trips up on pulses less than 5us
- v1.01 Trying to fix trip. Moved max width timer to first instruction after interrupt triggered
- v1.02 Still trips up and latency seemed high. Moved max width timer to last instruction in PCINT0_vect
- v1.03 Fixed trip up. Even feeding a 2MHz signal with nanosecond pulses doesn't phase it.
- */
- #define F_CPU 8000000UL // 8Mhz
- #define MAX_PULSE_WIDTH 190 // microseconds
- #define MIN_GUARD_TIMER 60 // min microseconds between pulses
- #define INPUT_PIN PB0
- #define OUTPUT_PIN PB1
- #include <avr/io.h>
- #include <avr/interrupt.h>
- // Used to control the behaviour of COMPB_vect
- volatile uint8_t long_timer_active = 0;
- int main(void)
- {
- // Set Output pin as output
- DDRB |= _BV(OUTPUT_PIN);
- // Set up the interrupt on pin 5
- GIMSK |= _BV(PCIE); // pin change interrupt enable
- PCMSK |= _BV(PCINT0); // only react to changes on PCINT0, ie PB0, pin 5
- // Timer0 interrupt settings to limit the pulse width
- TCCR0A = _BV(WGM01); // ctc mode
- TIMSK |= _BV(OCIE0A) | _BV(OCIE0B); // Enable Timer 0 COMP A & B interrupt vectors on match
- // Not setting this here as it starts the timer. That will be done by the timer 1 interrupt.
- //TCCR0B|= _BV(CS01); // prescaler 8, so OCR0A is in ยตs @ 8MHz
- OCR0A = MAX_PULSE_WIDTH; // should be close to microseconds with prescalar 8 and 8MHz clock
- OCR0B = MIN_GUARD_TIMER; // minimum time between pulses
- sei(); // enable global interrupts
- while(1)
- {
- //TODO:: Nothing to see here.
- }
- }
- ISR(PCINT0_vect) {
- // React to changes on pin 5. Logic is reversed as the fibre optic receiver
- // holds the pin high until it receives a signal.
- if ((PINB & _BV(INPUT_PIN)) == 0) { // pin is now low, so rising edge of original pulse
- PORTB |= _BV(OUTPUT_PIN); // turn the output pin on
- TCNT0 = 0; // reset the counter
- long_timer_active = 1;
- } else { // pin now high, so falling edge of original pulse
- PORTB &= ~_BV(OUTPUT_PIN); // output pin off
- TCNT0 = 0;
- PCMSK = 0; // disable pin change interrupts until the guard timer has expired
- long_timer_active = 0;
- }
- TCCR0B|= _BV(CS01); // start the max pulse width timer with prescaler 8
- }
- ISR(TIMER0_COMPA_vect)
- // Max pulse width timer. If we get to here then a pulse was received that exceeded the max
- // allowable. This could cause an over-current condition and damage to the IGBTs.
- {
- // Turn off the pin.
- PORTB &= ~_BV(OUTPUT_PIN);
- PCMSK = 0; // disable pin change interrupt
- // set the prescalar to 1024 to really delay the next possible pulse.
- TCCR0B = _BV(CS00) | _BV(CS02);
- long_timer_active = 0;
- }
- ISR(TIMER0_COMPB_vect)
- // Guard timer. No pin change interrupts are allowed until this has expired.
- {
- if (long_timer_active == 0) {
- // Turn the timer off, we're done with it for now
- TCCR0B = 0;
- }
- // Reenable pin change interrupts on the input pin
- PCMSK |= _BV(PCINT0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement