quinta-feira, 16 de setembro de 2010

sequencial de 22 leds com atmega8 (avr)

Olá ,aqui está um exemplo de codigo para quem precisar fazer um sequencial de leds

//************************************************************************
//                             usando sequencial
//  Version : 1.0
//  microcontrolador : AVR ATMega8
//  Autor     : Aguivone
//  descrição  : acesso individual usando define
//  data : 16/09/2010.
//
//************************************************************************
#define F_CPU 1000000UL  // 1 MHz deve vir antes das interrupçoes
#include <avr/io.h> //standard include for ATMega16 # Include <avr/io.h> / padrão para incluir ATMEGA16
#include <util/delay.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 pino_alto(x,y) ((x & _BV(y)) == _BV(y)) //o pino deve estar como entrada ,testa se está em nivel logico 1

///* _BV(a) is a macro which returns the value in hex corresponding to 2 to the power 'a'. / * _BV (A) é uma macro que retorna o valor em hexadecimal correspondente a 2 elevado à potência 'a'. Thus _BV(PX3) would be 0x08 or 0b00001000 */ Assim _BV PX3 () seria 0x08 ou 0b00001000 * /
int main (void)
{
    unsigned int valor = 50;
   // DDRB= 0xf7 ; //PORTB as OUTPUT DDRB = 0xff; / PORTB / as OUTPUT
    DDRB = 0xFF;
    DDRC = 0xFF;
    DDRD = 0xFF;
    PORTB = 0x00 ; //All pins of PORTB LOW PORTB = 0x00 / / Todos os pinos do PORTB LOW
    PORTC = 0x00 ; //All pins of PORTB LOW PORTB = 0x00 / / Todos os pinos do PORTB LOW
    PORTD = 0x00 ; //All pins of PORTB LOW PORTB = 0x00 / / Todos os pinos do PORTB LOW
    while (1)
    {
    //////////////////////////////////////////////
       liga_pino(PORTB,PB0);
    _delay_ms(1);
       desliga_pino(PORTC,PC5);
        _delay_ms(valor);
       liga_pino(PORTB,PB1);
    _delay_ms(1);
       desliga_pino(PORTB,PB0);
        _delay_ms(valor);
  liga_pino(PORTB,PB2);
  _delay_ms(1);
       desliga_pino(PORTB,PB1);
        _delay_ms(valor);
       liga_pino(PORTB,PB3);
    _delay_ms(1);
       desliga_pino(PORTB,PB2);
        _delay_ms(valor);
     
     liga_pino(PORTB,PB4);
  _delay_ms(1);
       desliga_pino(PORTB,PB3);
        _delay_ms(valor);
       liga_pino(PORTB,PB5);
    _delay_ms(1);
       desliga_pino(PORTB,PB4);
        _delay_ms(valor);
  liga_pino(PORTB,PB6);
  _delay_ms(1);
        desliga_pino(PORTB,PB5);
        _delay_ms(valor);
        liga_pino(PORTB,PB7);
     _delay_ms(1);
        desliga_pino(PORTB,PB6);
        _delay_ms(valor);
       ///////////////////////////////////////////////////////////
     liga_pino(PORTD,PD0);
    _delay_ms(1);
       desliga_pino(PORTB,PB7);
        _delay_ms(valor);
       liga_pino(PORTD,PD1);
    _delay_ms(1);
       desliga_pino(PORTD,PD0);
        _delay_ms(valor);
  liga_pino(PORTD,PD2);
  _delay_ms(1);
       desliga_pino(PORTD,PD1);
        _delay_ms(valor);
       liga_pino(PORTD,PD3);
    _delay_ms(1);
       desliga_pino(PORTD,PD2);
        _delay_ms(valor);
     
     liga_pino(PORTD,PD4);
  _delay_ms(1);
       desliga_pino(PORTD,PD3);
        _delay_ms(valor);
       liga_pino(PORTD,PD5);
    _delay_ms(1);
       desliga_pino(PORTD,PD4);
        _delay_ms(valor);
  liga_pino(PORTD,PD6);
  _delay_ms(1);
        desliga_pino(PORTD,PD5);
        _delay_ms(valor);
        liga_pino(PORTD,PD7);
     _delay_ms(1);
        desliga_pino(PORTD,PD6);
        _delay_ms(valor);
  ///////////////////////////////////////////
  liga_pino(PORTC,PC0);
    _delay_ms(1);
       desliga_pino(PORTD,PD7);
        _delay_ms(valor);
       liga_pino(PORTC,PC1);
    _delay_ms(1);
       desliga_pino(PORTC,PC0);
        _delay_ms(valor);
  liga_pino(PORTC,PC2);
  _delay_ms(1);
       desliga_pino(PORTC,PC1);
        _delay_ms(valor);
       liga_pino(PORTC,PC3);
    _delay_ms(1);
       desliga_pino(PORTC,PC2);
        _delay_ms(valor);
     
     liga_pino(PORTC,PC4);
  _delay_ms(1);
       desliga_pino(PORTC,PC3);
        _delay_ms(valor);
       liga_pino(PORTC,PC5);
    _delay_ms(1);
       desliga_pino(PORTC,PC4);
        _delay_ms(valor);

       }
}

terça-feira, 14 de setembro de 2010

usando lcd 4 bits com atmega8 AVR STUDIO

Aqui a proposta é controlar um lcd de forma facil e sem biblioteca :
///************************************************************************/
//                             usando LCD
//  Version    : 1.0
//  microcontrolador : AVR ATMega8
//  Autor        : Aguivone
//  descrição  : usando lcd interface de 8 bits
//  data : 02/09/2010.
//
//************************************************************************/
#define F_CPU 4000000UL  // 4 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <string.h> 

/////////////////////////////////////variaveis usada no lcd ///////////////////////////////////////////
//#define LCD PORTC //define qual porta vai usar neste caso port C
#define LCD PORTD //define qual porta vai usar neste caso port D
//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);

    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);

    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 
    
     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 

    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 
    
}
// escreve nibble
void escr(unsigned char crt,int vlr)
{
    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[17])
{
      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]!='\r') && (frase[indice]!='\n') && (indice<18))//dados
            {
               escreve(frase[indice],1);
            }   
       indice++;
       }
} 

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0XFF;  //inicializa portC
           DDRD = 0XFF;  //inicicializa portD como saida
           inicializa_LCD();
           impri_lcd("\n   teste de lcd ");
           impri_lcd("\r      AGUIVONE  ");
          for(;;)
            {
              //faz nada                
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////


quarta-feira, 8 de setembro de 2010

Interrupção externa com atmega8 - avr studio

//************************************************************************
// usando interrupção externa
// Version : 1.0
// microcontrolador : AVR ATMega8
// Autor : Aguivone
// descrição : usando interrupção externa int0 e int1
// data : 25/08/2010.
//
//************************************************************************
#define F_CPU 1000000UL // 1 MHz deve vir antes das interrupçoes
#include
#include

//////////////////////////interrupções externas ///////////////////////////////////
ISR(INT0_vect ) //int0
{
PORTC = ~PORTC;
}
ISR(INT1_vect ) //int1
{
PORTB = ~PORTB;
}

/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void inicializa_interrupt(void)
{
MCUCR = 0X07;//configura a interrupção 1 para qualquer mudança de estado no pino e int0 para borda de subida
GICR = 0xC0;//habilita int1 e int0
sei(); //habilita interrupções
}

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

PWM com o atmega8 - avr studio

//************************************************************************
// usando o PWM
// Version : 1.0
// microcontrolador : AVR ATMega8
// Autor : Aguivone
// descrição : PWM
// data : 30/08/2010.
//
//************************************************************************
#define F_CPU 1000000UL // 1 MHz deve vir antes das interrupçoes
#include

/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void PWM_CTC(void)
{
TCCR2 = 0X55;// toggle OC2 / usar modo CTC / preescaler(1/128) // // aqui se define a frequencia.
OCR2 = 0X40;//valor a ser comparado com o TCNT2 (aqui é mudado a largura do pulso)

//pinos de pwm PB1,PB2,PB3(OC1,2,3).
}

void PWM_NORMAL(void)// o valor da largura de pulso é sempre 50%
{
TCCR2 = 0X15;// toggle OC2 / usar modo normal / preescaler(1/128) // // aqui se define a frequencia.
//pinos de pwm PB1,PB2,PB3(OC1,2,3).
}

void PWM_FAST(void)// o valor da largura de pulso é sempre 50%
{
TCCR2 = 0X7D;// modo invertido OC2 / usar modo fast pwm / preescaler(1/128) // // aqui se define a frequencia.
//pinos de pwm PB1,PB2,PB3(OC1,2,3).

// neste modo gera um pulso muito rapido se no modo invertido a largura do pulso é proximo de 99%
// modo não invertido a largura do pulso é proximo de 1%
}

void PWM_FASE(void)// o valor da largura de pulso é sempre 50%
{
TCCR2 = 0X3F;// seta OC2 quando comparado/ usar modo fase pwm / preescaler(1/128) // // aqui se define a frequencia.
//pinos de pwm PB1,PB2,PB3(OC1,2,3).
// a verificar
}

Usando serial com atmega8 - avr studio

//************************************************************************


// usando a porta serial
// Version : 1.0
// microcontrolador : AVR ATMega8 UART
// Autor : Aguivone
// descrição : exemplo de uso da serial
//
//************************************************************************

#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz deve vir antes das interrupçoes
#include <avr/interrupt.h>
#include <stdio.h>
///////////////////////////////////////////////funçoes usadas////////////////////////////////////////////////

int uart_putchar(char c, FILE *stream)

{
if (c == '\n')
uart_putchar('\r', stream);
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}

int uart_getch(FILE *stream)
{
unsigned char ch;
while (!(UCSRA & (1<<RXC)));
ch=UDR;
return ch;
}

/* assimila I/O stream á UART */

FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getch, _FDEV_SETUP_RW);

void ini_serial(int BAUD_RATE)
{
UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // calcula o ubrr da comunicação
UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
UCSRB = (1<<RXEN)
(1<<TXEN); //habilita tx e rx

UCSRC = (1<<URSEL)
(1<<UCSZ1)
(1<<UCSZ0);//programa para 8bit ,sem paridade,1 stop bit
sei(); // habilita interrupçoes geral
}

void Delay(unsigned int count) // conta tempo

{
while(count>0)
{
count--;
}
}



//////////////////////////////////////////função principal///////////////////////////////////

int main(void)
{
stdout = stdin = &uart_str; /* inicializa a UART */
ini_serial(4800); /* inicializa serial para 4800 bps */
DDRD = 0xFF; // configura o portd
PORTD = 0; // inicializa o portd

for(;;)
{
printf("teste de serial \n\r");
Delay(12000);
}

}

///////////////////////////////////////////fim//////////////////////////////////////////////

Pisca pisca com timer0 - avr studio

//************************************************************************
// usando os timers
// Version : 1.0
// microcontrolador : AVR ATMega8
// Autor : Aguivone
// descrição : interrupção dos timer
// data : 24/08/2010.
//
//************************************************************************
#define F_CPU 1000000UL // 1 MHz deve vir antes das interrupçoes
#include
#include

//////////////////////////interrupções do timer0 ///////////////////////////////////
ISR(TIMER0_OVF_vect )
{ //interrupção overflow
PORTD =~ PORTD; //nessa interrupção não é preciso ler ou zerar o TCNT0
}

/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void inicializa_timer0(void)
{
TCCR0 = 0x05; //pre escaler dividido por 8
TIMSK = 0x01; //habilita interrupção do timer 0(estouro do contador)
sei(); //habilita interrupções
}

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
DDRD = 0xFF; //inicializa portd
PORTD = 0;
inicializa_timer0();
for(;;)
{
//faz nada!
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////

usando a eeprom do atmega8 - avr studio


 1:  //************************************************************************
   2:  //                             usando a memoria do atmel
   3:  //  Version    : 1.0
   4:  //  microcontrolador : AVR ATMega8
   5:  //  Autor        : Aguivone
   6:  //  descrição  : escrevendo e lendo a memoria
   7:  //  data : 01/09/2010.
   8:  //
   9:  //************************************************************************
  10:  #define F_CPU 4000000UL  // 4 MHz deve vir antes das interrupçoes
  11:  #include <avr/io.h>
  12:  #include <avr/interrupt.h>
  13:  #include <util/delay.h>
  14:  #include <string.h>
  15:  #include <avr/eeprom.h>
  16:   
  17:   
  18:  #define liga_pino(x,y) x |= _BV(y)
  19:  #define desliga_pino(x,y) x &= ~(_BV(y))
  20:   
  21:  unsigned char temp;
  22:   
  23:   unsigned char caracter;//
  24:   unsigned int  tam_buffer;//usado para contar o tamanho do buffer de recepção
  25:   unsigned char buffer_serial[14];//buffer da serial
  26:   volatile char rec_buffer ='S';//usado para ler o buffer de recepção (volatile para funcionar pois sempre ira retornar mesmo valor)
  27:   
  28:  ///////////////////////////////////////////////funçoes usadas pela usart////////////////////////////////////////////////
  29:   
  30:  void serial_inicializa(unsigned int BAUD)
  31:  {
  32:  unsigned int valor = F_CPU/16/BAUD-1; //é recomendavel ver o data sheet para ter certeza se está formula irá funcionar na sua mcu
  33:  /* baud rate */
  34:  UBRRH = (unsigned char)(valor>>8);
  35:  UBRRL = (unsigned char)valor;
  36:  UCSRA = 0X20;
  37:  /* habilita receiver and transmitter buffers */
  38:  UCSRB = 0X98;//deve se habilitar somente a interrupção de recepção para não travar o microcontrolador
  39:  /* 8 bits , 1 stop bit, assincrono , sem paridade */
  40:  UCSRC = 0X86;
  41:  }
  42:  void impri_serial(const char frase[80])
  43:  {
  44:        unsigned int indice=0;
  45:        unsigned int tamanho = strlen(frase);      
  46:        while(indice<=tamanho)///veja que o programa pode travar se aqui não tiver as duas aspas
  47:         {
  48:             while ( !( UCSRA & (1<<UDRE)) ); //espera transmitir para enviar um novo
  49:             UDR =frase[indice];
  50:             indice++;
  51:         }
  52:  }
  53:  void put_serial(unsigned char *carac)
  54:  {
  55:             while ( !( UCSRA & (1<<UDRE)) ); //espera transmitir para enviar um novo
  56:             UDR = *carac;
  57:  }
  58:  //////////////////////////interrupções requerida para usar a serial///////////////////////////////////
  59:  ISR(USART_RXC_vect)
  60:  {                                            // # caracter *
  61:   caracter = (char)UDR;
  62:    if(caracter == '*')
  63:     {
  64:          if(tam_buffer<14)//max do display
  65:            {
  66:              rec_buffer ='F';
  67:             }
  68:             else
  69:             {
  70:              rec_buffer ='E';//tamanhoa incompativel
  71:             }
  72:     }
  73:    if((caracter != '*')&&(rec_buffer == 'I'))
  74:     {
  75:      buffer_serial[tam_buffer]=caracter;
  76:      tam_buffer++;
  77:      }
  78:    if(caracter == '#')
  79:     {
  80:     rec_buffer ='I';
  81:     tam_buffer=0;
  82:     }
  83:  }
  84:   
  85:   
  86:  ////////////////////////////////////////////////função principal///////////////////
  87:   
  88:  int main(void)
  89:  {
  90:    DDRC = 0x00;  //inicializa portc como entrada
  91:    DDRD = 0XFE;  //inicializa portD
  92:    DDRB = 0xFF;  //inicializa portb como saida
  93:    serial_inicializa(4800);//não importa frequencia e 4800
  94:    sei();
  95:    impri_serial("Inicializado ... \n\r");
  96:    while (1)
  97:        {
  98:             if(rec_buffer == 'F')//tem dados para ler ?
  99:                       {
 100:                        impri_serial("recebeu primeiro caracter :");
 101:                        impri_serial(&buffer_serial[0]);
 102:                        impri_serial("\n\r");
 103:                        if(buffer_serial[0] == 'E')//houve interrupção
 104:                               {
 105:                                   impri_serial("comparou");
 106:                                   temp='n';
 107:                                   _EEPUT(5,buffer_serial[1]);//endereço/dado
 108:                                   _EEGET(temp,5);//local a ser escrito/endereço
 109:                                   impri_serial(& temp); 
 110:                                   liga_pino(PORTB,PB0);
 111:                                   _delay_ms(500);
 112:                                   desliga_pino(PORTB,PB0);
 113:                               }
 114:                        rec_buffer = 'S';
 115:                       } 
 116:                    if(rec_buffer == 'E')//deu erro ?
 117:                       {
 118:                        impri_serial("tamanho inconpativel");
 119:                        rec_buffer = 'S';
 120:                       }
 121:             
 122:   
 123:        }
 124:  }
 125:   
 126:   
 127:  //para usar float é necessario adiconar a biblioteca

usando lcd com atmega8 - avr studio

///************************************************************************/
// usando LCD
// Version : 1.0
// microcontrolador : AVR ATMega8
// Autor : Aguivone
// descrição : usando lcd interface de 8 bits
// data : 02/09/2010.
//
//************************************************************************/
#define F_CPU 1000000UL // 1 MHz
#include
#include

/////////////////////////////////////variaveis usada no lcd ///////////////////////////////////////////
#define LCD PORTD //dados a ser escrito
#define CMD PORTC //será usado só o bit0 é o bit1 desta porta
//o pino r/w é conectado ao terra pois não é feita nenhuma leitura no display
/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////

void inicializa_LCD(void)
{
_delay_ms(20);
CMD = 0X01;
LCD = 0X38;//modo de 8 bits
_delay_ms(1);//tempo para escrever no lcd
CMD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
_delay_ms(5);
CMD = 0X01;
LCD = 0X38;//modo de 8 bits
_delay_ms(1);//tempo para escrever no lcd
CMD = 0X00;
_delay_ms(5);
CMD = 0X01;
LCD = 0X0C;//cursor desligado
_delay_ms(1);//tempo para escrever no lcd
CMD = 0X00;
_delay_ms(5);//substitui a leitura do busy flag
CMD = 0X01;
LCD = 0X06;;//direção de movimento
_delay_ms(1);
CMD = 0X00;
_delay_ms(5);//substitui a leitura do busy flag
CMD = 0X01;
LCD = 0X01;//limpa display
_delay_ms(3);
CMD = 0X00;
_delay_ms(15);//substitui a leitura do busy flag
}
void impri_lcd(char frase[20])
{
unsigned int indice=0;
unsigned int us_controle=0;
while(us_controle<2)///veja que o programa pode travar se aqui não tiver as duas aspas
{
if(frase[indice]=='"')
{

if(us_controle==0)//identifica inicio e fim de transmissão
{
us_controle=1;
}
else
{
us_controle=2;
}
}
else
{
if(frase[indice]=='\n')
{
CMD = 0X01;//escreve comando
LCD = 0X80;//poe na linha 1 posicão 0
_delay_us(20);//para garantir sucesso , ao mexer com funcão é melhor deixar um tempo maior que 15us
CMD = 0X00;
_delay_us(20);//escreve dados
}
if(frase[indice]=='\r')
{
CMD = 0X01;//escreve comando
LCD = 0XC0;//poe na linha 2 posicão 0
_delay_us(20);//para garantir sucesso , ao mexer com funcão é melhor deixar um tempo maior que 15us
CMD = 0X00;
_delay_us(20);//escreve dados
}
if((frase[indice]!='\r') && (frase[indice]!='\n') && (indice<18))
{
CMD = 0X03; //prepara escrita de dados
LCD = frase[indice]; // coloca caracter para escrita
_delay_us(20);//tempo de estabilizar o valor na porta de saida
CMD = 0X02; //manda escrever
_delay_us(20);//tempo para escreve dados
}
}
indice++;
}
}
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
DDRC = 0XFF; //inicializa portC
DDRD = 0XFF; //inicicializa portD como saida
inicializa_LCD();
impri_lcd("\n teste");
impri_lcd("\r DE LCD");
for(;;)
{
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////

Botão e led com atmega8 - AVR studio

//
// acender led com botao
//
//Autor : aguivone
//data : 17/08/2010
//descrição : não necessária
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

#include

////////////////////////funçoes usadas ////////////////////////////////////////////////////////////

void Inicializa_chip(void)//inicializa portas
{
PORTB = (1<0)
{
count--;
}
}

/////////////////////////////////////////////função principal//////////////////////////////////////////////////

int main(void)
{
Inicializa_chip();
PORTD=0XFF;
while(1)
{
if((PINB & 4)==0)//faz uma logica and com o portb
{
while((PINB & 4)==0)
{
PORTB |= 0x08;
Delay(300);
PORTB &= 0x00;
Delay(300);
}
PORTB &= 0x01;
}
PORTB ^= 0x01;///usando ou exclusivo a inversão é mais rapido
Delay(1000);
PORTD = ~ PORTD;//inverte PORTD
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////

Piscar um led com atmega8 - AVRstudio

//demonstra como fazer delay sem usar arquivos de include

#include

/// Typedefs //////////
typedef unsigned char u8; //cria um caracter
typedef unsigned int u16; //cria um inteiro 16 bits
typedef unsigned long u32; //cria um inteiro 32 bits

/// Defines ///////////
#define forever 117
#define LEDOFF PORTB |= (1<<4)
#define LEDON PORTB &= ~(1<<4)

void InitPorts(void)//inicializa portas
{
DDRB |= 0x04;//pino 2 é entrada e os demai são saida 00000100
DDRD = 0XFF;
}

void Delay(u32 count)
{
while(count--);
}


int main(void)
{
InitPorts();

while (forever)
{
LEDON;
Delay(20000);
LEDOFF;
Delay(20000);
PORTD = ~ PORTD;//inverte port d
}
}

Contagiros digital com o pic

          Este projeto está em uso a mais de um ano e funciona muito bem, a montagem do circuito foi dividido em 2 partes o que reduziu o tamanho final do protótipo(além de não sobrecarregar o firmware do microcontrolador): placa de display 7 segmentos e placa de leds . O circuito nada mais é do que um frequencimetro digital ( conta os pulsos do alternador, pois este está acoplado ao motor e conseqüentemente a cada giro do motor é um giro do alternador ,mas isso depende do modelo da moto), valor da freqüência(RPM) e mostrado nos display 7 segmentos e cada um dos vintes leds da sequência são acionados a cada 500 RPM, ou seja para 2000RPM temos 4 leds acesos.Um detalhe importante é o fato dos leds terem cores diferentes para cada faixa de valores, até 5000RPM é verde, entre 5000 e 8000RPM amarelo, e acima de 8000RPM cor vermelha.veja na figura abaixo a foto do protótipo já instalado na moto e em dois momentos distintos.


Figura1 - contagiros já instalado na moto.

A placa do display 7 segmentos

             Afim de facilitar a interface entre as placas e usar uma quantidade menor de pinos do microcontrolador ( pois os led vão usar 20 dos 40 pinos do microcontrolador 16F877) foi colocado o CI CD4511 que é um decodificador bcd/7segmentos. O circuito da figura 2 mostra as principais interfaces.


Figura 2 – placa do display.

           De Q1 a Q4 são os transistores responsáveis por chavear os 4 displays pois o quinto display é mantido sempre em zero, pois não é significativo(veja que em todos os modelos comerciais de conta-giros analógicos são divididos por 10) pois o motor terá no minimo algo em torno de 900RPM, os resistores de R6 a R9 tem o valor de 1K,para economizar espaço e componentes foi utilizado um led para cada display.

A placa dos leds

           Os led estão dispostos conforme a figura 3.Onde é possível ver também o componente que é usado para gerar os pulsos no pino 17 do microcontrolador(versão de teste), embora que para uma melhor precisão utilizei os dois módulos CCPs (pino 16 e 17) na versão final do projeto.




Figura 3 – Simulação dos leds.


          Na placa dos leds existe um regulador de tensão que converte de 12 para 5V (LM 7805), pois a bateria da moto está entre 12V e 13.8V , os pinos de interface que saem do pic são :

Pino 8 - A (1° bit do código BCD).
Pino 9 - B (2° bit do código BCD).
Pino 10 - C (3° bit do código BCD).
Pino 18 - D (4° bit do código BCD).
Pino 4 - 1° digito.
Pino 5 - 2° digito.
Pino 3 - 3° digito.
Pino 6 - 4° digito.

           Apesar de ter ficado com bastante ligações e complexa (cheia de fios o que prejudica a visualização) optei por colocar aqui o esquemático usado para montar a placa, veja a figura 4.os resistores de R10 a R13 são de 120R/2W .


Figura 4 – Esquemáticos da placa dos leds.

               O sinal recebido do alternador é acoplado ao microcontrolador via CI 4N25, o sinal é aplicado no borne P1 e entregue ao borne P2 e dai aos pinos 17 e 16 do PIC, conforme a figura 4.


            Figura 4 – Acoplamento do sinal.

// ****************************************************************************************************************************************************
// Conta giro digital (funcionou)
// Data: 14/11/2008
// Autores: Aguivone
// Descrição: usando lcd
// ****************************************************************************************************************************************************
#include <16F877A.h>
#ignore_warnings 203, 216
#fuses NOWDT,XT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4M)
boolean flg;
int32 rpm,conta,tmp,sobe,sobe2,valor,valor2;
int flag,dig1,dig2,dig3,dig4;
#locate rx_reg = 0x1A
void digito(int valor)
{
switch(valor)
{
case 0:{output_low(PIN_E0);output_low(PIN_E1);output_low(PIN_E2);output_low(PIN_C3);}//0000
break;
case 1:{output_high(PIN_E0);output_low(PIN_E1);output_low(PIN_E2);output_low(PIN_C3);}//1000
break;
case 2:{output_low(PIN_E0);output_high(PIN_E1);output_low(PIN_E2);output_low(PIN_C3);}//0100
break;
case 3:{output_high(PIN_E0);output_high(PIN_E1);output_low(PIN_E2);output_low(PIN_C3);}//1100
break;
case 4:{output_low(PIN_E0);output_low(PIN_E1);output_high(PIN_E2);output_low(PIN_C3);}//0010
break;
case 5:{output_high(PIN_E0);output_low(PIN_E1);output_high(PIN_E2);output_low(PIN_C3);}//1010
break;
case 6:{output_low(PIN_E0);output_high(PIN_E1);output_high(PIN_E2);output_low(PIN_C3);}//0110
break;
case 7:{output_high(PIN_E0);output_high(PIN_E1);output_high(PIN_E2);output_low(PIN_C3);}//1110
break;
case 8:{output_low(PIN_E0);output_low(PIN_E1);output_low(PIN_E2);output_high(PIN_C3);}//0001
break;
case 9:{output_high(PIN_E0);output_low(PIN_E1);output_low(PIN_E2);output_high(PIN_C3);}//1001
break;
}
}
void converte(void)
{
dig1=0;
dig2=0;
dig3=0;
dig4=0;
while(rpm!=0)
{
rpm--;
while(rpm>=1000)
{
dig4++;
rpm=rpm-1000;
}
while(rpm>=100)
{
dig3++;
rpm=rpm-100;
}
while(rpm>=10)
{
dig2++;
rpm=rpm-10;
}
while(rpm>=1)
{
dig1++;
rpm=rpm-1;
}
}

}
#int_ccp1
void isr2()
{
sobe=CCP_1;
if(flag==1)
{
if(sobe2<=sobe) { valor2=sobe-sobe2; } else { conta=sobe2-sobe; valor2=65536-conta; } flag=2; } } #int_ccp2 void isr() { sobe2 = CCP_2; if(sobe2>=sobe)
{
valor =sobe2-sobe;
}
else
{
conta=sobe-sobe2;
valor =65536-conta;
}
flag=1;
}

//////////////////////////////////////////////////////////////////
void main(void)
{
#priority ccp2,ccp1
setup_ccp1(CCP_CAPTURE_FE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_RE); // Configure CCP2 to capture subida
//setup_ccp2(CCP_CAPTURE_DIV_4);
setup_timer_1(T1_INTERNAL); // Start timer 1
enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(INT_CCP1); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);
set_tris_a(0); // define o port a como saída
set_tris_b(0); // define o port b como saída
set_tris_d(0); // define o port b como saída
set_tris_c(15); // define o port d como saída
set_tris_e(0); // define o port e como saída
conta=0;
enable_interrupts(global);
output_b (0);
output_d (0);
rpm=0;
dig1=0;
dig2=0;
dig3=0;
dig4=0;
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (0);
output_d (0);
for(;;)
{
if(flag==2)
{
disable_interrupts(GLOBAL);
valor=valor+valor2;
tmp=1000000/valor;
rpm=tmp*6;
flg=0;
if((rpm<=100)&&(flg==0)) { output_low(PIN_C4); output_low(PIN_C5); output_low(PIN_C6); output_low(PIN_C7); output_b (0); output_d (0); flg=1; } if((rpm>=1000)&&(flg==0))
{
output_high(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (255);
flg=1;
}
if((rpm>=950)&&(flg==0))
{
output_high(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (254);
flg=1;
}
if((rpm>=900)&&(flg==0))
{
output_high(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (252);
flg=1;
}
if((rpm>=850)&&(flg==0))
{
output_low(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (252);
flg=1;
}
if((rpm>=800)&&(flg==0))
{
output_low(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (244);
flg=1;
}
if((rpm>=750)&&(flg==0))
{
output_low(PIN_C4);
output_high(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (240);
flg=1;
}
if((rpm>=700)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_high(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (240);
flg=1;
}
if((rpm>=650)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
output_b (255);
output_d (240);
flg=1;
}
if((rpm>=600)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (255);
output_d (240);
flg=1;
}
if((rpm>=550)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (255);
output_d (224);
flg=1;
}
if((rpm>=500)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (255);
output_d (192);
flg=1;
}
if((rpm>=450)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (255);
output_d (128);
flg=1;
}

if((rpm>=400)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (255);
output_d (0);
flg=1;
}

if((rpm>=350)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (254);
output_d (0);
flg=1;
}

if((rpm>=300)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (252);
output_d (0);
flg=1;
}
if((rpm>=250)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (248);
output_d (0);
flg=1;
}
if((rpm>=200)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (240);
output_d (0);
flg=1;
}
if((rpm>=150)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (224);
output_d (0);
flg=1;
}
if((rpm>=100)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (192);
output_d (0);
flg=1;
}
if((rpm>=50)&&(flg==0))
{
output_low(PIN_C4);
output_low(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
output_b (128);
output_d (0);
flg=1;
}
converte();
flag=0;
enable_interrupts(GLOBAL);
}
output_low(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
digito(dig1);
output_low(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_high(PIN_A2);
delay_ms(3);
output_low(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
digito(dig2);
output_low(PIN_A5);output_low(PIN_A1);output_high(PIN_A3);output_low(PIN_A2);
delay_ms(3);
output_low(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
digito(dig3);
output_low(PIN_A5);output_high(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
delay_ms(3);
output_low(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
digito(dig4);
output_high(PIN_A5);output_low(PIN_A1);output_low(PIN_A3);output_low(PIN_A2);
delay_ms(3);
}

}

Video do contagiros funcionando.