Перейти к содержанию
    

kelebeithel

Новичок
  • Постов

    1
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный
  1. Странная работа TWI

    Добрый день! Сел осваивать TWI и захотел попробовать реализовать работу с ним через прерывания. Написал приведенную ниже программу. Есть две меги 328p, одна прошита как мастер, вторая как слейв, код обоих ниже. Программа читает кнопку мастера и при нажатии отправляет кодовую посылку на другую мегу, которая по приеме кодовой посылки меняет состояние светодиода. В итоге залил нижеприведенные программы и начал отлаживать. Выяснил, что первая посылка происходит отлично, светодиод зажигается, и больше не гаснет. Первая посылка происходит и на стороне мастера, и на стороне слэйва без эксцессов. А вот на второй посылке в мастере срабатывает прерывание по Start Condition, и на этом все кончается. Прерывания дальше уже не срабатывают, то есть слэйв не подтверждает передачу ему адреса. И дальше все стопорится. Самое характерное, что если прописать в обработчике прерываний все коды возможных ошибок то он не заходит ни по одному из них. Форумчане, помогите разобраться с ситуацией #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define MASTER_ADDRESS (0b0100101) #define SLAVE_ADDRESS (0b0100111) #define LED_TOGGLE (0b00100010) #define SLAVE //Master #ifdef MASTER int current=0b00000010, previous=0b00000010, counter=0; ISR(TWI_vect) { switch(TWSR) { case 0x08: //start TWDR=SLAVE_ADDRESS<<1; TWCR=0b11001101; break; case 0x18: //SLA+W transmitted, ACK recieved TWDR=LED_TOGGLE; counter+=1; if(counter==2) PORTB|=0b00000001; else PORTB&=0b11111110; TWCR=0b10001111; break; case 0x20: PORTB|=0b00000001; break; case 0x30: PORTB|=0b00000001; break; case 0x38: PORTB|=0b00000001; break; case 0x10: PORTB|=0b00000001; break; case 0x28: //data transmitted, ACK recieved TWCR=0b10011111; break; } } int main(void) { DDRB=0b00000001; PORTB=0b00000010; TWAR=MASTER_ADDRESS; SREG|=0b10000000; while (1) { if((PINB&0b00000010)==0b00000000) _delay_ms(5); current=PINB&0b00000010; if((previous==0b00000010)&&(current==0b00000000)) { TWCR=0b10100101; } previous=current; } } #endif #ifdef SLAVE //Slave int counterSlave=0; ISR(TWI_vect) { switch(TWSR) { case 0x60: TWCR=0b11000101; break; case 0x80: if(TWDR==LED_TOGGLE) counterSlave+=1; TWCR=0b11000101; break; case 0xA0: TWCR=0b01000101; break; } } int main(void) { DDRB=0b00000001; PORTB=0b00000010; SREG|=0b10000000; TWAR=SLAVE_ADDRESS<<1; TWCR=0b01000101; while (1) { if ((counterSlave%2)==1) PORTB|=0b00000001; else PORTB&=0b11111110; } } #endif
×
×
  • Создать...