This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
code:ground_control [2008/10/30 15:08] laurenceb |
code:ground_control [2008/11/13 09:50] (current) laurenceb |
||
---|---|---|---|
Line 1: | Line 1: | ||
===== Input capture based version ===== | ===== Input capture based version ===== | ||
This uses the input capture function on timer1 (atmega168). The ICNC1 bit in the TCCR1B register need to be set to enable oversampling to give more noise tolerance. A second function running approx every 20ms is needed to decrement counter by two and check if counter>=30. If this is the case there is a valid pwm stream and the diff variable can be used to set the pwm output. | This uses the input capture function on timer1 (atmega168). The ICNC1 bit in the TCCR1B register need to be set to enable oversampling to give more noise tolerance. A second function running approx every 20ms is needed to decrement counter by two and check if counter>=30. If this is the case there is a valid pwm stream and the diff variable can be used to set the pwm output. | ||
- | |||
==== Header ==== | ==== Header ==== | ||
<code c> | <code c> | ||
- | #define enable_ground_control TIMSK1|=(1<<ICIE1) //enables the input capture interrupt | + | void enable_ground_control(); //enables the input capture interrupt |
- | #define disable_ground_control TIMSK1&=~(1<<ICIE1) //disables input capture interrupt | + | void disable_ground_control(); //disables input capture interrupt |
- | + | #define PULSE_MIN (s16)(0.001*(float)F_CPU/16.0) //pwm must be in the range 1 to 2 ms | |
- | #define PULSE_MIN 0.001*F_CPU/8; //pwm must be in the range 1 to 2 ms | + | #define PULSE_MAX (s16)(0.002*(float)F_CPU/16.0) //due to the bit shift we divide by 16 |
- | #define PULSE_MAX 0.002*F_CPU/8; | + | #define GROUND_LED_ON PORTD|=(1<<3) |
+ | #define GROUND_LED_OFF PORTD&=~(1<<3) | ||
+ | #define GROUND_LED_SET PORTD&(1<<3) | ||
+ | void run_ground_control(); | ||
</code> | </code> | ||
+ | |||
====Main code=== | ====Main code=== | ||
<code c> | <code c> | ||
- | extern volatile u08 counter; //globals | + | #ifdef GROUND |
- | extern volatile s16 diff; | + | #include "main.h" |
- | + | extern volatile u08 counter; //globals | |
+ | extern volatile u16 diff; | ||
+ | |||
+ | |||
ISR(TIMER1_CAPT_vect) | ISR(TIMER1_CAPT_vect) | ||
{ | { | ||
static u16 start; | static u16 start; | ||
- | if(TCCR1B|0x40) //start of a pulse | + | if(TCCR1B&0x40) //start of a pulse |
{ | { | ||
TCCR1B&=~0x40; //set to trigger on falling edge | TCCR1B&=~0x40; //set to trigger on falling edge | ||
- | start=ICP1; //record start of the pulse | + | start=ICR1; //record start of the pulse |
} | } | ||
else | else | ||
{ | { | ||
TCCR1B|=0x40; //set to trigger on rising edge | TCCR1B|=0x40; //set to trigger on rising edge | ||
- | if(!counter&0x80) //the lock bit isn't set, so we are free to run | + | if(!(counter&0x80)) //the lock bit isn't set, so we are free to run |
{ | { | ||
- | diff=ICP1-start; //set the global volatile u16 diff | + | diff=ICR1; //set the global volatile s16 diff |
- | if(start>ICP1) //our pwm pulse spans a timer overflow | + | if(start>diff) //our pwm pulse spans a timer overflow |
{ | { | ||
diff+=TOP_COUNT; | diff+=TOP_COUNT; | ||
} | } | ||
+ | diff-=start; | ||
if(diff>PULSE_MIN && diff<PULSE_MAX) //test against criterion | if(diff>PULSE_MIN && diff<PULSE_MAX) //test against criterion | ||
{ | { | ||
- | if(counter&0xEF<30) //30 consecutive pulses | + | if((counter&(~0x80))<30) //30 consecutive pulses |
{ | { | ||
- | counter+=3; //the 20ms timer1 overflow subtracts 2 from counter | + | counter+=3; //the 20ms timer1 overflow subtracts 2 from counter |
} | } | ||
} | } | ||
else | else | ||
{ | { | ||
- | counter&=0xEF; //set the last 7 bits to zero | + | counter&=0x80; //set the last 7 bits to zero |
} | } | ||
} | } | ||
} | } | ||
} | } | ||
+ | |||
+ | void run_ground_control() | ||
+ | { | ||
+ | if((~0x80&counter)>=28) | ||
+ | { | ||
+ | counter|=0x80; //lock the diff variable using the counter flag bit | ||
+ | OCR1B=diff; | ||
+ | counter&=~0x80; | ||
+ | GROUND_LED_ON; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | GROUND_LED_OFF; | ||
+ | } | ||
+ | if(counter&~0x80) //if the counter variable >0, decrement by 2 | ||
+ | counter-=2; | ||
+ | } | ||
+ | |||
+ | void enable_ground_control() | ||
+ | { | ||
+ | TIMSK1|=(1<<ICIE1); | ||
+ | counter=0; | ||
+ | } | ||
+ | |||
+ | void disable_ground_control() | ||
+ | { | ||
+ | TIMSK1&=~(1<<ICIE1); | ||
+ | GROUND_LED_OFF; | ||
+ | counter=0; | ||
+ | diff=0; | ||
+ | } | ||
+ | #endif | ||
</code> | </code> | ||