segunda-feira, 25 de fevereiro de 2013

Usando o modo captura de eventos externos no avr.

     Neste exemplo vou demonstrar como capturar e medir o periodo de um sinal aplicado ao pino de captura de eventos externos(pino PB0) do ATmega328P,este exemplo é útil para o momento em que se deseja medir a frequência de um sinal,existe a ainda a possibilidade de habilitar a interrupção do de estouro do timer1 para medir sinal muito longos(deixei comentado mas é só adaptar para a sua necessidade).Quando um botão é pressionado o microcontrolador muda o estado logico do portD e lê o valor que está em ICR1(período), pressionando varias vezes o botão você pode notar que ele dará diferentes valores de período(veja figura abaixo).


     Para achar a frequência basta fazer F=1/T(período),sendo que T = (1/frequência do cristal) X valor lido .segue abaixo o exemplo de código.

Código fonte: 
        
//************************************************************************
//                             usando o modo captura de pulsos 
//  Version    : 1.0
//  microcontrolador : AVR ATMega328
//  Autor        : Aguivone
//  descrição  : captura de eventos externos
//  data : 25/02/2013.
//
//************************************************************************
#define F_CPU 16000000UL  //  deve vir antes das interrupçoes
#include <avr/io.h>
#include <avr/interrupt.h>

int long lido; //variavel que vai ler o valor do registrador

//////////////////////////interrupções do timer0 ///////////////////////////////////
/*
ISR(TIMER1_OVF_vect )
  {                    //interrupção overflow

         PORTD =~ PORTD; //nessa interrupção não é preciso ler ou zerar o TCNT0  aprox 15hz
         //veja que na simulação dará 30hz pois o valor maximo de cristal para simular é 8 mhz
  }
  */
ISR(TIMER1_CAPT_vect)
{              //interrupção de captura de eventos externos.
          int high = ICR1L;//primeiro deve ser lido os byte mais baixo e depois os mais altos
          lido = (ICR1H<<8) + high;
          PORTD =~ PORTD;
          TCNT1 = 0;//limpar o timer
}
/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void inicializa_modo_captura(void)
{
   TCCR1A = 0X00;//não tem uso para o modo captura de eventos externos
   TCCR1B = 0x41;//filtro desabilitado,captura na borda de subida do sinal,clock interno sem prescaler 
   TCCR1C = 0X00;//não tem uso para o modo captura de eventos externos
   TIMSK1 = 0x20; //habilita interrupção de captura
   //TIMSK1 = 0x21; //habilita interrupção de estouro de timer e de captura
   sei(); //habilita interrupções
}
/*
opcional vai depender da aplicação

void parar_timer(void)
{
TIMSK0 = 0x20; //desabilita interrupção do timer 0(estouro do contador)
}

void reiniciar_timer(void)
{
TIMSK0 = 0x21; //habilita interrupção do timer 0(estouro do contador)
}*/
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{

            DDRD = 0xFF;  //inicializa portd como saida
            PORTD = 0;//limpa as portas logicas.
            inicializa_modo_captura();
           for(;;)
            {
             //faz nada!
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
veja tambem o posto do frequencimetro com o AVR

quinta-feira, 21 de fevereiro de 2013

MPlabXC8 - botão e led

Neste exemplo vou demonstrar como fazer um programa simples no MPlabXC8 usando o PIC16F6228A

/* 
 *                                      Botão e led
 *
 * Compilador : MPlabXC8
 * Microcontrolador: 16F628A
 * Autor: aguivone
 * Versão: 1
 * Data : on 21 de Fevereiro de 2013, 09:46
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/////////////////////////////////////////////////////////configuraçôes//////////////////////////////////////////////////

#define _XTAL_FREQ 20000000    // cristal de 20 Mhz

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)


//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////

void main(void) {
    TRISB = 0XFE;//configura portB como entrada e RB0 como saida
    for(;;)
    {
        if(RB1 == 1)
        {//se pino B1 do microcontrolador for acionado então fica piscando
            RB0 = 1;
            __delay_ms(100); 
            RB0 = 0;
            __delay_ms(100);
        }
        else
        {
            RB0 = 0;
        }
    }//loop infinito

}

quarta-feira, 20 de fevereiro de 2013

primeiro contato com o MPlabX :

     Voltei a usar microcontroladores PIC pois fiquei sabendo da nova IDE e dos compiladores gratuito(exceto versão standard e pro) da microchip, esses compiladores são MPlabXC8, MPlabXC16, MPlabXC32.
link para iniciantes :
 http://youtu.be/kbckQodNFmA

//////////////////////////////////////////////////////////////////////////////////////
/* 
 *                        primeiro programa 
 *   
 *Compilador:           MPlabXC8  
 *Microcontrolador:     12F675   
 *Autor:                aguivone
 *versão:               1
 *solução esperada :    pisca led 
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

#define _XTAL_FREQ 20000000    // 20 Mhz

// Configurações dos fuses 
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High speed crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

void  main()
{
    TRISIO = 0X00;//Configura saida do 12F675
        for(;;)
        {
                   GPIO   = 0X00;
           __delay_ms(500);
                   GPIO   = 0XFF;
           __delay_ms(500);
        }
}



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

considerações importantes:

    -> um detalhe interessante que deve ser ressaltado é quanto ao "mplab driver switcher" depois de instalado o MPlabX(e caso ainda tenha uma versão anterior instalada,"sugiro nem excluir" se vc usa ele com seu programador) vc deve abrir este programa e solicitar para que ele use o MPlabX.
    -> veja que a nova IDE não dá suporte a alguns programadores de PIC mais antigos,a solução é abrir o sua versão anterior ao MplabX e importar o arquivo hexadecimal gerado e então gravar usando seu programador de pic(no meu caso uso o pickit2 então nem preciso do MPlab antigo). 
    ->tem funções como a "__delay_ms()" que podem ficar como na imagem abaixo:



 ainda não sei bem o porque disto mas apenas ignorei e funcionou bem o programa de teste.

até o próximo post pessoal! 
Errata:
já sei por que do delay ficar assim,para resolver é só colocar(se quiser) os defines :

#define delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0))) 
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
        










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...)*/