1

I am using an Atmega16 to control a LED with an ultrasonic sensor. Basically the LED turns on if the distance is smaller than 100cm and otherwise it turns off.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>


#define  Trigger_pin PA0

volatile int TimerOverflow = 0;


ISR(TIMER1_OVF_vect)
{
    TimerOverflow++;
}

int main(void)
{
    char string[10];
    long count;
    double distance;
    
    DDRA = 0x01;

    DDRB = 0x01;

    sei();              
    TIMSK = (1 << TOIE1);
    TCCR1A = 0x00;              

    while(1)
    {

        PORTA |= (1 << Trigger_pin);
        _delay_us(10);
        PORTA &= (~(1 << Trigger_pin));
        
        TCNT1 = 0;          
        TCCR1B = 0x41;      
        TIFR = 1<<ICF1;     
        TIFR = 1<<TOV1;     
        
        
        while ((TIFR & (1 << ICF1)) == 0);  
        TCNT1 = 0;          
        TCCR1B = 0x01;      
        TIFR = 1<<ICF1;     
        TIFR = 1<<TOV1;     
        TimerOverflow = 0;  

        while ((TIFR & (1 << ICF1)) == 0); 
        count = ICR1 + (65535 * TimerOverflow); 
        
        distance = (double)count / 466.47;
        if (distance <= 100)
            PORTB |= (1<<0);
        else PORTB &= (~(1<<0));
        
        _delay_ms(200);
    }
}

The thing is I'll have to use an Atmega328p for my project. Because the 328p does not have a PORTA I changed my code to:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>

#define  Trigger_pin 0
volatile int TimerOverflow = 0;
ISR(TIMER1_OVF_vect)
{
    TimerOverflow++;
}

int main(void)
{
    long count;
    double distance;
    
    DDRB = 0b00000011;
    sei();
    TIMSK1 = (1 << TOIE1);
    TCCR1A = 0;

    

    while(1)
    {
        PORTB |= (1 << 0);
        _delay_us(10);
        PORTB &= (~(1 << 0));
        
        TCNT1 = 0;
        TCCR1B = 0x41;
        TIFR1 = 1<<ICF1;
        TIFR1 = 1<<TOV1;
        
        while ((TIFR1 & (1 << ICF1)) == 0);
        TCNT1 = 0;
        TCCR1B = 0x01;
        TIFR1 = 1<<ICF1;
        TIFR1 = 1<<TOV1;
        TimerOverflow = 0;


        while ((TIFR1 & (1 << ICF1)) == 0);
        count = ICR1 + (65535 * TimerOverflow);
        distance = (double)count / 466.47;
        if (distance < 100)
        PORTB |= (1<<1);
        else PORTB &= (~(1<<1));
        _delay_ms(200);
    }
}

I am using Proteus for simulation and I get the right distance in Simulation Log, but the LED connected to pin 1 of the B port stays off. What might be the problem? The pin configuration looks good and I followed the same logic as before.

Khenan
  • 11
  • 1
  • How many owerflows do you have? But anyway, it's nice the count is long, but ICR1 is int, 65535 is int, TimerOverflow is int, so it'll overflow into int and then it's promoted to long by assigment. – KIIV Apr 19 '21 at 21:55

0 Answers0