Engenheiro eletricista - Desenvolvedor de hardware. Protótipos e projetos. Desenvolvimento de software de interface.(aguivone@gmail.com)
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:
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 :
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 :
contribua com o blog postando seus exemplos aqui também
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:
contribua com o blog mande seus exemplos também!
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!
Assinar:
Postagens
(
Atom
)