Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#define F_CPU 8000000UL
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <stdlib.h>
- #include <util/delay.h>
- #include <util/atomic.h>
- #include "HD44780.h"
- //#define HARDWARE_TRIG /* If using software trigger comment this line */
- #ifndef HARDWARE_TRIG
- #define SOFTWARE_TRIG
- #endif
- #define TRIG_SET (PORTC |= (1<<PC4))
- #define TRIG_CLR (PORTC &= ~(1<<PC4))
- volatile unsigned char succeed_flag = 0;
- volatile unsigned int count = 0, newcount = 0;
- volatile enum {DATA_OLD, DATA_FRESH, DATA_BAD} FreshData;
- volatile enum {STATE_FREE, STATE_BUSY} ConversionState;
- volatile uint16_t length;
- char buffer[4];
- void Init(void);
- #ifdef SOFTWARE_TRIG
- void Trigger(void);
- #endif /* SOFTWARE_TRIG */
- int main(void)
- {
- Init();
- sei();
- while (1)
- {
- if (FreshData == DATA_FRESH)
- {
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
- {
- itoa( length/10, buffer, 10);
- LCD_WriteText(buffer);
- _delay_ms(40);
- LCD_Clear();
- }
- FreshData = DATA_OLD;
- }
- }
- return 0;
- }
- ISR(TIMER2_COMP_vect)
- {
- static uint8_t cnt=0;
- cnt++;
- if (cnt==4 && ConversionState==STATE_FREE)
- {
- #ifdef HARDWARE_TRIG //trigger measurement by hardware - Timer1 CTC Mode
- TCCR1B |= 1<<WGM12; //CTC mode
- TRIG_SET;
- TCNT1 = 0; //reset Timer1
- TIFR |= 1<<OCF1A; //clear any previous interrupt flag
- TIMSK |= 1<<OCIE1A; //Output Compare A Match Interrupt Enable
- #endif
- #ifdef SOFTWARE_TRIG
- Trigger(); //trigger measurement
- #endif
- cnt=0;
- } else if(cnt==4) //after 4 ticks (64ms) still ConversionState=BUSY_STATE ---> it means timeout condition
- {
- cnt=0;
- FreshData=DATA_BAD;
- }
- }
- ISR(TIMER1_CAPT_vect)//interrupt frequency = 2MHZ (F_CPU=16MHZ / prescaler=8), 1 tick every 0,5us
- {
- if( (TCCR1B & (1<<ICES1)) ) //if rising edge
- {
- TCNT1 = 0; //reset counter
- TCCR1B &= ~(1<<ICES1); //set falling edge trigger
- ConversionState = STATE_BUSY;
- }
- else //falling edge
- {
- if (FreshData != DATA_BAD) //if timeout condition has not occurred
- {
- length = ICR1/2; //length reading (1 tick=0,5us -> 200=100us therefore divided by 2)
- FreshData = DATA_FRESH; //set marker, reseted after sending data in main function
- }
- else FreshData = DATA_OLD; //next cycle after timeout will be handled correctly
- TCCR1B |= (1<<ICES1); //set rising edge trigger
- ConversionState = STATE_FREE;
- }
- }
- void Init(void) //ultrasonic initialization
- {
- /* Trigger configuration */
- DDRC |= (1 << PC4);
- TRIG_CLR;
- /* Timer0 configuration */
- TCCR2 |= (1 << WGM21 | 1 << CS22 | 1 << CS20); //CTC mode, prescaler=1024
- TIMSK |= (1 << OCIE2); //Output compare match interrupt enable
- OCR2 = 249; //(FCPU=16000000)/(prescaler=1024)/(OCR0+1=250)=62,5 ticks per second (every 16ms)
- /* Timer1 configuration */
- TCCR1B |= (1 << ICES1); //set rising edge
- TCCR1B |= (1 << CS11); //prescaler=8
- TIMSK |= (1 << TICIE1); //Timer1 Capture Interrupt Enable
- #ifdef HARDWARE_TRIG
- TCCR1B |= (1 << WGM12);
- OCR1A = 19; // 19 + 1 cycles = 10us (1 tick=0,5us)
- #endif
- LCD_Initalize();
- LCD_Clear();
- }
- #ifdef HARDWARE_TRIG
- ISR(TIMER1_COMPA_vect)/* interrupt occurs after 10us */
- {
- TRIG_CLR; //end trigger signal
- TIMSK &= ~(1<<OCIE1A); //Output Compare A Match Interrupt Disable
- TCCR1B &= ~(1<<WGM12); //CTC mode disabled
- }
- #endif /* HARDWARE_TRIG */
- #ifdef SOFTWARE_TRIG
- void Trigger(void)
- {
- TRIG_SET;
- _delay_us(10);
- TRIG_CLR;
- }
- #endif /* SOFTWARE_TRIG */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement