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

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

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а что? должен?

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

А поточнее можно? Чей последовательный порт? У тиньки порта в приципе нет. У наны как програматора то же не должно. Так что ответ на ваш вопрос - да, нормально. Из чистой тиньки ничего выходить не должно. Для програмирования 85 с наной должны быть соеденены 5 проводов. 

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

Все соединено, все программируется, значит просто порта нет последовательного, а я то думал)) на нанке значит отлаживать будем. Только вот вопрос ещё, можно ли ножку reset использовать для замера напряжения на батарее, вроде как её можно использовать как пин, только я не понял, что для этого надо...

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

Тут я выкладывал коротенький софтверный последовательный порт. Использую для отладки. 

http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=1...

Можно активировать ресет как порт чере фъюзы, но пропадёт возможность програмировать по SPI.

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

А если код отлаживать на другом модуле и уже полностью готовый код залить на тиньку с участком кода, преврвщающим ресет в полноценный порт?)

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

Можно залить готовый код. Проверить что работает остальное, кроме ноги ресет. Затем изменить фъюз. Нога заработает как надо, но програмирование будет потеряно. Восстановить можно полным сбросом.

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

А изменить фьюз как? И как, если что,полный сброс сделать?

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

nik182 пишет:
Восстановить можно полным сбросом.

чем сбрасывать?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Я вот эту штуку собирал, когда фузы глюканули. можно из ардуины сделать :)

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

dimax пишет:

Я вот эту штуку собирал, когда фузы глюканули. можно из ардуины сделать :)

я о том же - придётся городить балалайку на 12 вольт

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

Ну да. 12 вольтовый импульс на reset ногу и дальше  согласно даташиту.

Можно и так

https://sites.google.com/site/wayneholder/attiny-fuse-reset-with-12-volt...

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

RSTDISBL –разрешает использовать ножку Reset как еще один порт ввода-вывода.
Иногда нужная вещь, но нужно знать —
после программирования RSTDISBL микроконтроллер уже нельзя будет прошить последовательным программатором! Поэтому без особой надобности не трогайте его.
RSTDISBL = 1 – ножка сброса работает как сброс;
RSTDISBL = 0 – ножка сброса работает как еще один порт ввода-вывода, последовательное программирование отключено.
А в коде то правильно это как прописать?

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

В коде ничего прописывать не надо. Фъюзы меняются програматором.   

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

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

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

Уже сказали, ничего в скетче прописываиь не надо. Надо скачать любую GUI-оболочку для консольной утилиты Avrdude (например Sina Prog, Avrdude Prog и др.) и прошить фьюзы через них. Или научиться пользоваться Avrdude через консоль. 

В гугле полно информации, ищущий да обрящет.

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

Как понимаю проще скачать. Там, как понимаю, выбираю тип МК, жму галки?)

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

Но для этого програматор покупать придётся или нанка таки покатит?

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Unikolai пишет:
Но для этого програматор покупать придётся или нанка таки покатит?

не придётся - придётся купить новую голову.

Клапауций 232 пишет:

dimax пишет:

Я вот эту штуку собирал, когда фузы глюканули. можно из ардуины сделать :)

я о том же - придётся городить балалайку на 12 вольт

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

Unikolai пишет:
Там, как понимаю, выбираю тип МК, жму галки?)

Да, принцип примерно такой. Выбрать МК, выставить нужные фьюзы (галками или через различные опции выбора, зависит от программы) и нажать кнопку, чтобы прошить выставленные фьюзы.

Только, как уже сказали, если выставить фьюз RSTDISBL (Reset disable, отключить ресет) - прошить МК и фьюзы больше не сможете. Ни другой ардуиной, ни последовательным программатором.

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

А чем сейчас заливаете? Нанкой? Она полюбому Avrdude пользует для заливки. 

http://heliosoph.mit-links.info/arduinoisp-reading-writing-fuses-atmega328p/

Гугл дает кучу ссылок как фъюзы шить, это одна из них.

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

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

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

Unikolai пишет:
и вопрос так и не разъяснен, нанку то получится использовать или нет?

Да! Но после установки RSTDISBL нет.

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

В arduino ide есть скетч, после загрузки которого нагка превращается в програматор, щас просто с телефона пишу, возможности полноценно посидеть в интернете нет

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

Прекрасно, то есть мне нужно с помощью ардуино виде сделать из нанки програматор, затем ВКЛ одну из предложенные программ и пам-пам?)

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

Сделать програматор из наны. Залить работающий скетч в тинку. Проверить что работает что можно без шестой ноги.  Запустить avrdude в консоли или GUI к ней. Прошить фъюзы. 

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

Юху, надеюсь все так просто и будет) всем спасибо)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Unikolai, да получить неработающий камень -очень просто :)

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

Аха, перед тем,как это все шить я отпишусь сюда)

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

Друзья, у нас ведь сам МК проверяет напряжение питания, можно ли как-то доступ получить к этим данным?

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

static float vccRead(byte us =250) {
  ADMUX = 1<<REFS0; // опорное напряжение - Vcc
  ADMUX |= 0x0E;    // объект измерения - внутренний источник
                    // стабилизированного напряжения 1.1В
  delayMicroseconds(us);
 
  ADCSRA |= 1<<ADSC;         // запуск АЦ-преобразования
  while(ADCSRA & (1<<ADSC)); // и ожидание его завершения
  word x = ADC;
  return x ? (1100L * 1023) / x : -1;
}
 
void setup() {
  Serial.begin(9600);
  Serial.println("\n(bandgap)");
  analogRead(0);
  pinMode(13, OUTPUT);
}
 
void loop() {
  float d=vccRead()/1000;
  
  
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000/d);                       // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000/d); 
  Serial.println(d);

}

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

и такой вопрос еще у меня, как на из float = 52.4 получить по отдельности 5,2,4?

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

Зачем static float  в подпрограмме, если она често выдает миливольты? Сделайте int.

а3=10*х % 10;

а2=х  %10;

а1=х/10 %10;

 

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

ну это все верно? или може лучше? точность же здесь получается будет значительно больше, чем если бум использовать аналогрид? используя еще и при том при сем доп аналоговый вход

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

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

Точность не изменится. Здесь мультиплексор переключается на внутренний источник и с ним сравнивается напряжение питания. Аналогрид в базе такого не умеет. Дополнительного входа нет, это внутреннее соединение.

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

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

почему этот код корректно "миганием" выводит напряжение на МК нанке, но на аттини мигает 2 раза и приехали...

static int vccRead(byte us = 250) {
  ADMUX = 1 << REFS0; // опорное напряжение - Vcc
  ADMUX |= 0x0E;    // объект измерения - внутренний источник
  // стабилизированного напряжения 1.1В
  delayMicroseconds(us);

  ADCSRA |= 1 << ADSC;       // запуск АЦ-преобразования
  while (ADCSRA & (1 << ADSC)); // и ожидание его завершения
  word x = ADC;
  return x ? (1100L * 1023) / x : -1;
}

int p=3;

void setup() {

  pinMode(p, OUTPUT);

 // time.begin();
}

void loop() {


  int d = vccRead() / 10;
  int j3 = d % 10;
  int j2 = d / 10 % 10;
  int j1 = d / 100 % 10;

  for (int i = 0; i < j1; i++) {
    digitalWrite(p, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(200);                     // wait for a second
    digitalWrite(p, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
  }
  delay(1000);
  for (int i = 0; i < j2; i++) {
    digitalWrite(p, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(200);                     // wait for a second
    digitalWrite(p, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
  }
  delay(1000);
  for (int i = 0; i < j3; i++) {
    digitalWrite(p, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(200);                     // wait for a second
    digitalWrite(p, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
  }
  delay(5000);
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

[quote=Unikolai]

почему этот код корректно "миганием" выводит напряжение на МК нанке, но на аттини мигает 2 раза и приехали...

[/quite]

АЦП этих МК родственны, но не одинаковы. По крайней мере по части регистров настройки, они отличаются и очень сильно. Изучайте даташиты.

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

Что делать, при подключении к тиньке библиотеки для 3231 выдает ошибку при компиляции...

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

Как понимаю из-за того, что аттини не поддерживает i2c?
В любом случае, что с этим делать?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Поддерживает ли attiny I2C, не знаю, но если аппаратно не поддерживает, а нужно - реализовать программно.

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

учите меня полностью)

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

друзья, как подключить к attiny85 rts ds3231?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Unikolai пишет:

друзья, как подключить к attiny85 rts ds3231?

вылезти из танка и сходить по ссылке https://www.google.com/search?q=arduino+attiny85+ds3231

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

эх, видимо просто не выйдет, просто эти spi? ic2 для меня лес дремучий, с чего тут начать, я даже не знаю))а в тиньке там ее что-то свое...дкрдосм короч)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Unikolai, начинать нужно с изучения языка :)

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

Часы на tiny25, c двумя кнопками, будильником - пищалкой, DS3231, большими 7 сегментами индикаторами на 595 регистрах, настройка часов, будильника. Раз в 30 сек показывает температуру. За i2c спасибо wdrakula.

#define   F_CPU 8000000UL

//Порт подключенный к ST_CP 74HC595
#define latchPin  PB3
//Порт подключенный к SH_CP  74HC595
#define clockPin  PB1
//Порт подключенный к DS 74HC595
#define dataPin  PB4

#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 IICR  1
#define IICW  0
#define I2CDelay()  wdelay_us(10)
#define SDA_Pin   0
#define SCL_Pin   2
#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()
{
   I2CInit ();
   DDRB|= 1 << latchPin ;  
   DDRB|= 1 << clockPin ;  
   DDRB|= 1 << dataPin ;   
   DDRB|= 1 << dataPin ;   
}


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 disp(byte mask)
{
    PORTB &= ~(1 << latchPin);
    shOut(dataPin, clockPin,   c[temp[0]]);  
    shOut(dataPin, clockPin,   c[temp[1]]);
    shOut(dataPin, clockPin,   c[temp[2]] | mask );
    shOut(dataPin, clockPin,   c[temp[3]]) ;  
    PORTB|= 1 << latchPin ;    
}


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);
    temp[0]=minute % 10;   temp[1]=minute /10 ;   temp[2]=hour % 10;   temp[3]=hour / 10;
    if (second % 30) {int tem; readDS3231temp(tem); temp[0]=11;   temp[1]=12 ;   temp[2]=tem % 10;   temp[3]=tem / 10;};
    if ((alm==minute)&(alh==hour))   DDRB|= 1 << alPin ;  else    DDRB &= ~(1 << alPin);
 
    if (al) {temp[0]=alm % 10; temp[1]=alm /10 ;   temp[2]=alh % 10;   temp[3]=alh / 10;};

    if (hs % 1)   
    {
       if (!al) disp(0x80); else disp(0);
    }
    else
    {
      switch (ed)
      { 
        case 0: break;
        case 1: temp[3]=10;break;
        case 2: temp[2]=10;break;
        case 3: temp[1]=10;break;
        case 4: temp[0]=10;break;
      };
      disp(0);
      DDRB &= ~(1 << 6);
    };
  }; 
    tm=millis();
    if(tm-tio > 20)
    {
      tio=tm;
     
      DDRB &= ~(1 << dataPin);
      delayMicroseconds(100);
      if (k1cnt > 5){
        if ((PINB & dataPin)==0) k1cnt++; else {if (k1cnt > 40)  key=2; else key=1;} k1cnt=0;}
      else if ((PINB & dataPin)==0) k1cnt++;                
      DDRB|= 1 << dataPin ;    
    
      DDRB &= ~(1 << clockPin);
      delayMicroseconds(100);
      if (k2cnt > 5){
        if ((PINB & clockPin)==0) k2cnt++; else {if (k2cnt > 40)  key=4; else key=3;} k2cnt=0;}
      else if ((PINB & clockPin)==0) k2cnt++;                
      DDRB|= 1 << clockPin ;    
    }; 

   switch(key)
   {
    case 0: break;
    case 1: if (ed>0) switch (ed)
                      {
                         case 1: hour+=10;break;
                         case 2: hour++;break;
                         case 3: minute+=10;break;
                         case 4: minute++;break;
                       };
             if (minute>59) minute-=60; 
             if (hour>23) hour-=24; 
             break;
     case 2: ed++; if (ed>3) { ed=0; setDS3231time(second, minute, hour, dayOfWeek, dayOfMonth, month,year);};break;          
     case 3: if(al>0) switch (al)
                       {
                         case 1: alm++;break;
                         case 2: alm+=10;break;
                         case 3: alh++;break;
                         case 4: alh+=10;break;
                       };
             if (alm>59) alm-=60; 
             if (alh>23) alh-=24; 
             break;
      case 4:  al++; if (al>3) al=0; break;
   };    
   key=0;
 }
}



 

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

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

ATMEGA328P-AU

ATMEGA48V-10PU

ATmega88PA-PU

думал еще о 

ATtiny2313V-10PU, так как пинов мне таки не хватает чуть прям, но там как понимаю, тоже не ic2..

подскажите в общем, что лучше

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

пугающе) но щас попробуемс разобраться)

этот код закомпилировался)

ох уж мне этот низкоуровневый язык...

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

хотя бы то, что отностится совмещения тии и ic2

ну или не знаю, черканите отдельный код, чтобы где бы просто запрашивалось время с lc3231?ds ; знаете, что копировать из вышеукащанного)

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

Я автор этой версии софт и2с. Что непонятно? ИМХО там никаких коментов не надо. Просто по стандарту и2с протокол для мастера написан. Но ты не стесняйся, спрашивай.

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

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

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

Из loop выкинуть всё кроме

 byte  key, second, minute, hour, dayOfWeek, dayOfMonth, month, year;

и 

readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,&year);

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

//Порт подключенный к ST_CP 74HC595
#define latchPin  PB3
//Порт подключенный к SH_CP  74HC595
#define clockPin  PB1
//Порт подключенный к DS 74HC595
#define dataPin  PB4

#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 IICR  1
#define IICW  0
#define I2CDelay()  wdelay_us(10)
#define SDA_Pin   0
#define SCL_Pin   2
#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()
{
   I2CInit ();
   DDRB|= 1 << latchPin ;  
   DDRB|= 1 << clockPin ;  
   DDRB|= 1 << dataPin ;   
   DDRB|= 1 << dataPin ;   
}


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 disp(byte mask)
{
    PORTB &= ~(1 << latchPin);
    shOut(dataPin, clockPin,   c[temp[0]]);  
    shOut(dataPin, clockPin,   c[temp[1]]);
    shOut(dataPin, clockPin,   c[temp[2]] | mask );
    shOut(dataPin, clockPin,   c[temp[3]]) ;  
    PORTB|= 1 << latchPin ;    
}


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

в таком случае пока получается так?