@Vasilii_B2
Разрабатываю ПО и электронику

Не могу запустить I2C(TWI) на контроллере ATmega88?

распаяная макетка ATmega88PA 545dccb585d245b49a42024c6dff79e5.JPG,
вот программа на Си в AVRStudio 5.0 которая в нее прошита (делаю слейв)
#define F_CPU 12000000UL // 1MHz - по умолчанию выставлено в железе
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define ME_ADDR 8 //0b00001000 

#define LED_ON	1
#define LED_OFF	2

unsigned char data, flag_new_data=0, status_led=0, stat; ///
unsigned short tek_delay, ddelay=5000;

unsigned char I2C_GetStatus(void) {      //чтение статуса
unsigned char status;      //переменная хранения
status = TWSR & 0xF8;    //маска
return status;
}
 
void I2C_Init (void) {    //инициализация I2C как приемника
TWAR=ME_ADDR;// адрес для обращения
TWCR=(1<<TWEA)//разрешаем подтверждение
|(1<<TWEN)//включаем модуль TWI
|(1<<TWIE)//разрешаем прерывание
|(0<<TWSTA) // формирeт старт // это типа для мастера
|(0<<TWSTO) // сделать Stop. 
|(1<<TWINT); // флаг прерывания. Сброс его означает что конечный автомат провернется дальше, а прерывание будет снова уловлено
}
 
ISR(TWI_vect) {
stat=I2C_GetStatus();	
if((stat==0x80) || (stat==0x88)) { //пришли данные от ведущего (0x80 - приняли очередной байт, 0х88 - приняли последний байт)
   data=TWDR;     ///читаем значение
   flag_new_data=1;
   }
TWCR|=(1<<TWINT);  //сбрасываем флаг

//TWCR = 	(0<<TWSTA)|
//		(0<<TWSTO)|
//		(1<<TWINT)|
//		(1<<TWEA)| // Enable ACK. Разрешение ответа ACK. Если его включить, то автомат TWI будет отзываться на свой адрес, а также давать ACK во всех случаях когда этого требует протокол. Скажем, после прием байта. Если нам надо послать NACK то бит не ставим.
//		(1<<TWEN)|
//		(1<<TWIE);
}
  
void set_led(short set_l){
if(set_l==LED_OFF) {      // Setting pin PC0 low in order to turn off LED.
	PORTC &= ~(1 << PORTC0);
	return;
	}	 	
if(set_l==LED_ON) {   //Setting pin PC0 high in order to turn on LED.
	PORTC |= (1 << PORTC0);
	}	
}
  
int main(void)
{
DDRC = 0x1; //	делаем PC0 - output
set_led(LED_ON);
_delay_ms(2000);
set_led(LED_OFF);
_delay_ms(2000);	 
I2C_Init();//инициализация модуля
sei();//разрешение глобальных прерываний
while(1){
	if(tek_delay < ddelay) {
		tek_delay++;
		_delay_ms(1);
		}		
	else {
		if(status_led==0) {
			set_led(LED_ON);
			tek_delay=0;
			status_led=1;
			}
		else {
			set_led(LED_OFF);
			tek_delay=0;
			status_led=0;
			}			
		}
	if(flag_new_data==1){
		flag_new_data=0;
		if(data==23) {
			ddelay=300;
			tek_delay=0;	
			}
		if(data==114) {
			ddelay=1000;
			tek_delay=0;
			}
		}
	}
}

Задача соединить Ардуино мастер - ATmega88PA слейв
Часть которую делает Ардуино проверяно - работает
А вот слейв не как будто не принимает прерывания
Что можно еще сделать чтобы заработало?
  • Вопрос задан
  • 321 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы