Advertisement
MagnusArias

AVR | HC-SR04 v1

Mar 21st, 2017
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.45 KB | None | 0 0
  1. //#define F_CPU 8000000UL
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #include <stdlib.h>
  5. #include <util/delay.h>
  6. #include <util/atomic.h>
  7. #include "HD44780.h"
  8.  
  9. //#define HARDWARE_TRIG /* If using software trigger comment this line */
  10.  
  11. #ifndef HARDWARE_TRIG
  12.     #define SOFTWARE_TRIG
  13. #endif
  14.  
  15. #define TRIG_SET (PORTC |= (1<<PC4))
  16. #define TRIG_CLR (PORTC &= ~(1<<PC4))
  17.  
  18. volatile unsigned char succeed_flag = 0;
  19. volatile unsigned int count = 0, newcount = 0;
  20.  
  21. volatile enum {DATA_OLD, DATA_FRESH, DATA_BAD} FreshData;
  22. volatile enum {STATE_FREE, STATE_BUSY} ConversionState;
  23. volatile uint16_t length;
  24. char buffer[4];
  25.  
  26. void Init(void);
  27.  
  28. #ifdef SOFTWARE_TRIG
  29.     void Trigger(void);
  30. #endif /* SOFTWARE_TRIG */
  31.  
  32.  
  33. int main(void)
  34. {
  35.     Init();
  36.     sei();      
  37.    
  38.     while (1)
  39.     {
  40.         if (FreshData == DATA_FRESH)
  41.         {
  42.             ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
  43.             {
  44.                 itoa( length/10, buffer, 10);
  45.                 LCD_WriteText(buffer);
  46.                 _delay_ms(40);
  47.                 LCD_Clear();
  48.             }
  49.             FreshData = DATA_OLD;
  50.         }
  51.     }
  52.    
  53.     return 0;
  54. }
  55.  
  56. ISR(TIMER2_COMP_vect)
  57. {
  58.     static uint8_t cnt=0;
  59.     cnt++;
  60.     if (cnt==4 && ConversionState==STATE_FREE)
  61.     {
  62.         #ifdef HARDWARE_TRIG //trigger measurement by hardware - Timer1 CTC Mode
  63.             TCCR1B |= 1<<WGM12; //CTC mode
  64.             TRIG_SET;
  65.             TCNT1 = 0; //reset Timer1
  66.             TIFR |= 1<<OCF1A; //clear any previous interrupt flag
  67.             TIMSK |= 1<<OCIE1A; //Output Compare A Match Interrupt Enable
  68.         #endif
  69.        
  70.         #ifdef SOFTWARE_TRIG
  71.             Trigger(); //trigger measurement
  72.         #endif
  73.        
  74.         cnt=0;
  75.     } else if(cnt==4) //after 4 ticks (64ms) still ConversionState=BUSY_STATE ---> it means timeout condition
  76.     {
  77.         cnt=0;
  78.         FreshData=DATA_BAD;
  79.     }
  80. }
  81.  
  82. ISR(TIMER1_CAPT_vect)//interrupt frequency = 2MHZ (F_CPU=16MHZ / prescaler=8), 1 tick every 0,5us
  83. {
  84.     if( (TCCR1B & (1<<ICES1)) ) //if rising edge
  85.     {
  86.         TCNT1 = 0; //reset counter
  87.         TCCR1B &= ~(1<<ICES1); //set falling edge trigger
  88.         ConversionState = STATE_BUSY;
  89.     }
  90.     else //falling edge
  91.     {
  92.         if (FreshData != DATA_BAD) //if timeout condition has not occurred
  93.         {
  94.             length = ICR1/2; //length reading (1 tick=0,5us -> 200=100us  therefore divided by 2)
  95.             FreshData = DATA_FRESH; //set marker, reseted after sending data in main function
  96.         }
  97.         else FreshData = DATA_OLD; //next cycle after timeout will be handled correctly
  98.        
  99.         TCCR1B |= (1<<ICES1); //set rising edge trigger
  100.         ConversionState = STATE_FREE;
  101.     }
  102. }
  103.  
  104.  
  105. void Init(void)  //ultrasonic  initialization
  106. {
  107.     /*  Trigger configuration   */
  108.     DDRC |= (1 << PC4);
  109.     TRIG_CLR;
  110.    
  111.     /*  Timer0 configuration    */
  112.     TCCR2 |= (1 << WGM21 | 1 << CS22 | 1 << CS20);  //CTC mode, prescaler=1024
  113.     TIMSK |= (1 << OCIE2); //Output compare match interrupt enable
  114.     OCR2 = 249; //(FCPU=16000000)/(prescaler=1024)/(OCR0+1=250)=62,5 ticks per second (every 16ms)
  115.    
  116.     /* Timer1 configuration */
  117.     TCCR1B |= (1 << ICES1); //set rising edge
  118.     TCCR1B |= (1 << CS11); //prescaler=8
  119.     TIMSK |=  (1 << TICIE1); //Timer1 Capture Interrupt Enable
  120.    
  121.     #ifdef HARDWARE_TRIG
  122.         TCCR1B |= (1 << WGM12);
  123.         OCR1A = 19; // 19 + 1 cycles = 10us (1 tick=0,5us)
  124.     #endif
  125.    
  126.     LCD_Initalize();
  127.     LCD_Clear();
  128. }
  129.  
  130. #ifdef HARDWARE_TRIG
  131.     ISR(TIMER1_COMPA_vect)/* interrupt occurs after 10us */
  132.     {
  133.         TRIG_CLR;  //end trigger signal
  134.         TIMSK &= ~(1<<OCIE1A); //Output Compare A Match Interrupt Disable
  135.         TCCR1B &= ~(1<<WGM12); //CTC mode disabled
  136.     }
  137. #endif /* HARDWARE_TRIG */
  138.  
  139. #ifdef SOFTWARE_TRIG
  140.     void Trigger(void)
  141.     {
  142.         TRIG_SET;
  143.         _delay_us(10);
  144.         TRIG_CLR;
  145.     }
  146. #endif /* SOFTWARE_TRIG */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement