attiny85 и последовательный порт

nik182
Offline
Зарегистрирован: 04.05.2015

Можно так. Только вывести время осталось.

Unikolai
Offline
Зарегистрирован: 21.09.2016
#define IICR  4
#define IICW  5

что значат эти две строчки?

#define SDA_Pin   0
#define SCL_Pin   2

вот эти две отвечают за ноги мк, к которым будут подкл часы?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Unikolai пишет:

#define IICR  4
#define IICW  5

что значат эти две строчки?

#define SDA_Pin   0
#define SCL_Pin   2

вот эти две отвечают за ноги мк, к которым будут подкл часы?

первые две написаны неправильно, должно быть 1 и 0,

но их nik182 не использует, и тебе не нужно.

можешь убрать.

а SDA_Pin и SCL_Pin это номера ног I2C, как ты назывешь"к которым часы подлючены". В данном случае PB0 и PB2.

Unikolai
Offline
Зарегистрирован: 21.09.2016

спасибо

а можно ведь этот код отладить на нанке? подключать только к пинам всем, кроме 4 и 5(которые ворде как обычо с ic2?) сам щас проверить не могу, чтобы потом врем не терять

 

Unikolai
Offline
Зарегистрирован: 21.09.2016
#define   F_CPU 8000000UL



#define alPin  PB5


#define _NOP() asm volatile("nop")
#define LOOP_CYCLES 8
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))

inline __attribute__((gnu_inline)) void asm_delay(uint16_t delay) {
  uint16_t u = us(delay);
  do _NOP(); while (delay--);
}

#define wdelay_us(x)  asm_delay(us(x))
#define wdelay(x) delay(x)


#define I2CDelay()  wdelay_us(10)
#define SDA_Pin   PC2
#define SCL_Pin   PC1
#define I2C_in    PINB
#define I2C_out   PORTB
#define I2C_dir   DDRB

#define SDA_In()    (I2C_in & (1<<SDA_Pin))
#define SCL_In()    (I2C_in & (1<<SCL_Pin))

#define DS3231_I2C_ADDRESS 0x68

inline void SDA_Hi()  {
  I2C_out |= (1 << SDA_Pin);
  I2C_dir &= ~(1 << SDA_Pin);
}
inline void SDA_Lo()  {
  I2C_out &= ~(1 << SDA_Pin);
  I2C_dir |= (1 << SDA_Pin);
}
inline void SCL_Hi()  {
  I2C_out |= (1 << SCL_Pin);
  I2C_dir &= ~(1 << SCL_Pin);
}
inline void SCL_Lo()  {
  I2C_out &= ~(1 << SCL_Pin);
  I2C_dir |= (1 << SCL_Pin);
}

void I2CInit (void)
{
  SDA_Hi();
  SCL_Hi();
}
void I2CStart (void)
{
  SCL_Hi();
  //while (!SCL_In());
  I2CDelay();
  SDA_Lo();
  I2CDelay();
  SCL_Lo();
}

void I2CStop (void)
{
  SCL_Lo();
  SDA_Lo();
  I2CDelay();
  SCL_Hi();
  //while(!SCL_In());
  I2CDelay();
  SDA_Hi();
  I2CDelay();
}

boolean I2CWrite(byte b)
{
  byte i = 1 << 7;
  boolean ack = 0;
  while (i)
  {
    //I2CDelay();
    if (b & i) SDA_Hi(); else SDA_Lo();
    I2CDelay();
    SCL_Hi();
    I2CDelay();
    SCL_Lo();

    i >>= 1;
  }
  SDA_Hi();
  I2CDelay();
  SCL_Hi();
  // while(!SCL_In());

  if ( SDA_In() == 0 ) ack = 1;
  I2CDelay();
  SCL_Lo();
  SDA_Hi();
  return ack;
}

byte I2CRead(boolean ack)
{
  byte i = 8;
  byte b = 0;
  while (i--)
  {
    b <<= 1;
    SCL_Lo();
    SDA_Hi();
    I2CDelay();
    SCL_Hi();
    //while(!SCL_In());
    if (SDA_In()) b |= 1;
    I2CDelay();
    SCL_Lo();
  }
  if (ack) SDA_Lo();
  else SDA_Hi();
  I2CDelay();
  SCL_Hi();
  //while(!SCL_In());
  I2CDelay();
  SCL_Lo();
  return (b);
}
/*


*/
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(0);
  I2CWrite(decToBcd(second)); // set seconds
  I2CWrite(decToBcd(minute)); // set minutes
  I2CWrite(decToBcd(hour)); // set hours
  I2CWrite(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  I2CWrite(decToBcd(dayOfMonth)); // set date (1 to 31)
  I2CWrite(decToBcd(month)); // set month
  I2CWrite(decToBcd(year)); // set year (0 to 99)
  I2CStop ();

}


void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(0);
  I2CStop ();
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
  *second = bcdToDec(I2CRead(1) & 0x7f);
  *minute = bcdToDec(I2CRead(1));
  *hour = bcdToDec(I2CRead(1) & 0x3f);
  *dayOfWeek = bcdToDec(I2CRead(1));
  *dayOfMonth = bcdToDec(I2CRead(1));
  *month = bcdToDec(I2CRead(1));
  *year = bcdToDec(I2CRead(0));
  I2CStop ();
}

void readDS3231temp(int  *temp)
{
  byte m, l;
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(0x11);
  I2CStop ();
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
  m = bcdToDec(I2CRead(1));
  l = bcdToDec(I2CRead(0));
  *temp = m * 100 + (l >> 6) * 25;
  I2CStop ();
}

volatile long Decimal;

byte  temp[4];// на 4 цифр разложим число
static int8_t c[] = {

  0b00111111, // 0
  0b00000110,   // 1
  0b01011011,    // 2
  0b01001111,   // 3
  0b01100110,    // 4
  0b01101101,   // 5
  0b01111101,     // 6
  0b00000111,     // 7
  0b01111111,    // 8
  0b01101111,    // 9
  0b01000000, //minus
  0b00000000, //" "
  0b01100111, //"o"
  0b00111001 //"C "

};//0~9,A,b,C,d,E,F,"-"," " и другие символы


void setup()
{Serial.begin(9600);
  pinMode(2, OUTPUT);
  I2CInit ();
}


void shOut(uint8_t dPin, uint8_t cPin, uint8_t val)
{
  uint8_t i;
  for (i = 0; i < 8; i++)
  {
    if ( !!(val & (1 << (7 - i))))  DDRB |= 1 << dPin ; else  DDRB |= 1 << dPin ;
    delayMicroseconds(10);
    PORTB |= 1 << cPin ;
    delayMicroseconds(10);
    PORTB &= ~(1 << cPin);
  }
}




void loop()
{
  static byte k1cnt, k2cnt;
  static byte hs, ed, al, alm, alh;
  byte  key, second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  static long tm, tio, tdo;
  k1cnt = k2cnt = key = ed = al = 0; alm = alh = 10;




  while (1)
  {
    tm = millis();
    if (tm - tdo > 500)
    { tdo = tm; hs++;
 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,&year);

    
      int d = int(bcdToDec(I2CRead(1)));
      Serial.println(second);
      Serial.println(bcdToDec(I2CRead(1) & 0x7f));
      Serial.println(bcdToDec(I2CRead(1)));
      int j1 = d % 10;
      light(j1,2);
      int j2 = d / 10 % 10;
       light(j2,2);
       int j3 = d / 100 % 10;
       light(j3,2);






    };
  }
}
void light(int t, int p) {
  for (int i = 0; i < t; i++) {
    digitalWrite(p, HIGH);
    delay(200);
    digitalWrite(p, LOW);
    delay(200);
  }
  delay(1000);
}


что я делаю не так? часы подключены по питанию, подключены порты выводов к а1 и а2 нанки, но выдает только лиш

5
85
85
165
85
85
165
85
85
165
85
85
165
85
85
165
85
85
165
 
Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Хардварный I2C подключён к PC4, PC5. На Arduino NANO это А4, А5.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Хм, я думал таким Макаром получится любой пин использовать для связи по ic2...а на аттини 85 тогда куда, к 0 и к 2, как у автора изначально?

nik182
Offline
Зарегистрирован: 04.05.2015

Отлаживал на нане. Все отлично отладилось.

Для наны А0 А1 должно быть

#define   F_CPU 16000000UL

#define I2C_in    PINС

#define I2C_out   PORTС

#define I2C_dir   DDRС

Использовать можно любой пин. Порты надо правильно прописывать и следить, что бы другие части программы их не задевали.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Получается я обращался не к тем пинас? Если бы захотел использовать d2 и d3, нужно было бы здесь #define I2C_in PINС ,,pin d указать? А первая строка что меняет?

nik182
Offline
Зарегистрирован: 04.05.2015

Первая строка это частота процессора. От них зависят тайминги протокола. Порты и пины это разные стороны одного и того же. Взял пин от порта - обращайся к регистрам этого порта а не чужого. d2 d3 это пины PD2 PD3 порта D. Нужно использовать PIND,PORTD,DDRD.  

Unikolai
Offline
Зарегистрирован: 21.09.2016

А тайминги только на скорость выполнения влияют?

Unikolai
Offline
Зарегистрирован: 21.09.2016

как отключить вывод портов перед переходм в спящий режим?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Что значит отключить вывод портов?

Unikolai
Offline
Зарегистрирован: 21.09.2016

в рекомендациях по снижению энергопотребления сказано, что нужно отключить порты, чтобы нмичего не потребляли они, ибо аже если на выводах нет ничего(ничего к нему не подкл)он все равно может потреблять так

я как понял, нужно пины в low dвыставить

Unikolai
Offline
Зарегистрирован: 21.09.2016

друзья, тоска, такое дело, подключил часики я все хорошо, рабатают(огромное спасибо всем и в отдельности тем, кто кинул кодом) если часики питать напрямую от gnd и vcc, то все гуд, но если я так их буду питать, то они будут оч много кушать, поэтому мой план таков - патаю их через пин, на который перед считыванием инфы подаю 1(4,4 вольта), но это все теория, так у меня получалось, но только на нанке, при подлючении vcc часов к пину обычному и при попытке залить код, выдает ошибку при загрузке скетча

avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.
 
Произошла ошибка при загрузке скетча
 если разъединить связь между vcc часов и пином, то все норм, на тньке у меня, ксати, тоже получалось, но сначала я доставал это добро., затем, после загрузки, соединял
может где-то какой - нибудь резистр нужен? или конденсатор между ними
усиленно жду ответа)_

 

nik182
Offline
Зарегистрирован: 04.05.2015

Обычно ставят резистор 1к для развязки. 

Unikolai
Offline
Зарегистрирован: 21.09.2016

соединил пин с землей через 5,1 к резюк, та же история..

nik182
Offline
Зарегистрирован: 04.05.2015

Програматор должен подключаться прямо к ноге, всё остальное через 1К. Иначе програматор должен персилить остальную перефирию при програмировании. 

Unikolai
Offline
Зарегистрирован: 21.09.2016

я уточню: то есть мне нужно от пина, с которого буду питать часы кинуть резюк именно на 1к, и от этого же пина я кидаю проводок на питание часов?

nik182
Offline
Зарегистрирован: 04.05.2015

Нет, питание часов через 1к и обязательно за ним должна стоять емкость на 10 мкф или больше. Ни каких больше проводов кидать не надо. У вас же проблема с заливкой кода при подключенных часах? В таком варианте её не будет. 

Unikolai
Offline
Зарегистрирован: 21.09.2016

Да, все верно) а на энергопотреблении этот резюк на 1 к сказываться не будет? Или напряжение только теряться будет? Спасибо за ответы на мои, как кому-то может показаться, глупые вопросы)

nik182
Offline
Зарегистрирован: 04.05.2015

Теряться будет около 0.1 вольта. На энергопотребление влиять не будет.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Я по всякому пробовал, в итоге остался у меня только один резюк, с ним вроде все работает, как нужно было правильно подключить конденсатор?

nik182
Offline
Зарегистрирован: 04.05.2015

Между плюсом и минусом часов. Если он ещё не стоит не плате часов.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Хорошо, спасибо, поставим, а насколько рационально будет использовать какой-нибудь транзистор для замыкания цепи не на прямую?

nik182
Offline
Зарегистрирован: 04.05.2015

Здесь такой же транзистор. Смысл что то дополнительного ставить? Ток часов существенно меньше максимально допустимого.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Просто тема тут была, там вовсе рекомендовали ставить стабилизатоп

Unikolai
Offline
Зарегистрирован: 21.09.2016

Друзья, пипец, если вставить эту строчку в setup I2CInit (); 221 строчка из кода выше, то энергопотребление ниже 300 мкА не опускается...ввожу тиньку в pwr down, не понимаю, почему так, помогите разобраться, может что-то где-то подправить в коде? (Без этой строчки все зорошо) ну не считая того, что я не могу считывать время с часов)))

nik182
Offline
Зарегистрирован: 04.05.2015

Эта команда переключает ноги на выход. Если что то к ним подключено и потребляет ток, то этот ток не будет зависить от спящего режима. Перед входом в спящий режим нужно ноги перевести в режим входа. После выхода из спящего режима ещё раз дать команду инициализации.

Unikolai
Offline
Зарегистрирован: 21.09.2016

То есть на всякий случай можно все ноги перевести в режим low? Только тогда какой смысл в том, что мы что-то делаем в сетупе? Акромя сетупа вообще разве можно менять ноги - на вход или на выход они работают? Как это правильно сделать?
Или может эти пины как-то в low ставить?

nik182
Offline
Зарегистрирован: 04.05.2015

Вообще I2CInit() какраз и переводит ноги на вход и включает подтягивающие резисторы. Попробуйте перед сном подтягивающие резисторы выключить командами

I2C_out &= ~(1 << SDA_Pin);

I2C_out &= ~(1 << SCL_Pin);

После сна вызвать I2CInit()

Unikolai
Offline
Зарегистрирован: 21.09.2016

Nik182, спасибо, попробую, надеюсь поможет, я тут почитал за это время, по идее я ведь могу в ноль поставить эти пины, типа диджиталврайт(сда_пин, лов) а перед запросм времени как раз таки запускать айси2клиент? Да и (как пониааю, ваш код делает примерно то же самое/)вообще в лупе можно спокойно менять пины на вход//на выход? Уточняю)

nik182
Offline
Зарегистрирован: 04.05.2015

Да делают то же самое, только одной командой, digitalWrite длинно и долго. 

Менять направление можно в любой момент. Часто, когда ног мало вывод и ввод делают через одну ногу. Соответственно в цикле приходится переключать неправление. Перед обменом запускать I2CInit();

Unikolai
Offline
Зарегистрирован: 21.09.2016

А можете вы расписать строчки кода в вашем предыдущем сообщении? Что значит каждый символ?

nik182
Offline
Зарегистрирован: 04.05.2015

Есть тема, где это уже всё расписано и даже больше - разные способы записи одного и того же

http://arduino.ru/forum/programmirovanie/bitovye-operatsii

Хорошо расписано у них 

https://www.arduino.cc/en/Reference/BitwiseXorNot

https://www.arduino.cc/en/Reference/BitwiseAnd

Unikolai
Offline
Зарегистрирован: 21.09.2016

Спасибо, почитаем) ваш совет помог) только я пришел к выводу, ну собственно в даташите это тоже указано, что эта собака вотчдог кушает примерно 5 микроамперы....можно может поставить внешний кварц и уменьшить это значение?

Unikolai
Offline
Зарегистрирован: 21.09.2016
#define   F_CPU 8000000UL


#define alPin  PB5


#define _NOP() asm volatile("nop")
#define LOOP_CYCLES 8
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))

inline __attribute__((gnu_inline)) void asm_delay(uint16_t delay) {
  uint16_t u = us(delay);
  do _NOP(); while (delay--);
}

#define wdelay_us(x)  asm_delay(us(x))
#define wdelay(x) delay(x)


#define I2CDelay()  wdelay_us(10)
#define SDA_Pin   PB2//присваиваем 2 пин в регистре в, на этот порт мы посылаем данные-пакеты
#define SCL_Pin   PB1//присваиваем 1 пин в регистре в, на этот мы посылаем импульсы
#define I2C_in    PINB//?
#define I2C_out   PORTB//для выставления low/high пинам в регистре
#define I2C_dir   DDRB//обращение к регистру для задания пинам input/output

#define SDA_In()    (I2C_in & (1<<SDA_Pin))//"(1<<SDA_Pin)" пин у нас в SDA_Pin - 2, в двоичной это 0010, сдвиг делаем и получаем 0100, но для чего, не понимаю ибо зачем PINB нужен не ясно, вроде как отвечает за ответы от ведомого, получаем бит записи/чтения, получается единица будет только там, где в обоих байтах 1
#define SCL_In()    (I2C_in & (1<<SCL_Pin))

#define DS3231_I2C_ADDRESS 0x68

inline void SDA_Hi()  {//эта ф-я подтягивает к плюсу линию sda
  I2C_out |= (1 << SDA_Pin);//SDA_Pin-0010, опять таки, зачем делаем сдвиг?
  I2C_dir &= ~(1 << SDA_Pin);//vs что, каждый раз переопределяем, работает пин на вход или выход?
}
inline void SDA_Lo()  {//эта ф-я подтягивает к минусу линию sda
  I2C_out &= ~(1 << SDA_Pin);
  I2C_dir |= (1 << SDA_Pin);
}
inline void SCL_Hi()  {//эта ф-я подтягивает к плюсу линию scl
  I2C_out |= (1 << SCL_Pin);
  I2C_dir &= ~(1 << SCL_Pin);
}
inline void SCL_Lo()  {//эта ф-я подтягивает к минусу линию scl
  I2C_out &= ~(1 << SCL_Pin);
  I2C_dir |= (1 << SCL_Pin);
}

void I2CInit (void)//тут мы как раз таки благодаря вышесозданным ф-ям определяем, в каком регистре и какие пины будут настороены на вход и выход и плюс будет там или сям
{
  SDA_Hi();
  SCL_Hi();
}
void I2CStart (void)
{
  SCL_Hi();//выполняем условие старта, выводим scl в высокий уровень
  //while (!SCL_In());
  I2CDelay();
  SDA_Lo();//опускаем в ноль sda
  I2CDelay();
  SCL_Lo();//ну и в ноль scl,, условия старта врод как выполнены
}

void I2CStop (void)//пссле завершения передачи пакета
{
  SCL_Lo();//опускаем(ведущий)
  SDA_Lo();//опускаем(ведущий)
  I2CDelay();//в этот момент ведомый должен послать аск или наск, в зависимости от того, все передал или нет
  SCL_Hi();//ведущий подымает импульсную линию и читает, что послал ведомый
  //while(!SCL_In());
  I2CDelay();
  SDA_Hi();//так как у нас ф-я ля остановки, то вполняем условия стопа, линия scl уже поднята, поднимаем sda? условия стопа выполнены
  I2CDelay();
}

boolean I2CWrite(byte b)//вот тут начинается аврал, эта штука принимает на вход весь бит
{
  byte i = 1 << 7;//получаем из этого 10000000
  boolean ack = 0;
  while (i)//это опять какая-то сокращенная запись, какое тут условие, пока что? не закончатся биты из байта?
  {
    //I2CDelay();
    if (b & i) SDA_Hi(); else SDA_Lo();//не понимаю, что тут за условие if, сокращенное
    I2CDelay();
    SCL_Hi();
    I2CDelay();
    SCL_Lo();

    i >>= 1;
    //как понимаю, просто генерирует 8 импульсов на линии scl? а на линию sda подтягивает к +, если бит в обрабатываемом байте равен 1
  }
  SDA_Hi();//посылаем последний бит, отвечающий за чтение/запись, так как хай, то чтение
  I2CDelay();
  SCL_Hi();//считываем последний бит
  // while(!SCL_In());

  if ( SDA_In() == 0 ) ack = 1;//что такое SDA_In() так же остается непонятным
  I2CDelay();
  SCL_Lo();
  SDA_Hi();
  return ack;
}

byte I2CRead(boolean ack)//принимаем на вход единицу или ноль из предыдуще ф-и
{
  byte i = 8;
  byte b = 0;
  while (i--)//тоже сокращенное что-то, не понятно, но скорее всего пока i>=0
  {
    b <<= 1;//b =b<< 1;
    SCL_Lo();
    SDA_Hi();
    I2CDelay();
    SCL_Hi();
    //while(!SCL_In());
    if (SDA_In()) b |= 1;//какое-то непонятное условие,,и если вполняется, то из 1 получаем 11, далее 111 и тд
    I2CDelay();
    SCL_Lo();
  }
  if (ack) SDA_Lo();
  else SDA_Hi();
  I2CDelay();
  SCL_Hi();
  //while(!SCL_In());
  I2CDelay();
  SCL_Lo();
  return (b);
}

я комменитровал как мог, помогите разобраться

nik182
Offline
Зарегистрирован: 04.05.2015

Возьмите описание протокола i2c. Там всё расписано. Здесь реализация. К строке 34 - линию можно занимать только при передаче. Потом надо отдавать другим устройствам, их на линии может быть несколько. Делается это переводом режима ноги на вход. К строке 33 - стандартная запись установки бита. Реально сдвига нет. Бит определяется на этапе компиляции. Позволяет легко и понятно использовать стандартные определения битов.
80,108 пока переменная больше нуля.
104 ask не из предыдущей функции. Это признак последнего байта в посылке.
SDA_Hi SDL_Hi отпускание линии. Линия подтянута резисторами к +. Поэтому отпускание переводит в высокое состояию линию.

Unikolai
Offline
Зарегистрирован: 21.09.2016

спасибо!)

хм, вчера сидел с нанкой, выводил в мониторинг значения, вроде сдвиг был..но щас не смогу вспомнить, то есть если мы запишем вот это "I2C_out |= (1 << SDA_Pin);//SDA_Pin-0010, опять таки, зачем делаем сдвиг?"

вот так

I2C_out =I2C_out|SDA_Pin

будет то де самое?

получается нормальное бездействнное состояние у нас это когда оба провода подтянуты к +, как понял

nik182
Offline
Зарегистрирован: 04.05.2015

Unikolai пишет:

спасибо!)

хм, вчера сидел с нанкой, выводил в мониторинг значения, вроде сдвиг был..но щас не смогу вспомнить, то есть если мы запишем вот это "I2C_out |= (1 << SDA_Pin);//SDA_Pin-0010, опять таки, зачем делаем сдвиг?"

вот так

I2C_out =I2C_out|SDA_Pin

будет то де самое?

получается нормальное бездействнное состояние у нас это когда оба провода подтянуты к +, как понял

Посмотрите файл c:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr\iotnx5.h там описаны все регистры. SDA_pin объявлен как PB2. PB2 объявлен как 2. I2C_out =I2C_out| 2 не равно I2C_out |= (1 << 2); 

(1 << 2) равно 4 или В00000100;  2 равно В00000010

Бездействие = единице при передаче = подтянуты к + = состояние вход пина для данной реализации i2c

Написав  I2C_out |= (1 << SDA_Pin); мы не делаем сдвиг. Компилятор преобразует такую запись к виду  I2C_out |=  В00000100 - можно сразу так написать, но это будет ненаглядно.

Unikolai
Offline
Зарегистрирован: 21.09.2016

Понял)

а ф-я для того, чтоб задать ежесекундное срабатыванеибудильника будет так выглядеть?

void setDS3231alarm()
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(0x07);
  I2CWrite(1);
  I2CWrite(1);
  I2CWrite(1);
  I2CWrite(1);
  
  I2CStop ();

}

nik182
Offline
Зарегистрирован: 04.05.2015

Похоже. Только писать надо не единицы, а 0х80 или В10000000. Почему сообразите?

Unikolai
Offline
Зарегистрирован: 21.09.2016

Наверное потому что единицу мы должны в начало старш его полубайта записать, как понимаю можно еще сделать 1<<7

void setDS3231alarm()
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(0x07);
  I2CWrite(B10000000);
  I2CWrite(B10000000);
  I2CWrite(B10000000);
  I2CWrite(B10000000);
  
  I2CStop ();

}

только вот почему то изначально на sqw у нас 5 в..

nik182
Offline
Зарегистрирован: 04.05.2015

Осторжнее! 10000000 не равно В10000000. Очень сильно не равно. Я предпочитаю 0х80.

nik182
Offline
Зарегистрирован: 04.05.2015

Может быть потому что в даташите написано активный низкий?

Unikolai
Offline
Зарегистрирован: 21.09.2016

То есть при срабатывании будильника пин sqw будет прижат к 0?

nik182
Offline
Зарегистрирован: 04.05.2015

Да.

Unikolai
Offline
Зарегистрирован: 21.09.2016

хм, дак как тогда повесить прерыванеи на мк...инвертировать чтоли? там же вроде дуинка будится в том слуаче, если на не + подать, на ногу +

nik182
Offline
Зарегистрирован: 04.05.2015

http://arduino.ru/Reference/AttachInterrupt

Здесь описание прерываний. Вaм нужна мода FALLING.

Unikolai
Offline
Зарегистрирован: 21.09.2016

ааа) вон оно что) а это не будет расходовать лишнюю энергию, то, чтьо там почти всегда будет +

и еще такой вопрос есть, может таки моэжно сделать так, чтобы питать 3132 не от батарейки, и как-то в сон ее вгонять, чтобы работала как от батарейки?