реклама на сайте
подробности

 
 
> Странная работа TWI
kelebeithel
сообщение Oct 1 2016, 10:14
Сообщение #1





Группа: Новичок
Сообщений: 1
Регистрация: 13-08-16
Пользователь №: 92 944



Добрый день! Сел осваивать TWI и захотел попробовать реализовать работу с ним через прерывания. Написал приведенную ниже программу. Есть две меги 328p, одна прошита как мастер, вторая как слейв, код обоих ниже. Программа читает кнопку мастера и при нажатии отправляет кодовую посылку на другую мегу, которая по приеме кодовой посылки меняет состояние светодиода. В итоге залил нижеприведенные программы и начал отлаживать. Выяснил, что первая посылка происходит отлично, светодиод зажигается, и больше не гаснет. Первая посылка происходит и на стороне мастера, и на стороне слэйва без эксцессов. А вот на второй посылке в мастере срабатывает прерывание по Start Condition, и на этом все кончается. Прерывания дальше уже не срабатывают, то есть слэйв не подтверждает передачу ему адреса. И дальше все стопорится. Самое характерное, что если прописать в обработчике прерываний все коды возможных ошибок то он не заходит ни по одному из них. Форумчане, помогите разобраться с ситуацией

CODE
#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
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 20:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01326 секунд с 7
ELECTRONIX ©2004-2016