quinta-feira, 7 de fevereiro de 2013

Gerando pwm usando o timer 2 do avr




//************************************************************************
//                               pwm usando o timer 2
//  microcontrolador    : AVR ATMega328p
//  Autor           : Aguivone 
//  data de criação     : 07/02/2013.
//
//************************************************************************
#define F_CPU 16000000UL  // 16 MHz deve vir antes das interrupçoes
#include <avr/io.h>

int main(void)
{
        DDRB = 0xFF;  //inicializa portB como saida
DDRD = 0xFF;  //inicializa portD como saida
TCCR2A = 0XA3;// configura pino B3 e D3 como saida pwm e modo fast PWM
        TCCR2B = 0X01;// sem divisão de prescaler
        OCR2A = 100;
OCR2B = 50;
           for(;;)
            {
             //faz nada!  
            }
}
/* para calcular a frequência no modo pwm do timer2
 sera :
          F = Fclock/N.128 (isso se deve ao fato de não estar usando o OCR2A conforme o datasheet especifica)
 onde N é o prescaler (ex.1,8...)*/

quarta-feira, 6 de fevereiro de 2013

PWM no modo 8bits, usando o timer1



//************************************************************************
//                            PWM USANDO O TIMER1 (MODO 8 BITS)
//  microcontrolador    : AVR ATMega328p
//  Autor           : Aguivone 
//  data de criação     : 06/02/2013.
//
//************************************************************************

#define F_CPU 16000000UL  // 16 MHz deve vir antes das interrupções
#include <avr/io.h>

int main(void)
{
         DDRB = 0xFF;  //inicializa portB como saidas
 TCCR1A = 0XA1;// configura pino B1 e B2 como saida(modo não inversor) e fast PWM
         TCCR1B = 0X09;// sem divisão de prescaler
         OCR1A = 100;//valor máximo é 255.
 OCR1B = 50;
           for(;;)
            {
             //faz nada!  
            }
}

/* para calcular a frequência no modo 8 bits
 sera :
          F = Fclock/N.128 (isso se deve ao fato de não estar usando o OCR2A conforme o datasheet especifica)
 onde N é o prescaler (ex.1,8...)*/

segunda-feira, 15 de outubro de 2012

Interface Ethernet com o ATmega328 (2)

Olá a todos que seguem meu blog hoje vou ensinar como estabelecer uma conexão Ethernet com o microcontrolador ATmega328,pra quem não viu em postagens anteriores coloquei um exemplo onde ele se comunica via modulo "wiz 810" fornecido aqui no brasil pela hitech, neste exemplo vou fazer a interface com o pc sem usar uma pagina html(como foi feito no primeiro exemplo),com isso se economiza memoria do microcontrolador.
 O primeiro passo é configurar a porta de rede de seu pc(como no meu pc tenho 2 portas eu fiz o seguinte; uma é a que me conecto a internet e a outra deixei para acessar minha placa) vale lembra que no exemplo eu uso a porta 5000 e o IP da placa é 192.168.0.5,mas no pc deve ficar assim:
isso pode ser acessado por meus locais de rede->exibir conexões de rede então clicando duas vezes abrirá uma janela pra configurar a porta Ethernet  indo na aba geral protocolo TCP/IP tem se acesso a propriedades de protocolo, deixe como na figura acima.

O código fonte :

//***********************************************************************************************************
//                             ethernet exemplo de uso para interface com pc
//  versão                        : 1.0
//  descrição                   : Enviando e recebendo dados pela ethernet
//  Autor                      : Aguivone
//  microcontrolador           : ATmega328 P
//  compilador                   : AVR-GCC / Atmel AVR Studio 4.17
//  Data do projeto            : 15 / 02 / 2012 - inicio.

//*************************************************************************************************************
#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>// AVRJazz Mega328 SPI I/O

////////////////////////funçoes auxiliares/////////////////////////////
#define liga_pino(x,y) x |= _BV(y)
#define desliga_pino(x,y) x &= ~(_BV(y))
#define alterna_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
/////////////////////////////////////////////////////////////////////////////////////////////
//configuração dos pinos SPI
#define SPI_PORT PORTB //porta que será usado para SPI
#define SPI_DDR  DDRB  
#define SPI_SS   PORTB2//seleção de chip(habilita comunicação SPI)
// Wiznet W5100 Op Code usados
#define WIZNET_ESCREVE_OPCODE 0xF0  
#define WIZNET_LER_OPCODE     0x0F
// Wiznet W5100 endereço dos registradores
#define MR         0x0000   // Registrador de modo
#define GAR           0x0001   // endereço(inicial) de Gateway : 0x0001 a 0x0004
#define SUBR       0x0005   // mascara de subrede           : 0x0005 a 0x0008
#define SAR           0x0009   // Source Address Register , endereço de hardware (MAC)   : 0x0009 a 0x000E
#define SIPR       0x000F   // IP do hardware(escolhido pelo programador): 0x000F to 0x0012 //Socket 0
#define RMSR       0x001A   // RX tamanho do buffer(memória) de recepção
#define TMSR       0x001B   // TX tamanho do buffer(memória) de envio

#define S0_MR       0x0400      // Socket 0: registrador do socket0 
#define S0_CR       0x0401      // Socket 0: registrador de comandos do socket0
#define S0_IR       0x0402      // Socket 0: registrador de interrupçoes do socket0
#define S0_SR       0x0403      // Socket 0: registrador de status do socket0
#define S0_PORT    0x0404      // Socket 0: aqui é colocado o valor da porta TCP ->  endereço = 0x0404 a 0x0405
#define S0_DPORT   0x0410      // Socket 0: aqui é colocado o valor da porta TCP de destino->  endereço = 0x0410 a 0x0411
#define S0_DHAR    0x0406      // Socket 0: endereçamento de registro de hardware(tipo MAC)->  endereço = 0x0406 a 0x040B
#define S0_DIPR    0x040C      // Socket 0: IP de acesso remoto ->  endereço = 0x040C a 0x040F
#define SO_TX_FSR  0x0420      // Socket 0: tamanho do registrador de transmissão: 0x0420 to 0x0421
#define S0_TX_RD   0x0422      // Socket 0: ponteiro de leitura do buffer de transmissão : 0x0422 a 0x0423
#define S0_TX_WR   0x0424      // Socket 0: ponteiro de escrita do buffer de transmissão: 0x0424 a 0x0425
#define S0_RX_RSR  0x0426      // Socket 0: tamanho do registrador de recepção: 0x0426 a 0x0427
#define S0_RX_RD   0x0428      // Socket 0: ponteiro de leitura do tamanho dos dados: 0x0428 a 0x0429

#define TXBUFADDR  0x4000      // W5100 posição inicial do buffer de escrita
#define RXBUFADDR  0x6000      // W5100 posição inicial do buffer de recepção
//S0_MR (possiveis configuração)
#define MR_CLOSE      0x00    // socket não usado
#define MR_TCP          0x01    // TCP
#define MR_UDP          0x02    // UDP
#define MR_IPRAW      0x03      // IP LAYER RAW SOCKET
#define MR_MACRAW      0x04      // MAC LAYER RAW SOCKET
#define MR_PPPOE      0x05      // PPPoE
#define MR_ND          0x20      // sem delay de Ack(somente TCP) 
#define MR_MULTI      0x80      // suporte ao multicast(valido somente para UDP)
// S0_CR values
#define CR_OPEN          0x01      // Initializa ou abre socket
#define CR_LISTEN        0x02      // espera resposta de um ponto na rede (no modo tcp(modo servidor))
#define CR_CONNECT       0x04      // envia resposta a um ponto da rede(modo cliente)
#define CR_DISCON        0x08      // finaliza conexão e gera interrupção se falhar(desconexão)
#define CR_CLOSE         0x10      // desconecta socket
#define CR_SEND          0x20      // atualiza memoria de transmissão e envia dados
#define CR_SEND_MAC      0x21      // envia dados com o endereço do MAC, sem o processo ARP(modo UDP)
#define CR_SEND_KEEP     0x22      // ckeca estado da conexão - envia um byte pra testar a conexão (modo tcp)
#define CR_RECV          0x40      // indica uma recepção no socket
// S0_SR values
#define SOCK_CLOSED      0x00     // socket fechado
#define SOCK_INIT        0x13      // inicializa conexão
#define SOCK_LISTEN      0x14      // verifica estado(listen)
#define SOCK_SYNSENT     0x15      // comando de conexão foi iniciado
#define SOCK_SYNRECV     0x16      // houve sincronismo de recepção
#define SOCK_ESTABLISHED 0x17      // sucesso na conexão
#define SOCK_FIN_WAIT    0x18      // esperando finalizar
#define SOCK_CLOSING     0x1A      // finalizando conexão
#define SOCK_TIME_WAIT     0x1B      // espera tempo para finaliza
#define SOCK_CLOSE_WAIT  0x1C      // recebeu comando de fechar pelo host
#define SOCK_LAST_ACK    0x1D      // durante a finalização é o ultimo ack
#define SOCK_UDP         0x22      // UDP     socket
#define SOCK_IPRAW       0x32      // IP raw  socket
#define SOCK_MACRAW      0x42      // MAC raw socket
#define SOCK_PPPOE       0x5F      // PPPOE   socket
#define TX_BUF_MASK      0x07FF   // Mascara do buffer de transmissão 2K :
#define RX_BUF_MASK      0x07FF   // Mascara do buffer de recepção 2K :
#define NET_MEMORIA      0x05     // Use 8K de Tx/Rx Buffer(pode se usar até 8K)
#define MAX_BUF          100      // tamanho maximo do buffer de recepção(pode ser alterado)
/////////
//////// variaveis globais ////////////////////////////////////////
////////
char buf[MAX_BUF];//buffer para guardar os dados recebido
uint8_t ip_placa[4];
uint8_t gateway[4];
//////////////valores padrao

uint8_t sockstat=0;
char comando;
int rsize;
int tempo=0;
int enviar = 0;

//tipo de acionamento se : não acionado = 0 analogico = 1 ;botão manual = 2 ; agendamento = 3


///////////////////////função de escrita SPI////////////////////////
void ip_to_char(int quant,char convert_char[5])
{
       convert_char[0]='0';
       convert_char[1]='0';
       convert_char[2]='0';
       convert_char[3]='\0';
      while(quant>=100)
        {
         quant=quant-100;
         convert_char[0]++;
         }
       while(quant>=10)
        {
         quant=quant-10;
        convert_char[1]++;
         }
       while(quant>=1)
        {
           quant=quant-1;
         convert_char[2]++;
         }
      
}

void spi_escreve(unsigned int endereco,unsigned char dados)
{
  // ativa pino de habilitação do SPI
  SPI_PORT &= ~(1<<SPI_SS);  
  SPDR = WIZNET_ESCREVE_OPCODE;//inicializa escrita pelo W5100  
  // espera terminar a comunicação
  while(!(SPSR & (1<<SPIF))); 
   // inicialização do Wiznet W5100 envia os bytes mais significativo
  SPDR = (endereco & 0xFF00) >> 8;
   // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF))); 
   //inicialização do Wiznet W5100 envia os bytes menos significativo
  SPDR = endereco & 0x00FF;  
  // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF)));   

  SPDR = dados;  // inicializa transmissão de dados
  while(!(SPSR & (1<<SPIF))); // espera finalizar a transmissão
  // finaliza comunicação.
  SPI_PORT |= (1<<SPI_SS);
}
/////////////////////////de leitura////////////////////////////////
unsigned char spi_ler(unsigned int endereco)
{
  // ativa pino de habilitação do SPI
  SPI_PORT &= ~(1<<SPI_SS);
  //inicializa leitura pelo W5100 
  SPDR = WIZNET_LER_OPCODE;
   // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF)));
   // inicialização do Wiznet W5100 envia os bytes mais significativo
  SPDR = (endereco & 0xFF00) >> 8;
   // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF)));
  //inicialização do Wiznet W5100 envia os bytes menos significativo
  SPDR = endereco & 0x00FF;
   // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF)));   

  // envia um valor qualquer para ler os dados(pois isto liga o sinal de clock do registrado SPI)
  SPDR = 0x00;
  // espera finalizar a transmissão
  while(!(SPSR & (1<<SPIF))); 
  // finaliza comunicação.
  SPI_PORT |= (1<<SPI_SS);
  return(SPDR);//retorna o valor lido do W5100
}
////////////////////////inicializa ethernet //////////////////////////////////
void W5100_Inicializa(void)
{
// tanto o ip quanto o gatway pode ser alterado para sua aplicação aqui é só um exemplo.

 unsigned char porta[] = {0x13,0X88};// ex 5000 = 0X1388 -> 0X13 +0X88 //porta 5000
  //unsigned char porta[] = {0x00,0X50};// ex 80 = 0X0050 -> 0X00 +0X50 //porta tcp
  // esse mac é do AA0000 dezembro obsoleto
  unsigned char mac_addr[] = {0xAA,0x00,0x00,0xFF,0xFF,ip_placa[0]};//MAC usado pelo microcontrolador(para teste)
  //dois dispositivos na mesma rede não pode ter o mesmo mac, coloquei o mais alto como padrão
  //aqui usei o ip para alterar o mac assim como em cada conexão não pode haver o mesmo ip ,tambem não haverá o mesmo mac
  unsigned char ip_addr[] = {ip_placa[3],ip_placa[2],ip_placa[1],ip_placa[0]};//enderreço de ip do servidor(valor para teste,do microcontrolador)
  unsigned char sub_mask[] = {255,255,255,0};//sem mascara mascara de sub_rede
  unsigned char gtw_addr[] = {gateway[3],gateway[2],gateway[1],gateway[0]};//enderreço de ip do gateway cliente (valor para teste,do pc)
  //este ip não é necessariamente o do pc mas deve estar nesta faixa

  spi_escreve(MR,0x80);            // MR = 0b10000000; isso inicicializa os registradores internos automaticamente
  _delay_ms(1);
  //configura porta de comunicação para acesso remoto
  spi_escreve(S0_PORT , porta[0]);
  spi_escreve(S0_PORT + 1,porta[1]);//porta de envio e de destino são iguais 
  spi_escreve(S0_DPORT , porta[0]);
  spi_escreve(S0_DPORT + 1,porta[1]);
  spi_escreve(S0_MR,MR_TCP);    // configura o registrador de modo (MR)
  _delay_ms(1);
  // configura o MAC de acesso remoto
  spi_escreve(S0_DHAR , mac_addr[0]);
  spi_escreve(S0_DHAR + 1,mac_addr[1]);
  spi_escreve(S0_DHAR + 2,mac_addr[2]);
  spi_escreve(S0_DHAR + 3,mac_addr[3]);
  spi_escreve(S0_DHAR + 4,mac_addr[4]);
  spi_escreve(S0_DHAR + 5,mac_addr[5]);
  _delay_ms(1);
  // endereço de IP de acesso remoto será sempre 1 a mais
  spi_escreve(S0_DIPR,ip_addr[0]);
  spi_escreve(S0_DIPR + 1,ip_addr[1]);
  spi_escreve(S0_DIPR + 2,ip_addr[2]);
  spi_escreve(S0_DIPR + 3,1);//ip 1  //ip_placa + 1);
  _delay_ms(1);
  //configura gateway
  spi_escreve(GAR + 0,gtw_addr[0]);///o gateway deve ter mesma faixa de ip senão não funciona,mas nunca usar ip 1 pois é do gateway.
  spi_escreve(GAR + 1,gtw_addr[1]);
  spi_escreve(GAR + 2,gtw_addr[2]);
  spi_escreve(GAR + 3,gtw_addr[3]);
  _delay_ms(1);
  // configura o MAC (SAR): 0x0009 à 0x000E
  spi_escreve(SAR ,mac_addr[0]);
  spi_escreve(SAR + 1,mac_addr[1]);
  spi_escreve(SAR + 2,mac_addr[2]);
  spi_escreve(SAR + 3,mac_addr[3]);
  spi_escreve(SAR + 4,mac_addr[4]);
  spi_escreve(SAR + 5,mac_addr[5]);
  _delay_ms(1);
  // mascara de sub rede (SUBR): 0x0005 à 0x0008
  spi_escreve(SUBR ,sub_mask[0]);
  spi_escreve(SUBR + 1,sub_mask[1]);
  spi_escreve(SUBR + 2,sub_mask[2]);
  spi_escreve(SUBR + 3,sub_mask[3]);
  _delay_ms(1);
  // endereço de IP (SIPR): 0x000F à 0x0012
  spi_escreve(SIPR,ip_addr[0]);
  spi_escreve(SIPR + 1,ip_addr[1]);
  spi_escreve(SIPR + 2,ip_addr[2]);
  spi_escreve(SIPR + 3,ip_addr[3]);
  _delay_ms(1);
  // configura o tamanho do buffer  de memoria de escrita e leitura 
  spi_escreve(RMSR,NET_MEMORIA);//configura para cada socket 2K de memoria de leitura(no W5100 tem 4 socket mas vamos usar somente o socket 0)
  spi_escreve(TMSR,NET_MEMORIA);//configura para cada socket 2K de memoria de transmissao(no W5100 tem 4 socket mas vamos usar somente o socket 0)
}
//////////////////////////////////fecha socket 0  ///////////////////////
void fechar_socket(uint8_t socket)
{
   if (socket != 0)return;
   // manda fechar
   spi_escreve(S0_CR,CR_CLOSE);   // espera que S0_CR seja zerado(finalizado)
   while(spi_ler(S0_CR));
}

//////////////////////////////////fecha conexão//////////////////////////
void desconectar(uint8_t sock)
{
   if (sock != 0) return;   // envia comando para desconectar
   spi_escreve(S0_CR,CR_DISCON);   // espera desconexão.
   while(spi_ler(S0_CR));
}
////////////////////////////////conecta pelo modo servidor////////////////////
uint8_t conex_servidor(uint8_t socket)
{
    uint8_t retval=0;   
     if (socket != 0)//teste socket0
      return retval;
     if (spi_ler(S0_SR) == SOCK_CLOSED) // verificando se o socket 0 está fechado.
      {
      fechar_socket(socket);
      }     
    // abrindo o  Socket 0
    spi_escreve(S0_CR,CR_OPEN);                   // abre socket 
    while(spi_ler(S0_CR)); //espera abrir  
    if (spi_ler(S0_SR) == SOCK_INIT)//checa estado inicial
      retval=1;
    else
      fechar_socket(socket);
    return retval;
}

/////////////////////////////"escuta" a rede/////////////////////////////////
uint8_t escutar_rede(uint8_t socket)
{
     uint8_t retval = 0;
     if (socket != 0)
     return retval;
     if (spi_ler(S0_SR) == SOCK_INIT) 
     { 
         spi_escreve(S0_CR,CR_LISTEN);//envia comando para escutar a rede
         while(spi_ler(S0_CR));     // espera terninar processo de escuta
         if (spi_ler(S0_SR) == SOCK_LISTEN) //verifica status de escuta
           retval=1;
         else
           fechar_socket(socket);
     }
    return retval;
}
////////////////////////////envia pacote////////////////////////////////////
uint16_t envia_pacote(char pacote[],uint16_t buffer_tamanho)
{
    unsigned int ponteiro,ende_temp,ende_real,tx_tamanho,timeout;   

    if (buffer_tamanho <= 0 )return 0;//verifica se tem espaço livre para transmitir
    tx_tamanho=spi_ler(SO_TX_FSR);
    tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(SO_TX_FSR + 1));//calcula tamanho do buffer de transmissão.
    timeout=0;
    while (tx_tamanho < buffer_tamanho) 
    {
          _delay_ms(1);
         tx_tamanho= spi_ler(SO_TX_FSR);
         tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(SO_TX_FSR + 1));     // Timeout para aproximadamente 100ms
         if (timeout++ > 100) 
           {
            // desconecta socket 0 pois não há espaço livre após 1S
           desconectar(0);
           return 0;
           }
    }
    tx_tamanho=0;    
   ponteiro = spi_ler(S0_TX_WR);//lê o ponteiro de escrita.
   ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S0_TX_WR + 1));
    while(buffer_tamanho) 
    {
      buffer_tamanho--;
      // calcula o endereço real do buffer de transmissão. 
      ende_real = TXBUFADDR + (ende_temp & TX_BUF_MASK);      // copia pacote para W5100(TX_buffer)
      spi_escreve(ende_real,pacote[tx_tamanho]);
      ende_temp++;
      tx_tamanho++;
    }
    // incrementa valor de  S0_TX_WR , então este será o ponto da proxima transmissão
    spi_escreve(S0_TX_WR,( ende_temp & 0xFF00) >> 8 );
    spi_escreve(S0_TX_WR + 1,( ende_temp & 0x00FF));
    // agora envia o comando de enviar dados para rede.
    spi_escreve(S0_CR,CR_SEND);
    // espera terminar o envio
    while(spi_ler(S0_CR));
    return 1;
}

/////////////////////////////////recebe pacote//////////////////////////////////////////
int  recebe_pacote(char pacote[],int taman)
{
        unsigned int ponteiro,ende_temp,ende_real; 
        char recebido;
        int posicao=0;
        int flag_local=0;
        ponteiro = spi_ler(S0_RX_RD);//pega localização do dado recebido(tamanho)
        ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S0_RX_RD + 1));////pega localização do dado recebido por ser 16 bits "ponteiro" deve ser descolado 
       while(taman) 
        {
          taman--;
          ende_real=RXBUFADDR + (ende_temp & RX_BUF_MASK);//endereço inicial de leitura + endereço dos dados recebidos 
          recebido = spi_ler(ende_real);
          if((flag_local ==1)&&(recebido == '>'))
            {
             flag_local=2;
             taman = 0;
             pacote[posicao] = '>';// String de fim de pacote
             pacote[posicao+1] = '\0';// String de fim de pacote
             }
          if(flag_local ==1)
             {
               if(posicao == 0)
               {
                 comando = recebido;
               }
               else
               {
                pacote[posicao-1] = recebido;
                }
               posicao++;
              }
          if(recebido == '<')
          {
            posicao = 0;
            flag_local=1; 
          } 
          ende_temp++;
          
        }
    // incrementa S0_RX_RD ,este será o ponto da proxima recepção
    spi_escreve(S0_RX_RD,(ende_temp & 0xFF00) >> 8 );
    spi_escreve(S0_RX_RD + 1,(ende_temp & 0x00FF));///////////////////////////////////////////////////vou ver isso//////////
    //envia comando para leitura 
    spi_escreve(S0_CR,CR_RECV);
    _delay_us(5);    // espera terminar leitura.
    rsize=posicao;//atualiza o novo valor de rsize
    return(flag_local);                
}
///////////////////////////////////////////////////////////////////////
int Buffer_recepcao(void)
{
  return (((spi_ler(S0_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S0_RX_RSR + 1)); //
}
////////////////////////////////////////////////////////////////////////
int procura_string(char *str_de_teste,char *str_compara)//procura posição de uma string
{
  uint16_t i,str_tamanho;

  str_tamanho=strlen(str_compara);// pega tamanho da string
  for(i=0;*(str_de_teste+i); i++)//percorre o ponteiro 
  {
    if (strncmp(str_de_teste+i,str_compara,str_tamanho) == 0)//compara com str_compara  
      return i;
  }
  return -1;
}
////////////////////////funçoes auxiliares///////////////////////////////

void inicializa_spi(void)
{
// Seta MOSI (PORTB3),SCK (PORTB5) and PORTB2 (SS) , e os outros pinos como saida 
  SPI_DDR = (1<<PORTB3)|(1<<PORTB5)|(1<<PORTB2)|(1<<PORTB1);//coloca b1 como saida
  // SS não ativado
  SPI_PORT |= (1<<SPI_SS); 
  // habilita SPI, modo mestre 0, seta clock para fck/2
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR |= (1<<SPI2X);  
}

//////////////////////////////////////////////função principal/////////////////////////////////////
int main(void)
 {
  
  //////////////////inicializa port D e port C /////////////////////////////////////////////////////////////////////
  DDRD = 0x0F;//configura port D 
  PORTD = 0x00;//desabilita pull ups
  DDRC = 0x00;//configura port C como entradas
  PORTC = 0XFF; //se estiver como saida liga as saidas e se estiver como entrada habilita pull ups
  //i = PINB; //ler pinos
//  MUX = 0X40; //usar PORTC0, justificado a direita,referencia ligada ao VCC " colocar cap no AREF "
  //DIDR0 = 0X00;////desabilita entrada analogico(reduz consumo).evita problemas quando esse pino é usado como saida
  DDRB = 0x2F;//configura port B
  PORTB = 0x00;
  inicializa_spi();    //comunicação spi

    /* if(estado_pino(PIND,PD4))//reseta ip
                     {//sim(pressionado em nivel baixo)
                      _EEPUT(28,'I');//endereço/dado1  //indica que ip deve se alterado para padrão
                     }
                     */
////////////aqui configuro o ip e gatway //////////////
             ip_placa[3]=192;
             ip_placa[2]=168;
             ip_placa[1]=0;
             ip_placa[0]=5;

             gateway[3]=ip_placa[3];
             gateway[2]=ip_placa[2];
             gateway[1]=ip_placa[1];
             gateway[0]=1;

  enviar = 0;
  desliga_pino(PORTB,PB1);///// //reseta o chip de ethernet
  _delay_ms(10);//isso garante uma inicialização do modulo de forma correta
  liga_pino(PORTB,PB1);
  W5100_Inicializa();  //inicializa modulo ethernet
  desliga_pino(PORTD,PD1);//apaga led de comando 
  ///////////////////////////////////
  sei();//habilita interrupções
  ///////////////////////////////////////////////////////
 //OBS : devo desabilitar o bit RSTDISBL para qu e o pino C6 possa ser usado como I/O
 ///////////////////////////////////////////////////////
  for(;;)
    {
         
        if(tempo> 5000)//tempo qualquer 
          {
            alterna_pino(PORTD,PD0);//faz um led piscar
            tempo =0;
          }
          tempo++;                                   
     ////////////////////////rotina ethernet////////////////////////
            sockstat=spi_ler(S0_SR);
            switch(sockstat) 
            {
             case SOCK_CLOSED: ///socket fechado. fica escutando a rede
                 { 
                            if (conex_servidor(0) > 0) //como o socket está fechado,ele fica no modo servidor  escutando a rede
                             {// Escuta  Socket 0
                                if (escutar_rede(0) <= 0)//socket 0
                                     _delay_ms(1);
                             }
                 }break;    
             case SOCK_ESTABLISHED://conectado
                 {
                                    
                    //
                   // pega o tamanho do pacote recebido do cliente
                  if (Buffer_recepcao() > 0)//checa buffer de recepção
                     {
                      // lê o pacote recebido e verifica se é valido
                          rsize=((spi_ler(S0_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S0_RX_RSR + 1);//pega tamanho dos dados recebido
                          if(recebe_pacote(buf,rsize) == 2)//indica que está ok
                          {
                              int flag_erro = 0;
                              _delay_ms(500);//tempo de resposta pode ser aterado                         
                               if (comando == 'L') //comando para pegar o status do modulo
                                 {
                                     flag_erro = 1;
                                     liga_pino(PORTD,PD1);//apaga led de comando
                                     char frase[6]; // indica que ligou
                                         frase[0]='L';
                                         frase[1]='i';
                                         frase[2]='g';
                                         frase[3]='o';
                                         frase[4]='u';
                                         frase[5]='\0';
                                     
                                     if (envia_pacote(frase,6) <= 0)//envia pacote
                                     break;//se falhar sai da conexão
                                 }//fim do Status
                                 //strlen(buf)
                                  if (comando == 'D') //modo teste
                                 {
                                     flag_erro = 1;
                                     desliga_pino(PORTD,PD1);//apaga led de comando
                                     char frase[6]; // indica que desligou
                                         frase[0]='D';
                                         frase[1]='e';
                                         frase[2]='s';
                                         frase[3]='l';
                                         frase[4]='.';
                                         frase[5]='\0';
                                     
                                     if (envia_pacote(frase,6) <= 0)//envia pacote
                                     break;//se falhar sai da conexão
                                 }//fim do Status                              
                            
                               if (flag_erro == 0)
                                     {
                                         char dados_locais[5];
                                         dados_locais[0]='E';
                                         dados_locais[1]='R';
                                         dados_locais[2]='R';
                                         dados_locais[3]='O';
                                         dados_locais[4]='\0';
                                         if (envia_pacote(dados_locais,5) <= 0)
                                         break;//se falhar sai da conexão
                                     }//fim do erro
                            }//fim leitura do pacote
                  //   desconectar(0);// desconecta socket 0
                    }//pacote maior que zero          
              }break;//fim socket estabilizado      
              case SOCK_FIN_WAIT:
              case SOCK_CLOSING:
              case SOCK_TIME_WAIT:
              case SOCK_CLOSE_WAIT:
              case SOCK_LAST_ACK:
              fechar_socket(0);// força o fechamento do socket 0
              break;
      }//chave do switch

      ////////////////////////fim da rotina ethernet////////////////////////

   }//chave do laço infinito (for)
}//chave de main//

agora é só configurar no avr studio o oscilador para 16MHZ(pode ser alterado) e otimizações  para 01,conforme figura:

se for programar usando o Burn-o-mat deixei os fuses assim:


depois de tudo pronto e chip gravado é hora de testar(lembre que aqui alterei o pino de reset do modulo para B1, no artigo anterior era B0),o led que piscar(indicando quando está conectado(pisca de velocidade diferentes)) deve está no pino D0 e o led que será controlado no pino D1,para fazer acender o led envie <L> para a placa e para desligar <D>. eu usei um programa que eu fiz no visual Studio há um tempo atrás veja a figura:

depois disto fiz um outro em java para testar, quem tiver se interessado em fazer este projeto basta me enviar um e-mail que eu mando estes softwares gratuitamente . 


terça-feira, 25 de setembro de 2012

Usando display LCD 20X4 com o ATmega328



Configuração e desenho no simulador(clique na imagem para ampliar ):


configuração no avr Studio( tenho o 5 mas o 4 é mais rápido!)



Código fonte:



//************************************************************************
//                             Display 20X4 - com atmega328
//  Version    : 1.0
//  microcontrolador : AVR ATMega328P
//  Autor        : Aguivone
//  descrição  : funcionamento de display 
//  data : 25/09/2012.
//
//************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.h>

/////////////////////////variaveis globais ////////////////////////////////////////////////////////////

char frase[]="12345678912345678912";//vetor de 20 posiçoes

/////////////////////////////////////variaveis usada no lcd ///////////////////////////////////////////
#define LCD PORTC //define qual porta vai usar
//o pino r/w é conectado ao terra pois não é feita nenhuma leitura no display
//configuração:
//
// pino display  / pino da porta selecionada
//
// D4 = bit 0 da porta
// D5 = bit 1 da porta
// D6 = bit 2 da porta
// D7 = bit 3 da porta
//
// RS = bit 4 da porta
// EN = bit 5 da porta
//
/////////////////////////////////////////////////Funções usadas no LCD/////////////////////////////////////////////

void inicializa_LCD(void)
{
    _delay_ms(15);//tempo para estabilizar a tensão e preparar o display
    // o primeiro digito é de controle e o segundo configuração

    LCD = 0X22;//nesse momento o display ainda está em modo 8bits solicita modo de 4 bits
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);
                // é preciso colocar este comando pelo menos 2 vezes para que funcione o display
    LCD = 0X22;//nesse momento o display  está em modo 4bits 
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

    ////////entrou no modo 4bits/////////////////////////////////////

    LCD = 0X28;//nesse momento o display  está em modo 4bits,manda usar 2 linhas 
    _delay_ms(1);//tempo estabilizar o pino
    LCD =0X08;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

    /////////////////////envia 0X01 - limpar display ////////////////////////////////////
    LCD = 0X20;//manda limpar o display
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X21;//segundo nibble (limpa display)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X01;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

        /////////////////////envia 0X06  - movimento e pisca do display////////////////////////////////////
    
     LCD = 0X20;//manda deslocar a direita (0x06)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

     LCD = 0X26;//segundo nibble (desloca a direita)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X06;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    /////////////////////envia 0X0C - desliga display ////////////////////////////////////

    LCD = 0X20;//cursor desligado (0X0C)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X2C;//segundo nibble (cursor deligado)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X0C;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

        /////////////////////envia 0X2F - modo 4bits modo 4 linhas tipo de fonte ////////////////////////////////////

    LCD = 0X22;//cursor desligado (0X2F)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X2F;//segundo nibble (cursor deligado)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X0F;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 
    
}
// escreve nibble
void escr(unsigned char crt,int vlr)//se vlr = 1 é dados ,senão é comandos
{
    if(vlr == 1)
    {
    LCD = crt | 0X30 ;//escreve dados
    _delay_us(30);//tempo estabilizar o pino
    LCD = crt | 0X10;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_us(30);
    }
    else
    {
    LCD = crt | 0X20 ;//escreve comando
    _delay_us(30);//tempo estabilizar o pino
    LCD = crt | 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_us(30);
    }
}
// escreve caracter ou comando
void escreve(unsigned char carac,int val)
{
    unsigned char temp=carac;
    carac = ((carac >> 4) & 0X0F);
    temp  = temp & 0X0F;
    escr(carac,val);  //escreve primeiro nibble
    escr(temp,val);  //escreve segundo nibble
}

void impri_lcd(char frase[22])
{
      unsigned int indice=0;
      unsigned int tamanho = strlen(frase);
      while(indice<tamanho)
       {         
            if(frase[indice]=='\n')//linha 1 
            {
                 escreve(0X80,0);
            }
            if(frase[indice]=='\r')//linha2
            {
                 escreve(0XC0,0);//
            }
            if(frase[indice]=='@')//linha 3 
            {
                 escreve((0X94),0);
            }
            if(frase[indice]=='$')//linha4
            {
                escreve((0XD4),0);
            }
            if((frase[indice]!='\r') && (frase[indice]!='\n') && (frase[indice]!='@') && (frase[indice]!='$'))//dados
            {
               if(indice<21)
               {
                escreve(frase[indice],1);
               }
            }   
       indice++;
       }
} 

////////////////////////////////////telas de interface //////////////////////////////////////////////////

void tela_inicial()
{
           impri_lcd("\n.Testando display de");
           impri_lcd("\r.......20x4.........");
           impri_lcd("@12345678912345678912");
           impri_lcd("$------AGUIVONE------");
}

void tela_2()
{
            impri_lcd("@                    ");
           impri_lcd("$------teste2  ------");
}

void tela_3()
{
           impri_lcd("$------teste3  ------");
}

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0XFF;  //inicializa portC como saidas
           inicializa_LCD();
           tela_inicial();
           _delay_ms(2000);
           tela_2();
           _delay_ms(1000);
           tela_3();
           _delay_ms(1000);
           for(;;)
             {
              //faz nada!                                    
             }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////

quinta-feira, 26 de julho de 2012

Display de 7 segmentos com ATmega 328P (avr sutudio)

aqui é usado o display catodo comum!


Esquemático :

Código fonte:

//************************************************************************/
//                             Display 7 segmento com Atmega328P
//  Version             : 1.0
//  microcontrolador : AVR ATMega328
//  Autor            : Aguivone
//  descrição        : usando display 7 segmento com avr studio
//  data             : 26/07/2012.
//
//************************************************************************/
#define F_CPU 16000000UL  // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.h>

#define liga_pino(x,y) x |= _BV(y)
#define desliga_pino(x,y) x &= ~(_BV(y))
#define alterna_pino(x,y) x ^= _BV(y)

#define SEG_A   PD7
#define SEG_B   PB0
#define SEG_C   PB1
#define SEG_D   PB2
#define SEG_E   PB3
#define SEG_F   PB4
#define SEG_G   PB5
/////////////////////////////funçoes auxiliares /////////////////////////////
void  mostra_numero(int numero)
{
     switch(numero)
     {
     case 0:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 liga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 desliga_pino(PORTB,SEG_G);
                }break;
     case 1:
                {
                 desliga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 desliga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 desliga_pino(PORTB,SEG_F);
                 desliga_pino(PORTB,SEG_G);
                }break;
     case 2:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 desliga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 liga_pino(PORTB,SEG_E);
                 desliga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 3:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 desliga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 4:
                {
                 desliga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 desliga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 5:
                {
                 liga_pino(PORTD,SEG_A);
                 desliga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 6:
                {
                 liga_pino(PORTD,SEG_A);
                 desliga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 liga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 7:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 desliga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 desliga_pino(PORTB,SEG_F);
                 desliga_pino(PORTB,SEG_G);
                }break;
     case 8:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 liga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);
                }break;
     case 9:
                {
                 liga_pino(PORTD,SEG_A);
                 liga_pino(PORTB,SEG_B);
                 liga_pino(PORTB,SEG_C);
                 liga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 liga_pino(PORTB,SEG_F);
                 liga_pino(PORTB,SEG_G);            
                }break; 
     case 10://desliga display
                {
                 desliga_pino(PORTD,SEG_A);
                 desliga_pino(PORTB,SEG_B);
                 desliga_pino(PORTB,SEG_C);
                 desliga_pino(PORTB,SEG_D);
                 desliga_pino(PORTB,SEG_E);
                 desliga_pino(PORTB,SEG_F);
                 desliga_pino(PORTB,SEG_G);            
                }break; 
     }
}

/////////////////////////////função principal////////////////////////////////
int main(void)
{
           DDRD = 0XFF;  //inicializa portD como saida
           DDRB = 0XFF;  //inicializa portB como saida
           
          //////////////////////////
           for(;;)
            {     
              mostra_numero(0);
              _delay_ms(1000);
               mostra_numero(1);
              _delay_ms(1000);
               mostra_numero(2);
              _delay_ms(1000);
               mostra_numero(3);
              _delay_ms(1000);
               mostra_numero(4);
              _delay_ms(1000);
               mostra_numero(5);
              _delay_ms(1000);
               mostra_numero(6);
              _delay_ms(1000);
               mostra_numero(7);
              _delay_ms(1000);
               mostra_numero(8);
              _delay_ms(1000);
               mostra_numero(9);
              _delay_ms(1000);
               mostra_numero(10);
              _delay_ms(1000);               
            }
            
}
//////////////////////////////////////////////////////////////////////////////


para contribuir com o blog colocando seus projetos aqui basta entrar em contato!

até a próxima!

quarta-feira, 11 de julho de 2012

Discadora com ATmega328P


vou demonstrar aqui como fazer uma simples discadora de pulsos,para isso você terá que montar o seguinte circuito :


veja o código fonte:



/*
 *                                                 Discagem por pulsos
 *   Version    : 1.0
 *   microcontrolador : AVR ATMega328
 *   descrição  : como montar uma discadora por pulso
 *   criado: 11/07/2012 
 *   autor: aguivone moretti fogia
 */


#define F_CPU 16000000  // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.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    PC1  //no rele de discagem deve ser colocado um resistor de 470R para não curto circuitar a linha telefonica 

void numero(int valor)
{
    int xis=0;
     while(xis < valor)
     {
      desliga_pino(PORTC,PULSO);
      _delay_ms(35);
      liga_pino(PORTC,PULSO);
      _delay_ms(65); 
      xis++;
     }
     _delay_ms(400);//espaço necessario entre cada digito
}
 
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0XFF;  //inicializa portC como saida;
           
           for(;;)
           {
            // os numeros deve ser de 1 a 9, para o zero use o numero "10"
            //vamos supor que vai ligar para o numero 1234 5670
            liga_pino(PORTC,PULSO);
            _delay_ms(200); //espera para dar linha para discar 
            numero(1);
            numero(2);
            numero(3);
            numero(4);
            numero(5);
            numero(6);
            numero(7);
            numero(10);//zero             
            _delay_ms(10000); //espera para chamar por 10s
            desliga_pino(PORTC,PULSO);
            _delay_ms(10000);//espera 10s e liga denovo

           }
}

terça-feira, 10 de julho de 2012

Usando interrupções externas do ATMEGA328P:

           O grande diferencial deste exemplo é que aqui vou demonstrar como usar as interrupções externas de modo que vocês possam usar todas( 23 interrupções no total),tempos atrás postei aqui como usar as interrupções INT0 e INT1 para o ATMEGA8 mas é se você precisar de mais interrupções como fazer ?.Para responder a essa pergunta monte o seguinte circuito na proto-o-board("coloque um led em qualquer pino do PORTB") ou no simulador virtual :


           E agora vamos ao código fonte :

//************************************************************************
//                             usando interrupção externa
//  Version    : 1.0
//  microcontrolador : AVR ATMega328P
//  Autor        : Aguivone
//  descrição  : usando interrupção externa int8 pra usar as outras interrupções é do mesmo modo
//                                                    pino C0(int8)
//  data : 10/07/2012.
//
//************************************************************************
#define F_CPU 16000000UL  // 1 MHz deve vir antes das interrupçoes
#include <avr/io.h>
#include <avr/interrupt.h>

/*
ISR(PCINT0_vect) //interrupçoes e 0 a 7
  {
  PORTB = ~PORTB;
  }*/

ISR(PCINT1_vect) //interrupçoes e 8 a 14
  {
  PORTB = ~PORTB;//neste exemplo vamos usar a interrupção no pino C0(int8)
  }
/*
ISR(PCINT2_vect) //interrupçoes e 16 a 23
  {
  PORTB = ~PORTB;
  }*/

/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void inicializa_interrupcoes(void)
{

  // PCICR = 0X01;//habilita interrupções de 0 a 7 
    PCICR = 0X02;//habilita interrupções de 8 a 14 //no exemplo vou usar  a interrup~ção 8
//   PCICR = 0X04;//habilita interrupções de 16 a 23 ,depende do modelo do microcontrolador

//   pode ainda fazer conbinaçõe pra usar todas as interrupçoes simultâneas

    //PCMSK0 = 0X00//aqui coloca qual pino vai gerar a interrupçoes,pode se usar mais de um.  
      PCMSK1 = 0X01;//selecionei somente o pino de interrupção 8 (PC0)
    //PCMSK2 = 0X00//aqui coloca qual pino vai gerar a interrupçoes,pode se usar mais de um. 
   sei(); //habilita interrupções
}

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0xFE;  //inicializa portd
           PORTC = 0;
           DDRB = 0xFF;  //inicializa portd
           PORTB = 0; 
           inicializa_interrupcoes();
           for(;;)
            {
             //faz nada!
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////


 contribua com o blog postando seus exemplos aqui também

segunda-feira, 9 de julho de 2012

Usando o watchdog do pic 16F877A

       Neste exemplo vou demostrar como usar o watchdog do pic, você vai precisar montar o seguinte circuito para testes:
      Note que se você manter o botão pressionado o watchdog não estoura mas se ficar com o botão livre ele irá reiniciar o pic a aproximadamente  2,3 segundos.Veja o código-fonte: 



///////////////////////////////////////////////////////////////////////////////
//projeto : usando o watchdog do pic
//autor : aguivone
//data : 09/07/2012
//versão: 1
//////////////////////////////////////////////////////////////////////////////

#include <16F877A.h>
#fuses XT,WDT,NOPROTECT,NOLVP // deve se habilitar aqui o watchdog(WDT)
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main()
{ 
    setup_wdt(WDT_2304MS);//programa pra estourar a cada 2,3 segundos
    printf("Iniciando teste de watch dog! \r\n");
    for(;;)
    {
      delay_ms(1800);
      if(INPUT(PIN_B0))
        {
          RESTART_WDT();// reinicia contagem,é mais usual 
          //#fuses NOWDT   se usar esta linha desliga watchdog        
          printf("Não estourou ainda! \r\n");
        }
        else
        {
         printf("Vai estourar em breve! \r\n");
        } 
    }
}

/*valores possiveis:

 WDT_18MS 
 WDT_36MS 
 WDT_72MS 
 WDT_144MS 
 WDT_288MS 
 WDT_576MS 
 WDT_1152MS 
 WDT_2304MS 
*/


contribua com o blog mande seus exemplos também!