Advertisement
Regeneric

AVR Hall Sensor

Jan 29th, 2021
661
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.94 KB | None | 0 0
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/pgmspace.h>
  4. // #include <avr/eeprom.h>
  5.  
  6. #include <util/delay.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <math.h>
  10.  
  11. #include "lcd.h"
  12. // #include "spi.h"
  13.  
  14.  
  15. #define clockCyclesToMicroseconds(a) (((a) * 1000L)/(F_CPU / 1000L))
  16. #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
  17. #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
  18. #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000)>>3)
  19. #define FRACT_MAX (1000>>3)
  20.  
  21.  
  22. volatile float value = .0, rev = .0, last = .0;
  23. volatile uint16_t rpm = 0, count = 0;
  24. volatile uint16_t oldTime = 0, time = 0;
  25. volatile uint8_t counter = 0;
  26.  
  27.  
  28. volatile unsigned long int timer0_overflowCount = 0;
  29. volatile unsigned long int timer0_millis = 0;
  30. static unsigned char timer0_fract = 0;
  31. unsigned long int starttime = 0, endtime = 0;
  32.  
  33. unsigned long int millis() {
  34.     unsigned long int m = 0;
  35.     uint8_t oldSREG = SREG;
  36.  
  37.     // Disable interrupts while we read timer0_millis or we might get an
  38.     // Inconsistent value (e.g. in the middle of a write to timer0_millis)
  39.     cli();
  40.     m = timer0_millis;
  41.     SREG = oldSREG;
  42.     return m;
  43. }
  44.  
  45.  
  46. int main() {
  47.     // VSS signal, injector signal and navigation buttons - Atmega 8
  48.     DDRD &= ~((1<<PD3) | (1<<PD2));  // PD2/INT0 and PD3/INT1 input
  49.     PORTD |= ((1<<PD3) | (1<<PD2));  // PD2/INT0 and PD3/INT1 internal pull-up resistor
  50.  
  51.     MCUCR |= ((1<<ISC01) | (1<<ISC00));  // RISING edge of INT0 generates interrupt
  52.     GICR |= (1<<INT0);
  53.  
  54.  
  55.     // 16 bit timer for VSS
  56.     TCCR1A = 0;  // Timer1 normal mode
  57.     TCCR1B |= ((1<<CS10) | (1<<CS11));  // Prescaler 64, causes overflow every 0.524288 (8 MHz crystal, 0.262144s for 16 MHz)
  58.     TCNT1 = 34286;  // Counts from 34286 to 65535 - causes overflow every 0.25s (8 MHz crystal, 3036 for 16 MHz)
  59.  
  60.     // Counter for millis() function
  61.     TCCR0 |= ((1<<CS01) | (1<<CS00));  // Prescaler 64
  62.     TCNT0 = 0;  // Counts from 0 to 255;
  63.  
  64.     // Enable timer overflow interrupt
  65.     TIMSK = ((1<<TOIE1) | (1<<TOIE0));
  66.  
  67.  
  68.     char buffer[16];
  69.     LCD.init();
  70.  
  71.     sei();  // Enable global interrupts
  72.     while(1) {
  73.         LCD.cursor(1, 1);
  74.         LCD.sends("RPM: ", 1); LCD.sends(itoa(rpm, buffer, 10), 1);
  75.  
  76.         LCD.render();
  77.         LCD.clear();
  78.     } return 0;
  79. }
  80.  
  81.  
  82. ISR(TIMER0_OVF_vect) {
  83.     unsigned long int m = timer0_millis;
  84.     unsigned char f = timer0_fract;
  85.  
  86.     m += MILLIS_INC;
  87.     f += FRACT_INC;
  88.     if(f >= FRACT_MAX) {
  89.         f -= FRACT_MAX;
  90.         m += 1;
  91.     }
  92.  
  93.     timer0_fract = f;
  94.     timer0_millis = m;
  95.     timer0_overflowCount++;
  96. }
  97.  
  98. ISR(TIMER1_OVF_vect) {
  99.     counter++;
  100.  
  101.     if(counter > 3) {
  102.         cli();
  103.         time = millis()-oldTime;
  104.         rpm = (rev/time)*60000;
  105.         oldTime = millis();
  106.         rev = 0;
  107.         sei();
  108.     } TCNT1 = 34286;
  109.     last = rev;
  110. }
  111.  
  112.  
  113. // Hall signal interrupt
  114. ISR(INT0_vect) {
  115.     rev++;
  116.     count++;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement