ATXMega32D4 interfaz de dos cables

1

Últimamente he estado usando ATMega32A y ATMega324PA y aprendí varias técnicas de codificación en la programación de AVR C. Uno de estos códigos que escribí es avr_twi.c para comunicarse con un acelerómetro I2C

Ahora me migraron a ATXMega32D4, y puedo hacer frente al nuevo dispositivo con pocas dificultades. Sin embargo, no puedo hacer funcionar la programación I2C para la serie XMega y específicamente para ATXMega32D4. El código se adjunta a continuación

        #include <avr/io.h>
        #define F_CPU 2000000UL
        #include <util/delay.h>
        #include <avr/interrupt.h>
        #include <avr/wdt.h> // watchdog timer
        #include <stdio.h>
        #include <string.h>
        #include <stdlib.h>
        #include <avr/eeprom.h>
        #include <avr/pgmspace.h>

        #define F_TWI 100000
        #define TWI_BAUD(FSYS, FTWI) ((FSYS / (2 * FTWI)) - 5)
        #define TWI_BAUDSETTING TWI_BAUD(F_CPU, F_TWI)

        int8_t twi_read=0;
        TWI_t * BMA = &TWIC;

        void uart_transmit(char data)
        {
            USARTD0.DATA = data;
            if(!(USARTD0.STATUS & USART_DREIF_bm)) {
                while(!(USARTD0.STATUS & USART_TXCIF_bm)); // wait for TX complete
            }
            USARTD0.STATUS |= USART_TXCIF_bm;  // clear TX interrupt flag
        }

        uint8_t uart_getchar()
        {
            while(!(USARTD0.STATUS & USART_RXCIF_bm)); // wait for RX complete
            return (uint8_t)USARTD0.DATA;
        }

        void uart_array(char c[])
        {
            unsigned int j;
            j=strlen(c);
            for(unsigned int i=0;i<j;i++)
            {
                uart_transmit_gsm(c[i]);
            }
        }

        static inline void init_oscillator() {
            // enable 2Mhz internal oscillator
            OSC.CTRL |= OSC_RC2MEN_bm;
            // wait for it to be stable
            while (!(OSC.STATUS & OSC_RC2MRDY_bm));
            // tell the processor we want to change a protected register
            CCP=CCP_IOREG_gc;
            CLK.CTRL=CLK_SCLKSEL_RC2M_gc;
            // callibrated oscillator as auto-calibration source
        }

        static inline void init_usart()
        {
            // set PD3 as output for TX0
            PORTD.DIRSET = PIN3_bm;
            PORTD.OUTSET = PIN3_bm;
            // Atmel-42005-8-and-16-bit-AVR-Microcontrollers-XMEGA-E_Manual.pdf
            USARTD0.BAUDCTRLA = 12; // BSEL
            USARTD0.BAUDCTRLB = 0 << USART_BSCALE_gp; // BSCALE
            // disable 2X
            USARTD0.CTRLB = USARTD0.CTRLB & ~USART_CLK2X_bm;
            // enable RX and TX
            USARTD0.CTRLB = USARTD0.CTRLB | USART_RXEN_bm | USART_TXEN_bm;
            // enable async UART 8N1
            USARTD0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;
            USARTD0.CTRLC &= ~USART_SBMODE_bm;
            // set interrupt level for RX
            //USARTD0.CTRLA = (USARTD0.CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;
        }

        void twi_init()
        {
            //smart-mode activate
            BMA->MASTER.CTRLB |= TWI_MASTER_SMEN_bm;
            //Baud-rate setting
            BMA->MASTER.BAUD |= TWI_BAUDSETTING;
            //Enable twi
            BMA->MASTER.CTRLA |= TWI_MASTER_ENABLE_bm;
            //status register
            BMA->MASTER.STATUS |= TWI_MASTER_BUSSTATE_IDLE_gc;
        }

        void twi_write_data(uint8_t writeAddr,uint8_t writeData)
        {
            uint8_t i;
            uart_array("stp1");
            BMA->MASTER.ADDR = 0x30;
            while(!(BMA->MASTER.STATUS&TWI_MASTER_WIF_bm));

            BMA->MASTER.DATA = writeAddr;
            while(!(BMA->MASTER.STATUS&TWI_MASTER_WIF_bm));

            BMA->MASTER.DATA = writeData;
            while(!(BMA->MASTER.STATUS&TWI_MASTER_WIF_bm));

        }

        int8_t twi_read_data(uint8_t readAddr)
        {

            BMA->MASTER.ADDR = 0x31;

            while(!(BMA->MASTER.STATUS&TWI_MASTER_WIF_bm));

            BMA->MASTER.DATA = 0x00;
            BMA->MASTER.ADDR = readAddr;
            while(!(BMA->MASTER.STATUS&TWI_MASTER_RIF_bm));

            return BMA->MASTER.DATA;
        }

        int main(void)
        {
            init_oscillator();
            init_usart();
            twi_init();
            twi_write_data(0x3D,0xFA);
            uart_transmit(twi_read_data(0x3D));
            while(1);
        }

Si alguien tiene experiencia en AVR XMega I2C, publique un código de ejemplo con al menos alguna explicación. Gracias

    
pregunta gzix

1 respuesta

-1

Cambia USARTD0.STATUS con USARTD0_STATUS. Si usa Atmel Studio 6.2, puede ver que no es de color rosa si no se reconoce.

    
respondido por el Dario D.

Lea otras preguntas en las etiquetas