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

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

Unikolai пишет:

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

Откройте даташит и почитайте: 

21. Electrical Characteristics 
21.2 DC Characteristics 
Table 21-1. DC Characteristics. TA = -40C to +85C

 

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

Unikolai пишет:

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

А в чём проблема? Выньте батарейку и подайте на те выводы питание с другого источника.

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

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

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

я установил 0x7,0x8,0x9,0xA в 1, светодиод горит всегда, видимо low подается оч короткий, что глазом по светодиоду не понять

B00000111,0x0E вот это прописываю по этому адресу, вроде как все прерывания должны быт разрешены

замигал!!! ахаха, всем спасибо!

а вот само это изменение с 1 на 0, оно сколько длится?

бит 6, bbsqw разрешает преревания при питании от батарейки..но сколько кушать будут все часы....

 

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

друзья, у меня проблемы)

void set_register(byte i, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite(i); // set seconds
  I2CStop ();

}




void setup()
{ Serial.begin(9600);
  I2CInit ();
  set_register(B00000000, 0x0E);
  set_registers(0, 0, 0, 0,0x7);
}
void loop()
{
  static byte hs, ed, al, alm, alh;
  byte  key, second, minute, hour, dayOfWeek, dayOfMonth, month, g, year;
  static long tm, tio, tdo;
  tm = millis();
  if (tm - tdo > 500)
  { tdo = tm; hs++;
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print("sek-");
    Serial.println(second);
    Serial.print("min-");
    Serial.println(minute);
    Serial.print("hou-");
    Serial.println(hour);
    read_register(&g, 0x7);
    Serial.println(g);
    read_register(&g, 0x8);
    Serial.println(g);
    read_register(&g, 0x9);
    Serial.println(g);
    read_register(&g, 0x0A);
    Serial.println(g);
    read_register(&g, 0x0E);
    Serial.println(g,BIN);
  };
}

void set_registers(byte f, byte m, byte y, byte d,byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite(decToBcd(f)); //
  I2CWrite(decToBcd(m)); //
  I2CWrite(decToBcd(y)); //
  I2CWrite(decToBcd(d)); //
  I2CStop ();

}
void read_register(byte *second, byte *adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CStop ();
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
  *second = bcdToDec(I2CRead(0));
  I2CStop ();
}

вроде как делаю все, чтобы только светодио, подключенныйна sqw мигать перевтал(срабатывание будильника), а он все равно продолжает мигать, в чем ошибка?

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

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

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

Напишите что вы делаете, что бы перестал мигать светодиод. Алгоритм работы программы. Из приведённого листинга непонятно что делает программа. 

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

чё за фигня в строке 60? Адрес почему тоже как указатель определен? ;)

Так работать не будет.

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

строка 17, устанавливаю регистр "control так, чтобы" биты, отвечающие за разрешение прерываний в принципе и отдельные разрешения прерываний от будильников были установлены в 0(сама ф-я находится выше)

далее, строка 18, в двтвшите укащано, что чтоы будульник срабытывал каждую секунду, нужно все эти регстры установить в 1, чтобы будильник срабытывал, устанавливаю в 0, чтобы ничего не срабатывало, в строке 48 сама ф-я

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

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

ничего не менял, кроме того, что звездочки убрал в последне ф-и

все ранво, собака таккая, мигает...вот что выводит консоль

sek-50
min-5
hou-0
0
0
0
0
0
0
sek-50
min-5
hou-0
0
0
0
0
0
0
sek-51
min-5
hou-0
0
0

хотя так тоде нельзя, все вернул наместо и убрал только звездочку от адреса в 60 строке

если изменить строчк17 и 18 на

set_register(B00000111, 0x0E);
  set_registers(1, 1, 1, 1, 0x7);

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

sek-52
min-12
hou-0
1
1
1
1
111
100
sek-52
min-12
hou-0
1
1
1
1
111
0
sek-53
min-12
hou-0
1
1
1
1
111
100
sek-53
min-12
hou-0
1
1
1
1
111

 

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

Unikolai пишет:

ничего не менял, кроме того, что звездочки убрал в последне ф-и

там одна звездочка нужна, а другая - нет. ;) ;) ;)

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

ну да , в итоге одну и убрал, от "adress", но все равно прос=исходит то, что происходит...

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

Вы в регистр Е пишете 0. Это значит, что на ноге прерывания будет булькать 1 герц в не зависимости от состояния и времени.

Bit 2: Interrupt Control (INTCN). This bit controls the INT/SQW signal. When the INTCN bit is set to logic 0, a square wave is output on the INT/SQW pin.

Bits 4 and 3: Rate Select (RS2 and RS1). These bits control the frequency of the square-wave output

RS2 RS1 SQUARE-WAVE OUTPUT FREQUENCY

0      0           1Hz

Если В0111 то переводите в режим будильника и булькать может при установке восьмых битов (не 1 а 0х80!!!!) в регистры 7,8,9,А иначе будильник никогда не сработает.

 

Unikolai
Offline
Зарегистрирован: 21.09.2016
void set_register(byte i, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite(i);
  I2CWrite(i); // set seconds
  I2CStop ();

}




void setup()
{ Serial.begin(9600);
  I2CInit ();
  set_register(B0111, 0x0E);
  set_registers(0x8,0x8,0x8, 0x8, 0x7);
}
void loop()
{
  static byte hs, ed, al, alm, alh;
  byte  key, second, minute, hour, dayOfWeek, dayOfMonth, month, g, year;
  static long tm, tio, tdo;
  tm = millis();
  if (tm - tdo > 500)
  { tdo = tm; hs++;
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print("sek-");
    Serial.println(second);
    Serial.print("min-");
    Serial.println(minute);
    Serial.print("hou-");
    Serial.println(hour);
    read_register(&g, 0x7);
    Serial.println(g, BIN);
    read_register(&g, 0x8);
    Serial.println(g, BIN);
    read_register(&g, 0x9);
    Serial.println(g, BIN);
    read_register(&g, 0x0A);
    Serial.println(g, BIN);
    read_register(&g, 0x0E);
    Serial.println(g, BIN);
    read_register(&g, 0x0F);
    Serial.println(g, BIN);
    
  };
}

void set_registers(byte f, byte m, byte y, byte d, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite((f)); //
  I2CWrite((m)); //
  I2CWrite((y)); //
  I2CWrite((d)); //
  I2CStop ();

}
void read_register(byte *second, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CStop ();
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
  *second = bcdToDec(I2CRead(0));
  I2CStop ();
}
не мигает

пробовал и так "не 1 а 0х80!!!!" и так 0х8

не горит вообще, вот


111
1
sek-29
min-12
hou-2
1000
1000
1000
1000
111
1
sek-30
min-12
hou-2
1000
1000
1000
1000
111
1
sek-30
min-12
hou-2
1000
1000
1000
1000
111
1
sek-31
min-12
hou-2
1000
1000
1000
1000
111
1
sek-31
min-12
hou-2
1000
1000
1000
1000
111
1
sek-32
min-12
hou-2
1000
1000
1000
1000
111
1
sek-32
min-12
hou-2
1000
1000
1000
1000
111
1
sek-33
min-12
hou-2
1000
1000
1000
1000
111
1
sek-33
min-12
hou-2
1000
1000
1000
1000
111
1
sek-34
min-12
hou-2
1000
1000
1000
1000
111
1
nik182
Offline
Зарегистрирован: 04.05.2015

Ещё раз. Регистры 7,8,9,А должны быть заполнены 0х80 и при чтении должны давать В10000000. (Первая таблица даташита)

Eщё два. В даташите не дана длительность сигнала прерывания и я очень подозреваю, что его длительность 1/32768 секунды. Увидеть это на светодиоде проблематично. И судя по приведённому вами выводу данных регистров будильник сработал - регистр 0xF равен 1. Это признак срабатывания будильника. Прерывание было. Ловить его надо D-тригером. Тогда диод будет секунду гореть, секунду нет. 

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

nik182, прерывание кончается тогда, когда МК сбросит флаг прерывания в часах)

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

ник, но если поставить 0х80, то в выводе мы получаем "1010000"? мне кажется тут что-то со системами напутано

то есть, поидее, если у меня прерывание и вылетело(ьуильник сработал), то светодиод на sqw как раз таки должен погаснуть и не гореть? до тех пор, пока не пропишу код по сбросу флага прерывания?

при таких данных светодиод не горит, и вроде как флаг срабатывания прерывания поднят

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

Было у меня такое предположение. И я даже склонен с ним согласиться. Смутила меня фраза даташита о выставлении прерывания If the A1IE bit is logic 1 and the INTCN bit is set to logic 1, the INT/SQW pin is also asserted - говориться, а о сбросе нет. Только о сбросе флага. И диаграммы не приведены :-(  Да и диод у Николая не горит, хотя все биты выставлены. Должен бы , если прерывание до конца флага живёт. 

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

А как подключен свето диод? Выход с открытым коллектором - диод между + и ногой. Должен гореть при срабатывании. 

С выводом вообще не понимаю. Пишем В10000000 получаем В1010000. Что то тут не понятки какие то. К сожалению я только ближе к выходным проверить это всё в железе. 

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

я попал домой, подкл вторые такие же часы, только изначально выставлчл 0х8, а потом 0х80, как только делаешь второй вариант, сразу диод не горит и влаг из регистра контроля, отвечающий за прерывания, поднимается, 0х80 это ведь в 16-тиричной?

ну и теперь походу ясно, почему у меня никак не получалось скинуть все в ноль, походу в ноль жтот флаг может скинуть только ресет и сам мк, щас попробуем

светодиод подкл между землей общей и sqw

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

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

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

О вот и ответ. Как только погас диод - в регистре 0xF появилась единица - сразу пишем 0 в 0хF регистр. Диод должен загорется.   

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

Ну так всё работает штатно. А что вы хотели?

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

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

но можно ведь эту ф-ю использовать? 

byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}
хочу вот сюда ее забубенить, чтоб пистаь все в десятичной
как здесь
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 ();

}

 

 

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

объясните, почему вы предпочитаете использзовать 0х8, в этом виде xbckf7 и уточню еще раз, это 16-тиричная?

" set_registers(B10000000,B10000000,B10000000,B10000000, 0x7);" пытаюсь забить так

сама ф-я такая

void set_registers(byte f, byte m, byte y, byte d, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite((f)); //
  I2CWrite((m)); //
  I2CWrite((y)); //
  I2CWrite((d)); //
  I2CStop ();

}

а при чтении  все равно выдает 10100000

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

Да шестнадцатеричная. Одинокие биты в ней писать легко. 0х1, 0х2, 0х4, 0х8 = В1, В10, В100, В1000. Соответственно 0х80 = В10000000. Старший бит байта. Легче нолики посчитать и не ошибиться. 

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

Наверное мне нужно в ринтлн написать не бин, а хекс)

nik182
Offline
Зарегистрирован: 04.05.2015
Unikolai
Offline
Зарегистрирован: 21.09.2016
void set_register(byte i, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite(i);
  I2CWrite(i); // set seconds
  I2CStop ();

}




void setup()
{ Serial.begin(9600);
  I2CInit ();
  set_register(B0111001, 0x0E);
  
  set_registers(0x8,B10000000,B10000000,B10000000, 0x7);
}
void loop()
{
  static byte hs, ed, al, alm, alh;
  byte  key, second, minute, hour, dayOfWeek, dayOfMonth, month, g, year;
  static long tm, tio, tdo;
  tm = millis();
  if (tm - tdo > 500)
  { tdo = tm; hs++;
  Serial.print("status_prer-");
    Serial.println(g, BIN);
  set_register(B00000000, 0x0F);
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    
    Serial.print("sek-");
    Serial.println(second);
    Serial.print("min-");
    Serial.println(minute);
    Serial.print("hou-");
    Serial.println(hour);
    read_register(&g, 0x7);
    Serial.println(g, BIN);
    read_register(&g, 0x8);
    Serial.println(g, BIN);
    read_register(&g, 0x9);
    Serial.println(g, BIN);
    read_register(&g, 0x0A);
    Serial.println(g, BIN);
    read_register(&g, 0x0E);
    Serial.println(g, BIN);
    read_register(&g, 0x0F);
    Serial.print("status_prer-");
    Serial.println(g, BIN);
    
  };
}

void set_registers(byte f, byte m, byte y, byte d, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CWrite((f)); //
  I2CWrite((m)); //
  I2CWrite((y)); //
  I2CWrite((d)); //
  I2CStop ();

}
void read_register(byte *second, byte adress)
{
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1));
  I2CWrite(adress);
  I2CStop ();
  I2CStart();
  I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
  *second = bcdToDec(I2CRead(0));
  I2CStop ();
}

 set_register(B0111001, 0x0E);

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

при питаннии от ардуины, мигает светодиод1 ыв секунду

закомментилс рочку 32 и все равно мигает.. 


rer-1001
status_prer-1001
sek-30
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-30
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-31
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-31
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-32
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-32
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-33
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
status_prer-1001
sek-33
min-8
hou-0
1010000
1010000
1010000
1010000
10011
status_prer-1001
nik182
Offline
Зарегистрирован: 04.05.2015

Нет не правилно. Третий бит дает вывод коребаний, а не прерывания. Достаточно В111. 

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

Хм..но как так? Первый бит у нас отвечает за разрешение вкл 0 буд 1бит за второй будильник 2 бит ха разрешение прерывания на выводе Sqw, по совпадении одного из будильников 3 и 4 за настройку частоты на выходе Пина 32 к 5 за преобразование температура А вот 6 бит как раз таки за разрешение прерывания на Sqw при питании от батарейки... То есть вроде как должно быть б11100010, или таки это все же не правильно? Щас только заметил, что у меня нолик вначале откуда-то взялся,,

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

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

а может биты так прописывать нужно? set_register(B01000111, 0x0E);

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

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

Шестой бит не за прерывания а за вывод частоты при установке третьего в 0. Т.е если третий  0, то шестой имеет значение. Он (шестой) так и называется Battery-Backed Square-Wave Enable  - к прерыванию не имеет никакого отношения. 

Биты имеют названия - BIT0 - LSB - самый малький, самый правый. BIT8 - MSB - самый большой - самый левый. Посмотрите в дата шите на DS3231 fig1 - 1. Вообще достаточно В101 для наличия прерываний при батарейном питании. Вы ж секундные прерывания хотите? На втором будильнике секундных прерываний нет. Второй бит не нужен.  

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

аааа, вот он, трудности перевода))спасибо)

к сожалению шнур заббыл...не получится сегодня плклпаться...

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

я как понимаю тут каждый бит соответствует одному пину тиньки85? устанаввливаем 1 и будет он ловить прерывания?

или я в дебри ухожу? может вот этого буде достточно?

int pin = 13;
volatile int state = LOW;
 
void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}
 
void loop()
{
  digitalWrite(pin, state);
}
 
void blink()
{
  state = !state;
}

еще как понял 7 бит в регисьре sreg должен бть установлен?

еще в gimsk придется поковыряться походу..

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

Да. Каждый бит этого регистра - разрешение одному пину выставлять прерывания.

Нет. attachInterupt здесь не прокатит. Он заточен под конкретные пины. Прерывания на другие нужно писать стандартными средствами AVR.

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

если я выставлю 5 бит в регистре pcmsk? то на 5 пин тиньки можно будет подавать перрывания? ии нужно писать конкретную ф-ю, еще ведь надо указать,какой тип прерываня будет понимать мк

а под стандартными средствами авр вы что подразумеваете?

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

Посмотрите этот код

http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie#comment-216742

строки 24,25 инициализация прерывания ног

строки с 35-40 обработчик прерывания.

Unikolai
Offline
Зарегистрирован: 21.09.2016
ISR (PCINT0_vect){

if (PINB&(1<<PINB4)) { return;}

TCNT1 = 0;                //reset timer - count from zero

TCCR1 = B00001011;        // prescaler on 1024, see table 12.5 of the tiny85 datasheet

  

}

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

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

Главное это ISR (PCINT0_vect) - подпрограмма обработки прерывания  от ног процессора.

if (PINB&(1<<PINB4)) { return;} если на ноге не то - выход.

Остальные строки это настройки таймера. Вам не нужны. Сюда писать ваши команды.

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

спасибо, очень помогаете)

а вот меня работа застает в расплох вновь и вновь))

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

и я как понял ISR это просто название пользовательской функции, но зачем там что то в скобках(PCINT0_vect), если она ничего не возвращает и никак не использует PCINT0_vect

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

Нет. ISR это стандартная фунция прерывания из библиотеки AVR http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Когда случается любое прерывание подпрограмма прыгает на подпрограмму ISR с именем прерывания. Если вы не описали такую подпрограмму, то прыгает на RESET!!! Имена прерываний здесь http://avrprog.blogspot.ru/2013/03/isrc.htmlPCINT0_vect -прерывание по изменению состояния  выводов

Таблица 12-5 для таймера! Только для таймера 1.

 

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

в очередной раз спасибо)

вроде понял, ike,t копну чуть позже)

GIMSK=1<<PCIE;
    PCMSK=1<<PCINT4;

 

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

 

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

Все непонятные обозначения ищите в даташите. Вот например PCIE это БИТ 5.

GIMSK – General Interrupt Mask Register

Bit 5 – PCIE: Pin Change Interrupt Enable
When the PCIE bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt is
enabled. Any change on any enabled PCINT[5:0] pin will cause an interrupt. The corresponding interrupt of Pin
Change Interrupt Request is executed from the PCI Interrupt Vector. PCINT[5:0] pins are enabled individually by
the PCMSK0 Register.
Unikolai
Offline
Зарегистрирован: 21.09.2016

Спасибо! Понял!!) Как же это все интересно!

Unikolai
Offline
Зарегистрирован: 21.09.2016
void setup() {
  // put your setup code here, to run once:
  pinMode(4, OUTPUT);
  pinMode(3, INPUT);
   GIMSK=1<<PCIE;//GIMSK = B00000110;не катит поч
  PCMSK = 1 << PCINT3;


}

void loop() {
  // put your main code here, to run repeatedly:
 

}
ISR (PCINT0_vect){
if (PINB&(1<<PINB3)) { return;}
  
 digitalWrite(4, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(10);                       // wait for a second
  digitalWrite(4, LOW);    // turn the LED off by making the voltage LOW
  delay(10);
}

что -то я делаю не так...ибо светодиод, подключенный к pb4 не мигает, перрывания устраиваю трехвольтовой батарейкой, минус коей подсоединен к минусу тиньки, а плют тыкаю на пины

хотя вру, контакт был плохой, он абсолютно рандомно горит почему-то

Могу предположить, что 3 пин к земле нужно подтянуть, но мне кажется не только в этом дло

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

Есть такое понятие дребезг контакта. Когда вы касаетесь батарейкой , то прерывание успевает сработать много раз.

10мс это мало. У меня глаз еле-еле различает такой моргание :-)

В прерывании delay не работает на большинстве ардуин. Вас спасает только то, что 85 делает прерывание по своему. Вообще вставлять в прерывание любые затягивающие время или длинные алгоритмы плохо. Обычно в прерывании выставляют флаги и производя минимум необходимых именно сейчас действий. Потом в основном цикле обрабатываются флаги. Т.е. мигание светодиодом следует поставить в loop.   И не забывать volatile у флагов. 

Зачем вам строка 17?

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

в том то и дело, что лампочка оч странно работает, она абсолютно рандомногорит даже когда я выставил на 100мс, то есть может гореть секунду, потом мерцать, частота меняется постоянно, делей поставил, чтобы можно было отсделить как раз таки, что это не дребезг и понять, что все работает, но увы, возможно делей ждействительно не работет, допустим если я просто щажгу диод, то поидее он должен вс равно гореть и когда я поднесу + батарейки к пину 3? а тот же делей значит в лупе оставить?

а по регистрам, я выставил все, ч нужно7

GIMSK = B00000110 не нужно так делать?

volatile это что такое?

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Это как помолиться?

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

типо того)

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

http://arduino.ru/Reference/Volatile

GIMSK - нормально.

Есть инструкция sei() которая разрешает глобальные прерывания. 

Я проверяю прерывания такой конструкциейЖ if ((PINB & (1 << PB3))==0) PORTB|=(1 << PB3); else PORTB &= ~(1 << PB3);