V
V
Vasily F2017-01-22 13:45:34
Microcontrollers
Vasily F, 2017-01-22 13:45:34

Can't run I2C(TWI) on ATmega88 controller?

soldered ATmega88PA breadboard 545dccb585d245b49a42024c6dff79e5.JPG,
here is a C program in AVRStudio 5.0 that is flashed into it (I make a slave)

#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;
      }
    }
  }
}

The task is to connect Arduino master - ATmega88PA slave
The part that Arduino does is checked - it works
But the slave does not seem to accept interrupts
What else can be done to make it work?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question