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);
}
}
Engenheiro eletricista - Desenvolvedor de hardware. Protótipos e projetos. Desenvolvimento de software de interface.(aguivone@gmail.com)
quinta-feira, 16 de setembro de 2010
sequencial de 22 leds com atmega8 (avr)
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!
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 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//////////////////////////////////////////////
// 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 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(;;)
{
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// 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<
{
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
}
}
#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.
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.
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.
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 .
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.
// ****************************************************************************************************************************************************
// 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.
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.
Assinar:
Postagens
(
Atom
)