Autor Tema: PIC+AVR  (Leído 2499 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
PIC+AVR
« en: 20 de Julio de 2013, 18:45:04 »
Hola! Esta iniciativa nace de mi intención de aprender a programar los micro de ATMEL (concretamente los AVR) y a profundizar mas en la programación con el compilador XC  conjunto a MPLAP X para los PIC. Entonces, iré mostrando los programas que haga (cualquier chorrada) pero que incluya ambos micros en simulación o vida real.

De esta forma estoy trabajando (por ahora) con un ATMEGA8535 a 4MIPS y un PIC16F887 a 1MIPS. Para el AVR estoy usando el compilador CodeVisionAVR 3.04 y para el PIC el XC8 1.12 con el MPLAB X v1.80. Todo (por ahora, otra vez) es simulador con el Proteus 7.10 SP0.

Esta primera practica lo que hace es: por el lado del PIC, recibir por el pin RB0 (habilitado con pullup) el estado de un botón y sacarlo por el pin RC0. Por el lado del AVR, recibir por el pin PB0 (habilitado con pullup) el estado de RC0 y sacarlo inversamente por el pin PC0 que esta conectado a un LED.

Se que es una chorrada y lo dije antes. Pero la idea es ir aprendiendo y no me importa =D Así que dejo todo adjuntado alfinal.

Una imagen:
https://docs.google.com/file/d/0B3BkNcqm_dJtNEhHVW9HaTNoVm8/edit?usp=sharing


Codigo del PIC
Código: [Seleccionar]

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

#define _XTAL_FREQ 4000000

// CONFIG1
#pragma config FOSC = EXTRC_CLKOUT// Oscillator Selection bits (RC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, RC on RA7/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#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)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

int main(int argc, char** argv)
{
    ANSELH = 0;                 // Para poder usar bien el puerto B
    PORTB = 0;                  // inicializacion del puerto B
    TRISB = 0b00000001;         // direcion de los pines del peurto B, el bit 0 (RB0) como entrada.
    OPTION_REGbits.nRBPU = 0; // habilitamos los pullups internos del puerto B.
    WPUB = 0b00000001;          // habilitmos el pullup del pin b0

    PORTC = 0;                  // inicializamos puerto C
    TRISCbits.TRISC0 = 0;       // direcion del pin C0 como salida (por deffault los demas quedan como entrada)
    RC0 = 0;                    // inicializo el estado del pin c0 a 0.

    while (1)   // programa infinito
    {
        RC0 = RB0;  //sacamos por rb0 lo mismo que haya en rc0
    }

    return (EXIT_SUCCESS);
}




Codigo del AVR
Código: [Seleccionar]

#include <mega8535.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<WGM20) | (0<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);


DDRB = 0b11111110;  // el pin pb0 como entrada
PORTB.0 = 1;        // habilito pullup en rb0

DDRC.0 = 1;         // pin pc0 como salida
PORTC.0 = 0;        // inicizlida como 0

while (1)
{
    PORTC.0 = !PINB.0;
}
}



LINKS de interés:
http://www.micros-designs.com.ar/creando-un-proyecto-en-codevisionavr/
http://www.micros-designs.com.ar/control-sobre-puertos-io-y-demoras/
http://www.atmel.com/devices/atmega8535.aspx
http://hpinfotech.ro/html/cvavr.htm
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en026561



Saludos!
« Última modificación: 20 de Julio de 2013, 18:57:24 por jeremylf »

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Re: PIC+AVR
« Respuesta #1 en: 21 de Julio de 2013, 06:43:40 »
Te animo a seguir dandole a los atmel, yo llevo un tiempo trabajando con ellos, uso el compilador WinAVR junto con AVRStudio de Atmel, creo que son unos micros con una gran potencia. Existe una gran comunidad, aunque en ingles:

http://www.avrfreaks.net/

Y aqui en el foro encontraras tambien un subforo. Eso si no se como sera Codevision, pero despues de CCS pasar al WinAVR se hace al principio pesado, aunque al final lo veo preferible, vuelves a tener que configurar los registros de perifericos, volver a saber que esta pasando en el micro, y tienes todas las ventajas de C.
Saludos desde Córdoba, españa

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: PIC+AVR
« Respuesta #2 en: 28 de Julio de 2013, 21:47:02 »
Gracias Kain589 por las palabras. En esta nueva entrega hago uso de esos programas, creo que mejor usaré eso.

PWM
PIC16F887 a 20Mhz
PWM modo normal a 38khz al 50% duty por RC2 (CCP1)

Para esta configuración me he guiado especificamente de lo que dice el datasheet p131:


IDE MPLAB X v1.80 y compilador XC v1.12
Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

#define _XTAL_FREQ 20000000

// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection bits (RC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, RC on RA7/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#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)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

int main(int argc, char** argv)
{
    ANSELH = 0;                 // Para poder usar bien el puerto B
    PORTB = 0;                  // inicializacion del puerto B
    TRISB = 0b00000001;         // direcion de los pines del peurto B, el bit 0 (RB0) como entrada.
    OPTION_REGbits.nRBPU = 0; // habilitamos los pullups internos del puerto B.
    WPUB = 0b00000001;          // habilitmos el pullup del pin b0

    PORTC = 0;                  // inicializamos puerto C
    TRISCbits.TRISC0 = 0;       // direcion del pin C0 como salida (por deffault los demas quedan como entrada)
    RC0 = 0;                    // inicializo el estado del pin c0 a 0.

   // CONFIGURACION PWM   /////////////////////////////////
   TRISC2 = 1; // deshabilito pin pwm
   PR2 = 130;      // 38.16 khz
   // Frec PWM = Fosc / (4*(PR2+1)*Pescaler)
   // 38.16 khz = 20 / (4*(130+1)*1) * 1000
   CCP1CON = 0b00001100;
   // 00: solo salida pwm por c2
   // xx: son los dos bit menos significantes para el duty
   // 11xx: modo pwm selecionado
   CCPR1L = 65; // duty 0%    65 = duty al 50%
   TMR2IF = 0;
   T2CON = 0b00000100;
   // 0: no implementado
   // xxxx: postcaler tmr2
   // 1: timer2 on
   // 00: timer2 prescale a 1
   while (TMR2IF == 0) {}  // espera hasta que timer2 desborde
   TRISC2 = 0; // habilito pin ccp a salida


    while (1)   // programa infinito
    {
        
    }

    return (EXIT_SUCCESS);
}

ATMEGA8535 a 8Mhz
PWM con el timer1 en modo de fase y frecuencia correcta a 2.5Khz al 50% del duty por PD5 (OC1A)
Para esta configuración me he guiado del datasheet y con ayuda de este link: http://www.cursomicros.com/avr/timers/timer1-y-timer3-del-avr-en-modo-pwm.html

IDE ATMEL Studio 6.1 y compilador AVR GCC (WinAVR)
Código: [Seleccionar]
#include <avr/io.h>

int main(void)
{
      
TCCR1A = 0b10000100;
// 10: OC1A a 0 en la compracion (onda no invertida)
// 00: OC1B desconectado
// 0x: FOC1A a 0 para asegurar compatibilidad de futuro dispositivos y FOC1B a 0 porque no uso pwm en OC1B
// 00: PWM de fase y frecuencia con tope de conteo en ICR1 (junto con los bits 3 y 4 de TCCR1B)

TCCR1B = 0b10010;
// 10: PWM de fase y frecuencia con tope de conteo en ICR1 (junto con los bits 0 y 1 de TCCR1A)
// 010: fuente de reloj F_CPU/8

DDRD = 0b100000; // RD5 como salida.

    /* Poner algunos valores iniciales */
    ICR1 = 200;      // frecuencia PWM = 1/(2*200 ) = 2.5 kHz //tope de conteo
    OCR1A = 100;     // Duty cycle canal A = 50%

    while(1)
    {
        
    }
}







Saludos!
« Última modificación: 29 de Julio de 2013, 01:38:00 por jeremylf »

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Re: PIC+AVR
« Respuesta #3 en: 29 de Julio de 2013, 06:46:04 »
Veo que sigues avanzando, yo estuve mirando el otro dia, y en los atmegaxx8 si no me equivoco hay una funcion del timer0 con el modulo ccp, que permite complementar la salida y resetar el valor del timer0 todo por hardware, lo que lo hace idoneo para pwm del 50%. Aun no hice el programa, a ver si me pongo
Saludos desde Córdoba, españa


 

anything