Atmega48A PD6 sin salida

0

Estoy teniendo problemas con la salida de un alto digital en PD6 en el Atmega48A. Cuando trato de establecerlo alto, simplemente se mantendrá bajo sin hacer nada. A pesar de que el led parpadeará y otros pines funcionarán en el puerto D.

Aquí está el esquema del tablero, así como el fragmento de código que estoy usando para intentar establecer el pin alto.

¿Hay algo indocumentado sobre PD6 que no haya explicado?

Esquema: enlace

FYI: R1 ahora es un J0 en lugar de 10k

#define I2C_MODE_NORMAL   TWBR = 32;
#define I2C_MODE_FAST     TWBR = 2;

// timer overflow occur every 0.256 ms
ISR(TIMER2_OVF_vect) {
    _1000us += 256;
    while (_1000us > 1000) {
        _millis++;
        _1000us -= 1000;
    }
}

// safe access to millis counter
uint64_t millis() {
    uint64_t m;
    cli();
    m = _millis;
    sei();
    return m;
}

uint16_t read_adc(uint8_t channel) {
    ADMUX = (ADMUX & 0xf0) | channel; // Channel selection
    ADCSRA |= _BV(ADSC);                // Start conversion
    while (!bit_is_set(ADCSRA, ADIF));    // Loop until conversion is complete
    ADCSRA |= _BV(ADIF);                // Clear ADIF by writing a 1 (this sets the value to 0)

    return(ADC);
}

uint8_t i2c_start(uint8_t address) {
    TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
    while (!(TWCR & _BV(TWINT)));
    TWDR = address;
    TWCR = _BV(TWINT) | _BV(TWEN);
    while (!(TWCR & _BV(TWINT)));
    return(TWSR);
}

uint8_t i2c_data_send(uint8_t data) {
    TWDR = data;
    TWCR = _BV(TWINT) | _BV(TWEN);
    while (!(TWCR & _BV(TWINT)));
    return(TWSR);
}

uint8_t i2c_data_read(bool more) {
    int timeout = 0;
    if (more) {
        TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA); // starts bus read
    }
    else {
        TWCR = _BV(TWINT) | _BV(TWEN); // starts bus read
    }
    while (!(TWCR & _BV(TWINT)))
    {
        timeout++;
        if (timeout >= 100) break;
    }
    return(TWDR);
}

void i2c_stop() {
    TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
}

void setup() {
    // IO Configuration
    DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB6) | _BV(PB7);
    DDRC = _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
    DDRD = _BV(PD0) | _BV(PD1) | _BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5) | _BV(PD6);
    DDRD &= ~_BV(PD7);
    PORTD &= ~_BV(PD7);

    // ADC Init
    ADMUX = _BV(REFS0); // For Aref=AVcc;
    ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // Enable ADC and set 128 prescale

    // Interrupt
    // prescale timer2 to 1/8th the clock rate
    // overflow timer2 every 0.256 ms
    TCCR2B |= _BV(CS21);
    // enable timer2 overflow interrupt
    TIMSK2 |= 1 << TOIE2;

    // Enable global interrupts
    sei();

    //Flip SCL Until SDA is high to clear the state of RTC I2C brown outs
    while (!(PINC >> PINC4 & 1)) {
        PORTC &= 0b11011111;
        _delay_us(3);
        PORTC |= 0b00100000;
        _delay_us(3);
    }

    I2C_MODE_FAST;  // I2C Begin

    i2c_start(I2C_RTC_WRITE);
    i2c_data_send(0x0E); // Control byte to select Register
    i2c_data_send(0b00011101); // Data for 0Eh Control
    i2c_data_send(0b00000000); // Data for 0Fh Control/Status
    i2c_stop();

    get_rtc_time(seconds, minutes, hours, TIME_REGISTER_RTC);
}

void loop() {
    uint64_t curr_millis = millis(); // grab current time

    if ((curr_millis - old_millis) >= 1000) {
        PORTD ^= 1; // toggle led
        PORTD ^= _BV(PD4);
        PORTD ^= _BV(PD6);
        old_millis = curr_millis;
        alarm_on = !alarm_on;
    }
}

int main(void) {
    _delay_ms(50); // Settling time

    setup();

    for (;;) { // Loop forever
        loop();
    }
}

No todo está incluido ya que es simplemente otra lógica.

    
pregunta a_dizzle

0 respuestas

Lea otras preguntas en las etiquetas