/*
* usando o sensor ultrassônico HC-SR04
* Version : 1
* microcontrolador : AVR ATMega328
* descrição : medir distancia com o modulo HC-SRO4
* criado: 13/08/2013
* autor: aguivone moretti fogia
*/
/////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#define F_CPU 16000000UL // 16MHz deve vir antes da funcão de delay
#include <util/delay.h>
#include <string.h>
#include <avr/eeprom.h>//usado para acessar memoria
////////////////////////////parametros///////////////////////////////////
//funçoes basicas dos pinos
#define alterna_pino(x,y) x ^= _BV(y)
#define liga_pino(x,y) x |= _BV(y)
#define desliga_pino(x,y) x &= ~(_BV(y))
#define estado_pino(x,y) ((x & _BV(y)) == _BV(y)) //o pino deve estar como entrada ,testa se está em nivel logico 1
//configurando os pinos/////////////////////////////////////////////////
#define TRIGGER PB2 //no rele de discagem deve ser colocado um resistor de 470R para não curto circuitar a linha telefonica
#define LED PB3
//variaveis usadas/////////////////////////////////////////////////////
long distancia_cm= 0;
///////////////////////////funçoes auxiliares//////////////////////////
void delay_ms(long conta)
{
long valor=0;
while(valor<conta)
{
_delay_us(999);// 1ms
valor++;
}
}
void RS232_inicializa(unsigned int BAUD)
{
unsigned int velocidade = F_CPU/16/BAUD-1;
// veja que na simulação do proteus dá erros nas velocidade diferentes de 9600 mas na pratica funciona.
UCSR0A = 0X20;
UBRR0H = (unsigned char)(velocidade>>8);
UBRR0L = (unsigned char)velocidade;
UCSR0B = 0X18;//não vou habilitar nenhuma interrupção da porta serial
/* 8 bits , 1 stop bit, assincrono , sem paridade,modo nornal */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void escreve_caracter(unsigned char carac)
{
_delay_loop_1(1);//tempo para estabilizar tensão
while ( !( UCSR0A & (1<<UDRE0)) ); //espera transmitir para enviar um novo
UDR0 = carac;
while ( !( UCSR0A & (1<<UDRE0)) ); //espera transmitir desabilita a transmissão
_delay_loop_1(1);//tempo para garantir o envio
}
void impri_serial(const char frase[20])
{
unsigned int indice=0;
unsigned int tamanho = strlen(frase);
while(indice<=tamanho)///veja que o programa pode travar se aqui não tiver as duas aspas
{
escreve_caracter(frase[indice]);
indice++;
}
}
void int_to_char(long quant)
{
char convert_char1='0';
char convert_char2='0';
char convert_char3='0';
char convert_char4='0';
while(quant>=1000)
{
quant=quant-1000;
convert_char1++;
}
while(quant>=100)
{
quant=quant-100;
convert_char2++;
}
while(quant>=10)
{
quant=quant-10;
convert_char3++;
}
while(quant>=1)
{
quant=quant-1;
convert_char4++;
}
escreve_caracter(convert_char1);
escreve_caracter(convert_char2);
escreve_caracter(convert_char3);
escreve_caracter(convert_char4);
impri_serial("- \n\r");
}
int main(void)
{
DDRB = 0XFE; //inicializa portC,como saida exceto B0 - usado para icp1
DDRC = 0X00; //inicializa portC,como entrada
DDRD = 0XF6; //inicializa portD como Saida exceto pd0 e d3;
liga_pino(PORTB,TRIGGER);
RS232_inicializa(9600);
impri_serial("Sensor de distancia ultrassonica! \n\r");
sei();
long tempo;
for(;;)
{
desliga_pino(PORTB,LED);
tempo = 0;
desliga_pino(PORTB,TRIGGER);
_delay_us(20);//20us necessario para gerar os pulsos
liga_pino(PORTB,TRIGGER);
while(estado_pino(PINB,PB0)==0);//espera o pino ir para nivel alto
while(estado_pino(PINB,PB0)==1)//espera o pino ir para nivel baixo
{distancia_cm++;}
//de forma empirica verifiquei que 1cm = 30unidades de contagem(aproximadamente)
distancia_cm = distancia_cm/30;
int_to_char(distancia_cm);///envia valor para porta serial
desliga_pino(PORTB,LED);
delay_ms(1000);//espera 1s para ler novo valor
//(no datasheet eles alertam que este tempo não pode ser menor que 60ms para não pegar ecos falsos)
}//fim do for
}//fim do main