This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Distance measurement by ARM1176JZF-S(DS- 5 TOOLS) using ultrasonic sensor

I have to measure distance between an object by ARM1176JZF-S(DS- 5 TOOLS) using ultrasonic sensor. I am not being able to write the codes. I have connected the ultrasonic sensor in the GPIO pins PL061 peripheral bock (j39). Please help me write the codes.

Header file and sample program of ultrasonic distance measuring sensor for mbed is given in HCSR04 - a mercurial repository | mbed       and another of ATMega 16 http://www.robokits.co.in/documentation/Ultrasonic%20distance%20sensor.pdf

(
#include "hcsr04.h"


HCSR04::HCSR04(PinName TrigPin,PinName EchoPin):
    trigger(TrigPin), echo(EchoPin)
{
    pulsetime.stop();
    pulsetime.reset();
    echo.rise(this,&HCSR04::isr_rise);
    echo.fall(this,&HCSR04::isr_fall);
    trigger=0;
}

HCSR04::~HCSR04()
{
}

void HCSR04::isr_rise(void)
{
    pulsetime.start();
}
void HCSR04::start(void)
{
    trigger=1;
    wait_us(10);
    trigger=0;
}

void HCSR04::isr_fall(void)
{
    pulsetime.stop();
    pulsedur = pulsetime.read_us();
    distance= (pulsedur*343)/20000;
    pulsetime.reset();
}

void HCSR04::rise (void (*fptr)(void))
{
    echo.rise(fptr);
}
void HCSR04::fall (void (*fptr)(void))
{
    echo.fall(fptr);
}

unsigned int HCSR04::get_dist_cm()
{
    return distance;
}
unsigned int HCSR04::get_pulse_us()
{
    return pulsedur;
}
Here is a sample code usage
*********************************************************
#include "hcsr04.h"
HCSR04  usensor(p25,p6);
int main()
{
    unsigned char count=0;
    while(1) {
        usensor.start();
        wait_ms(500);
        dist=usensor.get_dist_cm();
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("cm:%ld",dist );

        count++;
        lcd.locate(0,1);
        lcd.printf("Distance =%d",count);
     
    }
}
)


http://www.robokits.co.in/documentation/Ultrasonic%20distance%20sensor.pdf

(

Sample Program for ATMega16
Connections:
VCC - +5VDC
Trig – PA.6 on ATmega16
Echo – PA.7 on ATMega16
GND – GND
ATMega16 running at 16Mhz


char timer0counter;
void main()
{
char buffer[10];
float range;
sei(); //Enable global interrupt
sbi(DDRA,6); //Set pin as output
cbi(DDRA,7); //Set pin as input
while(1)
{
sbi(PORTA,6); //Send Trigger
DELAYUS(10);
cbi(PORTA,6); //Send trigger
http://www.robokits.co.in
http://www.robokitsworld.com Page 4
Ultrasonic Distance Measurement Sensor 4M [RKI-1540]
timer0counter=0;
TCNT0=0; //Clear timer
while(bit_is_clear(PINA,7)); //Wait for rising edge
sbi(TCCR0,CS02); //Select prescalar 256
sbi(TIMSK,TOIE0); //Enable timer0 overflow interrupt
LCD_CLRSCR();
while(bit_is_set(PINA,7) && timer0counter<9) //wait for falling edge of echo
{
DELAYUS(5);
}
cbi(TCCR0,CS02); //Stop timer
cbi(TIMSK,TOIE0);
if(bit_is_set(PINA,7))
{
LCD_PRINT("No OBSTACLE");
}
else
{
range=(256*timer0counter+TCNT0)*16*0.017; //range conversion
itoa(range,buffer,10);
LCD_PRINT(buffer);
UART_PRINT(buffer);
UART_PRINT("\n\r");
}
DELAYMS(100);
}
}
SIGNAL(SIG_OVERFLOW0)
{
cbi(TIMSK,TOIE0);
TCNT0=0;
timer0counter++;
UART_PUTCHAR(timer0counter);
sbi(TIMSK,TOIE0);
if(timer0counter>8)
{
cbi(TCCR0,CS02);
cbi(TIMSK,TOIE0}}
)




Parents
  • Hi Albert,

    You will need to read the manual for the PL061 peripheral itself to work out how to drive the register interface correctly - it is not a simple as just writing to the base address. You're currently just writing to the base address of a multi-register interface, but the address masking functionality of the peripheral means that this doesn't actually write any GPIO lines.

    TRM for PL061:

    In software mode (i.e. programming through the register interface), bits [9:2] of the address form an 8-bit mask, and only data values which are not masked take effect. In your case:

    0x1010A000=1;
    
    

    Bits [9:2] are all zero so nothing takes effect. (FWIW you are missing a * "points to operator, but I assume this is just a typo as the compiler would error otherwise).

    I _think_ the code below should clear all the GPIO pins (x3FC = an 8-bit mask of xFF), wait for that to complete, and then set GPIO[0] (x004 = an 8-bit mask of 0x01) to 1.

    *0x1010A3FC=0;
    dmb();
    *0x1010A004=1;
    
    

    Note that the data value you write is also an 8-bit on/off mask, not a binary on off for the bit you have selected. If you want to set GPIO[1] to 1 you would need.

    *0x1010A008=2;
    
    

    I'm not 100% sure this works - I don't have access to one of these boards, so just going by the manual. P.S. you may need to mark up the pointers as volatile, or there is a risk the compiler optimizes them out.

    *((volatile unsigned int*)0x1010A008)=2;

    HTH,

    Pete

Reply
  • Hi Albert,

    You will need to read the manual for the PL061 peripheral itself to work out how to drive the register interface correctly - it is not a simple as just writing to the base address. You're currently just writing to the base address of a multi-register interface, but the address masking functionality of the peripheral means that this doesn't actually write any GPIO lines.

    TRM for PL061:

    In software mode (i.e. programming through the register interface), bits [9:2] of the address form an 8-bit mask, and only data values which are not masked take effect. In your case:

    0x1010A000=1;
    
    

    Bits [9:2] are all zero so nothing takes effect. (FWIW you are missing a * "points to operator, but I assume this is just a typo as the compiler would error otherwise).

    I _think_ the code below should clear all the GPIO pins (x3FC = an 8-bit mask of xFF), wait for that to complete, and then set GPIO[0] (x004 = an 8-bit mask of 0x01) to 1.

    *0x1010A3FC=0;
    dmb();
    *0x1010A004=1;
    
    

    Note that the data value you write is also an 8-bit on/off mask, not a binary on off for the bit you have selected. If you want to set GPIO[1] to 1 you would need.

    *0x1010A008=2;
    
    

    I'm not 100% sure this works - I don't have access to one of these boards, so just going by the manual. P.S. you may need to mark up the pointers as volatile, or there is a risk the compiler optimizes them out.

    *((volatile unsigned int*)0x1010A008)=2;

    HTH,

    Pete

Children