Como funciona?
Olá, hoje vou trazer um projeto completo e funcional de uma discadora para alarmes
usando a discagem por pulsos,o funcionamento é bem simples basta deixar o jumper (ou uma chave on/off) fechado para configurar os telefones a serem discados e com a chave aberta ao energizar o circuito ele já inicia a discagem(após 5s). assim basta ligar a alimentação do circuito a saida da sirene(que geralmente é 12V).Para configurar os telefones basta deixar o jumper fechado e enviar pela serial do seu pc (lembre se de usar o ci max 232,para não queimar os pinos de comunicação do seu microcontrolador) um comando com a seguinte formatação "<" + "memoria" + "digitos do telefone" + ">",onde "memoria" é o numero do registro (no máximo 3 registros) e os digitos é o numero do telefone(maximo de 15 digitos ).Por exemplo vamos supor que vc queira liguar para três numeros '111','222' e '333'então basta enviar os comandos "<0111>","<1222>" e "<2333>", mas se vc quer apenas 2 telefones faça assim: "<0111>","<1222>" e "<2>",então o circuito só vai ligar para 111 e 222.
usando a discagem por pulsos,o funcionamento é bem simples basta deixar o jumper (ou uma chave on/off) fechado para configurar os telefones a serem discados e com a chave aberta ao energizar o circuito ele já inicia a discagem(após 5s). assim basta ligar a alimentação do circuito a saida da sirene(que geralmente é 12V).Para configurar os telefones basta deixar o jumper fechado e enviar pela serial do seu pc (lembre se de usar o ci max 232,para não queimar os pinos de comunicação do seu microcontrolador) um comando com a seguinte formatação "<" + "memoria" + "digitos do telefone" + ">",onde "memoria" é o numero do registro (no máximo 3 registros) e os digitos é o numero do telefone(maximo de 15 digitos ).Por exemplo vamos supor que vc queira liguar para três numeros '111','222' e '333'então basta enviar os comandos "<0111>","<1222>" e "<2333>", mas se vc quer apenas 2 telefones faça assim: "<0111>","<1222>" e "<2>",então o circuito só vai ligar para 111 e 222.
O esquemático:
O circuito de simulação:
O código fonte:
/*
* Discadora simples configurada via porta serial
* Version : 1.0
* microcontrolador : AVR ATMega328
* descrição : discadora por pulso(apenas liga não toca som), liga para 3 numeros
* criado: 08/04/2013
* autor: aguivone moretti fogia
*/
#define F_CPU 20000000 // 20 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/eeprom.h>//usado para acessar memoria
//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
#define PULSO PB0 //no rele de discagem deve ser colocado um resistor de 470R para não curto circuitar a linha telefonica
#define LED PB2 //led piscante
int tel_num[3][15];//matriz pra guardar os numeros dos telefones
int disparo = 0;
int tempo_led = 0;
//variaveis para RS-232
unsigned char caracter; //usado para pegar o caracter que chega pela serial
int tam_buffer; //usado para contar o tamanho do buffer de recepção
volatile char rec_buffer ='S'; //usado para notificar que chegou dados
char buffer_serial[17]; //buffer da serial,tamanho máximo de 17 caracter
///////////////////////////////////////////////funçoes usadas pela usart////////////////////////////////////////////////
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;
/* habilita receiver and transmitter buffers */
UBRR0H = (unsigned char)(velocidade>>8);
UBRR0L = (unsigned char)velocidade;
UCSR0B = 0X98;//deve se habilitar somente a interrupção de recepção para não travar o microcontrolador
/* 8 bits , 1 stop bit, assincrono , sem paridade,modo nornal */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void escreve_caracter(unsigned char carac)//adaptado para funcionar com RS485
{
_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
}
//////////////////////////interrupções requerida para usar a recepção serial///////////////////////////////////
ISR(USART_RX_vect)//aqui pega os dados da serial
{
caracter = (char)UDR0;
if(caracter == '>')
{
if(tam_buffer<17)//max do buffer/maximo de digitos 17
{
buffer_serial[tam_buffer]=caracter;
tam_buffer++;
rec_buffer ='F';
buffer_serial[tam_buffer]='\0';
}
else
{
rec_buffer ='E';//tamanhoa incompativel
}
}
else
{
if(rec_buffer == 'I')
{
buffer_serial[tam_buffer]=caracter;
tam_buffer++;
}
}
if(caracter == '<')//inicia a captura dos numeros do telefone
{
rec_buffer ='I';
buffer_serial[0]='<';
tam_buffer=1;
}
}
void numero(int valor)// função usada para fazer a discagem
{
int xis=0;
while(xis < valor)
{
desliga_pino(PORTB,PULSO);
_delay_ms(35);
liga_pino(PORTB,PULSO);
_delay_ms(65);
xis++;
}
_delay_ms(400);//tempo necessario entre cada digito
}
int char_to_int(char valor,int seleciona)//seleciona entre numero e pulsos
{//converte caracter para numero
int retorno = 100;//se retornar 100 é porque deu erro
switch(valor)
{
case '0':
{
if(seleciona == 1)
{
retorno = 10;//nos pulsos 10 = 0
}
else
{
retorno = 0;
}
}break;
case '1':
{
retorno = 1;
}break;
case '2':
{
retorno = 2;
}break;
case '3':
{
retorno = 3;
}break;
case '4':
{
retorno = 4;
}break;
case '5':
{
retorno = 5;
}break;
case '6':
{
retorno = 6;
}break;
case '7':
{
retorno = 7;
}break;
case '8':
{
retorno = 8;
}break;
case '9':
{
retorno = 9;
}break;
case '*':
{
retorno = 11;
}break;
case '#':
{
retorno = 12;
}break;
}
return(retorno);
}
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
DDRB = 0XFF; //inicializa portB como saida;
DDRD = 0X02; //inicializa portD como entrada e D1 como saida;
desliga_pino(PORTB,PULSO);//rele de discagem
RS232_inicializa(9600);//inicializa serial com a velocidae de 9600bps
sei();//habilita interrupções
char gravado = 'n';
_delay_ms(500);//espera estabilizar a tensão
_EEGET(gravado,50);//pega valor da posição de memoria 50
if(gravado == 'G')//memoria já foi gravado alguma vez
{
int x = 0;
while(x<3)
{
int posi = x*15;//pega posição inicial
int y=0;
while(y < 15 )
{
_EEGET(tel_num[x][y],posi); //pega valores da memoria eeprom
y++;
posi++;
}
x++;
}
}
for(;;)
{
if(estado_pino(PIND,2))//checa pra ver se modo discadora habilitado
{//se estiver no modo discadora nem chega a serial para evitar que ruidos apague os dados
if(disparo < 2)//aqui define quantas vezes o circuito vai repetir as chamadas
{
int nume=0;
while(nume<3)
{
_delay_ms(5000);//espera 5s antes de discar pois pode ter sido só um bip do alarme ; comentar na simulação pois leva muito tempo
alterna_pino(PORTB,LED);
int digito = 0;
liga_pino(PORTB,PULSO);
_delay_ms(200); //espera para dar linha para discar
while((digito<15)&&(tel_num[nume][digito]!= 100)&&(tel_num[nume][digito] != 0))//se maior que 15 e se valor null ou '>' manda parar
{
numero(tel_num[nume][digito]);//disca numero
escreve_caracter(tel_num[nume][digito] + '0'); //escreve o digito na serial
digito++;
}
alterna_pino(PORTB,LED);
_delay_ms(20000);//tempo de chamada //comentar na simulação pois leva muito tempo
desliga_pino(PORTB,PULSO);
escreve_caracter('\n'); //pula linha
escreve_caracter('\r'); //retorna a linha inicial
nume++;
}
disparo++;
}
}
else
{
if(rec_buffer == 'F')//tem dados pra ler na serial.
{
int xis=255;
xis = char_to_int(buffer_serial[1],0);
if(xis < 3)//vetor valido
{
xis = 2;
while(xis<tam_buffer)
{//tem que converte para char
tel_num[char_to_int(buffer_serial[1],0)][xis-2] = char_to_int(buffer_serial[xis],1);//copia e já converte em numero e pulsos
_EEPUT(((xis-2) +(char_to_int(buffer_serial[1],0)*15) ),tel_num[char_to_int(buffer_serial[1],0)][xis-2] );//endereço/dado para memoria
xis++;
}
_EEPUT(((xis-2) +(char_to_int(buffer_serial[1],0)*15) ),100);
escreve_caracter('O');//ok dados gravados
_EEPUT(50,'G');
}
else
{
escreve_caracter('F');//dados invalidos
}
rec_buffer ='S';//indica que foi lido
}
}
tempo_led++;
if(tempo_led > 20000)//tempo do led piscar
{
alterna_pino(PORTB,LED);
tempo_led = 0;
}
}//for infinito
}//main
até a próxima veja também a pagina no face : busque pelo perfil "Microcontroladores-C"
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!