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.