Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.03 KB | None | 0 0
  1. #define F_CPU 16000000UL
  2. #include <avr/io.h>
  3. #include <util/delay.h>
  4. #include <avr/interrupt.h>
  5. #include <util/delay.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <avr/sfr_defs.h>
  9.  
  10. #define TRIGGER_PIN PB7 //PA0 dla echo, PB7 wbudowany led na arduino
  11. uint16_t Measurement;
  12. uint16_t Distance;
  13.  
  14. uint16_t Measure(void);
  15. uint16_t Calculation(uint16_t);
  16.  
  17. int main () //Temporary main for testing. In official version this file will be included in main.c
  18. {
  19.     DDRB |= (1 << TRIGGER_PIN); //Make trigger pin as output
  20.  
  21.     TIMSK4 = (1 << TOIE4);  //Enable Timer1 overflow interrupts
  22.     TCCR4B |= (1 << CS40); //Prescaler = 1
  23.  
  24.     sei(); //Enable global interrupt
  25.  
  26.     while(1) //Temporary while(1) in main for testing. In official version this file will be included in main.c
  27.     {
  28.         Measure(); //Calling a Measure function
  29.     }
  30. }
  31.  
  32. uint16_t Measure(void)
  33. {
  34.     //Giving 10us trigger pulse on trig pin to HC-SR04, then disabling it without making an interrupt
  35.  
  36.     /*
  37.      * TCNT4 - stores ticks that timer gets by clock ticking (divided by prescaler)
  38.      * PINx, x - A, B, C... - read a state of output (high/low)
  39.      *
  40.      * How we calculate a timer:
  41.      * - prescaler divided by clock (e.g. 1/16000000)
  42.      * - A) our sensor needs a 10us high output on trig pin,
  43.      * - B) then it's making x8 40kHz pulse and we're waiting for echo back - its from 150 us to 25 ms, 38ms if no obstacle
  44.      *
  45.      * A) To make 10us high output, we aren't using prescaler here, so 1/16000000 = 62.5 ns per tick -> 10us/62.5ns = 0.00001s/0.0000000625s = 160 ticks
  46.      * We need to count 160 ticks to get 10us. To avoid using an interruptions, we're not making a overflow (its 16bit timer - we can store 65536 ticks) nor using a CTC mode in timer.
  47.      * We're checking it by two if statements. Second if is inverse of first if.
  48.      * Below we're doing a part A).
  49.      */
  50.  
  51.     if ((TCNT4 == 160) && (~(PINB & (1 << PB7))))
  52.     {
  53.         PORTB ^= (1 << TRIGGER_PIN); //1 on trig pin of HC-SR04 - TRIGGER ENABLED
  54.         TCNT4 = 0; //Reseting Timer4 to 0
  55.     }
  56.  
  57.     //Timer is counting from 0 do 160 again
  58.  
  59.     if ((TCNT4 == 160) && (PINB & (1 << PB7)))
  60.     {
  61.         PORTB &= (~(1 << TRIGGER_PIN)); //0 on trig pin of HC-SR04 - TRIGGER DISABLED
  62.         TCNT4 = 0; //Reseting Timer4 to 0
  63.     }
  64.  
  65.     /*
  66.      * part B) - we're using here a CTC mode. We will use a prescaler 64.
  67.      * 64/16000000 = 0.000004 s = 4*10^-6 = 4 us
  68.      * We need to count minimum 150 us, so:
  69.      * 150us/0.000004s = 0.00015/0.000004 = 37.5
  70.      * We have a problem here, because its not an integer. If we use 38 ticks as 150us, in fact we will have 152 us (38*0.000004=152). We have a rounding error.
  71.      * To fix this, we must subtract a ticks from final result.
  72.      * We can calculate, how much we need to subtract:
  73.      * (38*0.000004) - (37.5*0.000004) = (152-150) = 2
  74.      *
  75.      * What if we have more than 150 us? Take 10ms = 0.01s as another example.
  76.      *
  77.      * HERE JAK TO PRZELICZYC DALEJ I NAPISA OGOLNY WZOR
  78.      *
  79.      *
  80.      * Final formula is:
  81.      *
  82.      *
  83.      */
  84.  
  85.  
  86.  
  87.  
  88.     return Measurement;
  89. }
  90.  
  91. uint16_t Calculation(uint16_t Measurement)
  92. {
  93.     Distance = Measurement/932.8;
  94.     return Distance;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement