Если на 85, то как угодно. Я делал и по и2с на другую плату, и софт сериал.. да как хочешь изгаляйся, там памяти хватит.
Если на 13, то отладь сперва на 85-ой. ;) Я серьезно, у тебя 1 К программы. Я ставил как-то себе софтварный и2с собственного разлива и ловил на Ардуинку, но для кода уже очень мало остается. Тут либо на симуляторе - терпеть их не могу! - либо на 85-ой отлаживать.
-------------
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Есть несколько готовых схем, где тинька 13 вполне себя оправдывает. Лично у меня работает
- Сенсорный выключатель с диммированием по оному каналу
- Сторожевой таймер
- Таймер сна или кнопка питания для более прожорливых МК
Когда есть готовые схемки и разведенные платки и госрть корпусов купленных по 0.3$ там вполне ксть где развернуться
Но вот сидеть и впихивать код в МК с мизерной памятью, когда Mega8 стоит всего в 1.5 раза дороже извращение еще то
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Есть несколько готовых схем, где тинька 13 вполне себя оправдывает. Лично у меня работает
- Сенсорный выключатель с диммированием по оному каналу
- Сторожевой таймер
- Таймер сна или кнопка питания для более прожорливых МК
Когда есть готовые схемки и разведенные платки и госрть корпусов купленных по 0.3$ там вполне ксть где развернуться
Но вот сидеть и впихивать код в МК с мизерной памятью, когда Mega8 стоит всего в 1.5 раза дороже извращение еще то
Да я не о замене на Мегу, я про ТИНЬКУ, Точно такую же по ногам - в 8-ми ногом корпусе и совместимую на плате - про Тиньку85. Если есть идея и плата, то ну ее нахер это 13-ую. Только если в столе валяются и девать некуда.
int main(void)
{
while(1)
{
mode = 0;
while ( (PINB&(1<<2)) == (1<<2) ) {};
while ( (PINB&(1<<2)) == 0b00000000 ) {};
_delay_us(1200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
_delay_us(200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
_delay_us(200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
if (mode == 0 && analogRead(2)<150)
{
off();
}
else flag=0;
if ( mode == 1 ) doubleflash();
if ( mode == 2 ) siren();
if ( mode == 3 ) always();
if ( analogRead(2)<150 && flag==0)
{
always();
flag1=1;
}
}
}
Коллеги, подскажите где ошибка? Смысл такой, с RC приемника идет сигнал, когда уровень меньше 150 то выполняется условие OFF()(подсветка выключена), и когда пропал сигнал управления с пульта, т.е сигнал будет тот же 150, должно выполняться условие always()., а это условие не выполняется.Понимаю что ошибка кроется в 15 и 24 строках т.к выполняется одновременно одно условие.Режим mode=0 тоже соответствует условию <150
Ну я сделал прерывание по нарастанию фронта, так как мне нужно замерить длину импульса, while(PINB & (1<<PB1)) эта строка ждет пока не произойдет спад на 0, пока спада нет идет замер длительности, и если она меньше 1000мс то выключить светодиод.
обработка прерывания в любых МК (пусть меня гуру исправят если я не прав) ВСЕГДА должна занимать минимум времени, они не предназначены для периодов типа ваших целая секунда - вечность с точки зрения МК.
и если уж совсем хочеться так сделать - обязательно первой командой после срабатывания прерывания - выключить его.
опять же, повторюсь - напишите минимальный скетч зажигания светодиода при нарастании импульса - проверьте, а потом уже будете всякие расчеты и прочее делать.
Не получается напивать скетч по нарастанию, по изменению сигнала получается, а по нарастанию не получается(((
А уважаемый просящий не забыл про дребезг?
Что мешает прерыванию реагировать на оба фронта: по первому фронту запоминать текущее время, по второму вычислять длительность. В основном цикле проверять эту длительность и реагировать в бесконечном цикле.
Что мешает прерыванию реагировать на оба фронта: по первому фронту запоминать текущее время, по второму вычислять длительность. В основном цикле проверять эту длительность и реагировать в бесконечном цикле.
Так я так и хочу сделать, а вот реализовать никак не получается. Набросайте если не сложно примерчик.
Вам необходимо по большому счету всю логику программы поменять (если я правильно задачу понял):
Логику вы поняли правильно) . Но на входе у меня не кнопка, и сигнал с приемника радиоуправления, импульсы там идут каждые 20мс, и мне надо измерять длину импульса и если она меньше 1000мс, то соответсвенно выполнить какое то действие.
volatile int length = 0;
volatile int start_time = 0;
void setup() {
Serial.begin(9600);
// Привязываем к Pin2 прерывание по фронту сигнала
attachInterrupt(0, rising, RISING);
}
void loop() { }
//Обработчик прерывания на возрастание сигнала
void rising() {
// Привязываем к Pin2 прерывание по срезу сигнала
attachInterrupt(0, falling, FALLING);
//сохраняем значение времени начала импульса
start_time = micros();
}
//Обработчик прерывания по срезу сигнала
void falling() {
// Привязываем к Pin2 прерывание по фронту сигнала
attachInterrupt(0, rising, RISING);
//сохраняем значение длительности импульса
length = micros() - start_time;
if (length<1000) Serial.println("werty");
else Serial.println(length);
}
Вот делал на ардуино, все работает как надо, не пойму как этот код перевети на Attiny.
на его основе можно уже считать, чуть позже попробую примерчик накидать, или сами, условие на ==1 поменяйте и попробуйте светодиод зажечь по высокому уровню
на его основе можно уже считать, чуть позже попробую примерчик накидать, или сами, условие на ==1 поменяйте и попробуйте светодиод зажечь по высокому уровню
Код компилится, условие поменял на ==1, туда же вставил строку PB4_HIGH else PB4_LOW, не работает.
Так сразу прерывание срабатывает, независимо от того, что подано на вход PB1, т.е сразу после загрузки скетча светодиод на PB4 загорается, специально добавил delay туда чтобы понять, прерывание включается сразу.
во время отображения могут (и наверняка срабатывают, т.к. Serial.print работает несоизмеримо медленнее ваших замеров) оба прерывания сработать и наверняка переменная start_time дает уже некорректное значение.
если хотим правильные цифры получить - необходимо отключать прерывание сразу после их вызова, и включать после отображения данных.
да и здесь вам ответили что возможно времени меньше 1000 мкс не бывает
На ардуино код работает отлично, импульс который мне надо отследить длительностью 980мкс он четко показывает и выполняет необходимые действия как только этот импульс поймался. На импульсы другой длительности не реагирует, короче то что я хочу и сделать на Attiny13.
Не встретилась
Если на 85, то как угодно. Я делал и по и2с на другую плату, и софт сериал.. да как хочешь изгаляйся, там памяти хватит.
Если на 13, то отладь сперва на 85-ой. ;) Я серьезно, у тебя 1 К программы. Я ставил как-то себе софтварный и2с собственного разлива и ловил на Ардуинку, но для кода уже очень мало остается. Тут либо на симуляторе - терпеть их не могу! - либо на 85-ой отлаживать.
-------------
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Есть несколько готовых схем, где тинька 13 вполне себя оправдывает. Лично у меня работает
- Сенсорный выключатель с диммированием по оному каналу
- Сторожевой таймер
- Таймер сна или кнопка питания для более прожорливых МК
Когда есть готовые схемки и разведенные платки и госрть корпусов купленных по 0.3$ там вполне ксть где развернуться
Но вот сидеть и впихивать код в МК с мизерной памятью, когда Mega8 стоит всего в 1.5 раза дороже извращение еще то
Можно исходники и схему
Вообще, совет: совсем не использовать 13-ые. У меня еще есть несколько и я думаю куда их пристроить (или просто выбросить). Нет смысла изгаляться с 13, если энергопотребление у 85-ой такое же, а памяти в разы больше.
Есть несколько готовых схем, где тинька 13 вполне себя оправдывает. Лично у меня работает
- Сенсорный выключатель с диммированием по оному каналу
- Сторожевой таймер
- Таймер сна или кнопка питания для более прожорливых МК
Когда есть готовые схемки и разведенные платки и госрть корпусов купленных по 0.3$ там вполне ксть где развернуться
Но вот сидеть и впихивать код в МК с мизерной памятью, когда Mega8 стоит всего в 1.5 раза дороже извращение еще то
Да я не о замене на Мегу, я про ТИНЬКУ, Точно такую же по ногам - в 8-ми ногом корпусе и совместимую на плате - про Тиньку85. Если есть идея и плата, то ну ее нахер это 13-ую. Только если в столе валяются и девать некуда.
Можно исходники и схему
#define F_CPU 9600000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/atomic.h> #include <avr/eeprom.h> #include <util/delay.h> #include <avr/sleep.h> struct bits { uint8_t b0:1; uint8_t b1:1; uint8_t b2:1; uint8_t b3:1; uint8_t b4:1; uint8_t b5:1; uint8_t b6:1; uint8_t b7:1; } __attribute__((__packed__)); #define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin) #define SENSKEY_A0 SBIT( PORTB, 3 ) // connect to senspad #define SENSKEY_A0_DDR SBIT( DDRB, 3 ) #define SENSKEY_B0 SBIT( PORTB, 4 ) // connect to cap to A0 #define SENSKEY_B0_DDR SBIT( DDRB, 4 ) #define SENSKEY_B0_PIN SBIT( PINB, 4 ) #define TP_THRESHOLD 8 #define TP_UP 0 #define TP_DOWN 1 #define TP_HOLD 2 // Значения настроек при первом включении (хранятся в EEPROM) EEMEM unsigned char param_eeprom [] = { 120, // Уровень яркости }; uint8_t led_on, up, adj, hold; volatile uint8_t smplctr, level; int16_t tp_filter, tp_current; int8_t tp_state; #define MAX_CYCLE 2000 uint16_t senskey( void ) { uint16_t i = MAX_CYCLE + 1; SENSKEY_A0 = 0; SENSKEY_A0_DDR = 1; SENSKEY_B0 = 0; SENSKEY_B0_DDR = 1; // discharge cap ATOMIC_BLOCK(ATOMIC_FORCEON){ do{ SENSKEY_A0_DDR = 0; // A0 = tristate SENSKEY_B0 = 1; // B0 = weak high SENSKEY_B0_DDR = 1; // B0 = strong high SENSKEY_B0_DDR = 0; // B0 = weak high SENSKEY_B0 = 0; // B0 = tristate SENSKEY_A0_DDR = 1; // A0 = strong low if( --i == 0 ) break; // timeout }while( SENSKEY_B0_PIN == 0 ); // until charged } SENSKEY_B0_DDR = 1; // discharge cap return MAX_CYCLE - i; // big value = key touched or timeout } SIGNAL(TIM0_OVF_vect) { // Counter for main loop smplctr++; // Check if the lamp should be on if(led_on && tp_state == TP_UP) { TCCR0A |= (1 << COM0A1); // Включаем выход таймера for(OCR0A = 0; up && (OCR0A != level); OCR0A++) // Светодиод разгорается { _delay_ms(5); } up = 0; OCR0A = level; } if(led_on == 0 && tp_state == TP_UP) { for(OCR0A = level; up == 0 && (OCR0A != 0); OCR0A--) // Светодиод тухнет { _delay_ms(5); } up = 1; OCR0A = 0; // Минимальная яркость TCCR0A &= ~(1 << COM0A1)|(1 << COM0A0); // Отключаем выход таймера } } #define FILORD 8 #define FILSHIFT 3 // Moving average lowpass filter int16_t lpfilter(int16_t sample) { static int16_t z[FILORD]; static int8_t ctr; int8_t i; int16_t fil; z[ctr&(FILORD-1)] = sample; ctr++; fil=0; for(i=0 ; i<FILORD ; i++) { fil += z[i]; } return fil>>FILSHIFT; } // Settle the lowpass filter to some sampled value void lpfilter_settle(int16_t sample) { int8_t i; for(i=0 ; i<FILORD ; i++) lpfilter(sample); } int main(void) { DDRB |= (1 << PB0); // Светодиод PORTB &= ~(1 << PB0); ACSR |= (1 << ACD); TCCR0A |= (1 << WGM00)|(1 << WGM01); TCCR0B |= (1 << CS02); // 122 Hz PWM TIMSK0 |= (1 << TOIE0); tp_state = TP_UP; tp_filter = tp_current = senskey(); lpfilter_settle(tp_current); set_sleep_mode(SLEEP_MODE_IDLE); sei(); // Установки при первом включении adj = 1; level = eeprom_read_byte(param_eeprom); up = 1; // Main loop while(1) { // Go to idle mode until next timer event sleep_mode(); // Read touchpad and filter signals at 5Hz if(smplctr >= 12) { // Read touchpad value tp_current=0; for(char i=0;i<8;i++) tp_current += senskey(); tp_current >>= 3; if(tp_current < (tp_filter - TP_THRESHOLD) && tp_state == TP_UP) { // New touchpad state tp_state = TP_DOWN; // Toggle the lamp on/off led_on ^= 1; // Settle the lowpass filter to the current touchpad value // so that a touchpad change will be sensed relative to this value lpfilter_settle(tp_current); } else if(tp_current > (tp_filter + TP_THRESHOLD) && tp_state != TP_UP) { // "Button up event" // New touchpad state tp_state = TP_UP; if(hold > 20) // Если сенсор удерживался { eeprom_write_byte(param_eeprom, level); // Записываем уровень в EEPROM hold = 0; led_on = 1; // Оставляем включенным up = 0; } // Settle the lowpass filter to the current touchpad value // so that a touchpad change will be sensed relative to this value lpfilter_settle(tp_current); } else if(tp_state != TP_UP) { // "Button hold event" // New touchpad state tp_state = TP_HOLD; if(hold ++> 21) hold = 21; if(hold > 20 && led_on == 0) { OCR0A = level; if(level != 255 && adj == 1) { level = level + 5; if(level == 255) { OCR0A = 50; _delay_ms(100); OCR0A = 255; _delay_ms(100); OCR0A = 50; _delay_ms(100); OCR0A = 255; _delay_ms(100); adj = 0; } } if(level != 0 && adj == 0) { level = level - 5; if(level == 5) { adj = 1; level = 5; } } } } // Filter touchpad value tp_filter = lpfilter(tp_current); // Start counting the timer from 0 smplctr = 0; } }; return 0; }Такой модуль подойдёт?
И всё же
Такой модуль подойдёт?
Для чего подойдет?
Там нет диммирования. Там нет запоминания состояния. Плавного включения.
Для включения в схему
Для включения в схему
Тема про тини 13. Я написал, как использую тини 13
Естественно TTP223 и тысячи других микросхем можно включат в свои схемы. Иногда тинька выходит дешевле, чем специализированная микросхема
int main(void) { while(1) { mode = 0; while ( (PINB&(1<<2)) == (1<<2) ) {}; while ( (PINB&(1<<2)) == 0b00000000 ) {}; _delay_us(1200); if ( (PINB&(1<<2)) == (1<<2) ) mode++ ; _delay_us(200); if ( (PINB&(1<<2)) == (1<<2) ) mode++ ; _delay_us(200); if ( (PINB&(1<<2)) == (1<<2) ) mode++ ; if (mode == 0 && analogRead(2)<150) { off(); } else flag=0; if ( mode == 1 ) doubleflash(); if ( mode == 2 ) siren(); if ( mode == 3 ) always(); if ( analogRead(2)<150 && flag==0) { always(); flag1=1; } } } Коллеги, подскажите где ошибка? Смысл такой, с RC приемника идет сигнал, когда уровень меньше 150 то выполняется условие OFF()(подсветка выключена), и когда пропал сигнал управления с пульта, т.е сигнал будет тот же 150, должно выполняться условие always()., а это условие не выполняется.Понимаю что ошибка кроется в 15 и 24 строках т.к выполняется одновременно одно условие.Режим mode=0 тоже соответствует условию <150#define F_CPU 1200000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> volatile int length = 0; volatile int start_time = 0; ISR(INT0_vect) { while (PINB & (1<<PB1)) //пока высокий уровень { length = micros() - start_time;//считаем длительность импульса до спада } if (length<1200) PORTB |= (1 << PB4); if (length>1500) PORTB &= ~ (1 << PB4); } int main() { DDRB |= (1 << PB4); // OUTPUT PORTB &= ~ (1 << PB4); DDRB &= ~(1 << PB1); // INPUT PORTB |= (1 << PB1); rising(); while (1) { } } void rising() { MCUCR |= (1 << ISC01) | (1 << ISC00); //включаем прерывание по нарастающему фронту GIMSK |= (1 << INT0); //разрешаем прерывание start_time = micros(); sei(); } }Ребят, подскажите,почему не работает код?
а зачем 32 строка?
и прерывание вообще срабатывает? прикрутите какой нибудь светодиод - чтоб загорался как сработает прерывание,
я бы отключение прерывания засунул внутрь ISR(INT0_vect)
да и не пойму логику - ISR срабатывает один раз при спаде, зачем цикл while для расчета времени между стартом программы и спадом?
Прерывание не срабатывает. светодиод подключен.
Прерывание не срабатывает. светодиод подключен.
значит начинаем последовательно искать где косяк,
выкидываете из скетча все кроме запуска этого прерывания и на срабатывание прерывания включение светодиода - тестируйте.
ЗЫ. а вы правильно прерывание включаете? даташит читали?
и кстати в вашем случае логичнее было бы использовать прерывание PCINT - оно
срабатывает при любом изменении сигнала, а внутри уже обрабатывать
Ну я сделал прерывание по нарастанию фронта, так как мне нужно замерить длину импульса,
while(PINB & (1<<PB1)) эта строка ждет пока не произойдет спад на 0, пока спада нет идет замер длительности,и если она меньше 1000мс то выключить светодиод.обработка прерывания в любых МК (пусть меня гуру исправят если я не прав) ВСЕГДА должна занимать минимум времени, они не предназначены для периодов типа ваших целая секунда - вечность с точки зрения МК.
и если уж совсем хочеться так сделать - обязательно первой командой после срабатывания прерывания - выключить его.
опять же, повторюсь - напишите минимальный скетч зажигания светодиода при нарастании импульса - проверьте, а потом уже будете всякие расчеты и прочее делать.
Не получается напивать скетч по нарастанию, по изменению сигнала получается, а по нарастанию не получается(((
А нарастание - это не изменение?
Что мешает проверить значение сразу после входа в прерывания?
Пробный скетч написали?
Не получается напивать скетч по нарастанию, по изменению сигнала получается, а по нарастанию не получается(((
А уважаемый просящий не забыл про дребезг?
Что мешает прерыванию реагировать на оба фронта: по первому фронту запоминать текущее время, по второму вычислять длительность. В основном цикле проверять эту длительность и реагировать в бесконечном цикле.
Так я так и хочу сделать, а вот реализовать никак не получается. Набросайте если не сложно примерчик.
чтоб набросать примерчик, необходимо вчитаться в даташит, на это нужно время, которого к сожалению нет :(
могу скинуть пример с прерыванием PCINT на attiny85 но там много лишнего....
вам необходимо по большому счету всю логику программы поменять (если я правильно задачу понял):
при старте обнулять флаг, обнулять счетчик времени, запускать прерывание.
в прерывании первой командой выключить прерывание, установить флаг.
в цикле loop постоянно смотреть состояние флага/время и как только он установиться - делать свою логику.
примеров в интернете масса:
http://osboy.ru/blog/microcontrollers/attiny13-switch.html
http://1io.ru/articles/microcontroller/attiny13/
https://radiokot.ru/forum/viewtopic.php?p=1657416
Вам необходимо по большому счету всю логику программы поменять (если я правильно задачу понял):
Логику вы поняли правильно) . Но на входе у меня не кнопка, и сигнал с приемника радиоуправления, импульсы там идут каждые 20мс, и мне надо измерять длину импульса и если она меньше 1000мс, то соответсвенно выполнить какое то действие.
volatile int length = 0; volatile int start_time = 0; void setup() { Serial.begin(9600); // Привязываем к Pin2 прерывание по фронту сигнала attachInterrupt(0, rising, RISING); } void loop() { } //Обработчик прерывания на возрастание сигнала void rising() { // Привязываем к Pin2 прерывание по срезу сигнала attachInterrupt(0, falling, FALLING); //сохраняем значение времени начала импульса start_time = micros(); } //Обработчик прерывания по срезу сигнала void falling() { // Привязываем к Pin2 прерывание по фронту сигнала attachInterrupt(0, rising, RISING); //сохраняем значение длительности импульса length = micros() - start_time; if (length<1000) Serial.println("werty"); else Serial.println(length); }Вот делал на ардуино, все работает как надо, не пойму как этот код перевети на Attiny.
это как? "идут каждые 20мс, и мне надо измерять длину импульса и если она меньше 1000мс"
противоречие - нет? импульс 1000 мс не может идти каждые 20 мс, или его длительность меньше 20
тьфу,период 20мс, длительность импульса от 1мс до 2мс, надо отследить импульс менее 1мс.
тьфу,период 20мс, длительность импульса от 1мс до 2мс, надо отследить импульс менее 1мс.
Между периодами (импульсами) низкий уровень на пине?
[/quote] Между периодами (импульсами) низкий уровень на пине?[/quote]
так точно,низкий.
#define F_CPU 1200000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> volatile int length = 0; volatile int start_time = 0; void rising (void) { MCUCR |= (1 << ISC01); //устанавливаем прерывание по спаду MCUCR &= ~ (1 << ISC00); GIMSK |= (1 << INT0); //INT0 Interrupt Enable sei(); //Global Interrupts Enable start_time = micros(); falling(); } void falling (void) { MCUCR |= (1 << ISC01) | (1 << ISC00); // устанавливаем прерывание по фронту GIMSK |= (1 << INT0); sei(); length = micros() - start_time; if (length<1000) PORTB |= (1 << PB4); //если меньше 1000мкс , зажигаем светодиод if (length>1300) PORTB &= ~(1 << PB4); rising(); } int main() { DDRB |= (1 << PB4); // OUTPUT DDRB &= ~(1 << PB1); // INPUT PORTB |= (1<<4); rising(); while (1) { } }попробовал так,тоже ничего не получается.
тьфу,период 20мс, длительность импульса от 1мс до 2мс, надо отследить импульс менее 1мс.
Серва и вот её тайминг?
Ну да, по этой диаграмме и пытаюсь написать код.
вот пример сработки прерывания по низкому уровню для attiny85 (13ой нету попробовать)
попробуйте - откомпилируется или нет для attyny13
#include <avr/sleep.h> #include <avr/interrupt.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_IN cbi(DDRB,PB0) #define PB0_HIGH sbi(PORTB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - input data #define PB1_OUT sbi(DDRB,PB1) #define PB1_IN cbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) #define PB1_READ bitRead(PINB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_IN cbi(DDRB,PB2) #define PB2_HIGH sbi(PORTB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3) #define PB3_IN cbi(DDRB,PB3) #define PB3_HIGH sbi(PORTB,PB3) #define PB3_LOW cbi(PORTB,PB3) // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) ISR(PCINT0_vect) { if (PB1_READ == 0) { // LOW level KEY // disable interrupt cbi(GIMSK, PCIE); cbi(PCMSK, PCINT1); } } void setup () { // pins mode PB0_OUT; PB0_LOW; PB1_IN; PB1_HIGH; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_OUT; PB4_LOW; // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); } void loop () { }на его основе можно уже считать, чуть позже попробую примерчик накидать, или сами, условие на ==1 поменяйте и попробуйте светодиод зажечь по высокому уровню
Ну да, по этой диаграмме и пытаюсь написать код.
Только там меньше 1000мкс не бывает.
От 1000 до 2000 с серединой 1500.
Ищите RC Switch.
Включая поиском недавно на форуме, кто-то уже сделал это.
http://arduino.ru/forum/programmirovanie/poluchenie-dannykh-s-priemnika-...
https://brainwagon.org/2014/06/14/making-a-simple-rc-switch/
на его основе можно уже считать, чуть позже попробую примерчик накидать, или сами, условие на ==1 поменяйте и попробуйте светодиод зажечь по высокому уровню
Код компилится, условие поменял на ==1, туда же вставил строку PB4_HIGH else PB4_LOW, не работает.
туда же вставил строку PB4_HIGH else PB4_LOW
ничего не понял - весь код приведите
#include <avr/sleep.h> #include <avr/interrupt.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_IN cbi(DDRB,PB0) #define PB0_HIGH sbi(PORTB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - input data #define PB1_OUT sbi(DDRB,PB1) #define PB1_IN cbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) #define PB1_READ bitRead(PINB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_IN cbi(DDRB,PB2) #define PB2_HIGH sbi(PORTB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3) #define PB3_IN cbi(DDRB,PB3) #define PB3_HIGH sbi(PORTB,PB3) #define PB3_LOW cbi(PORTB,PB3) // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) ISR(PCINT0_vect) { if (PB1_READ == 1) { // LOW level KEY // disable interrupt cbi(GIMSK, PCIE); cbi(PCMSK, PCINT1); PB4_HIGH; } else PB4_LOW; } void setup () { // pins mode PB0_OUT; PB0_LOW; PB1_IN; PB1_HIGH; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_OUT; PB4_LOW; // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); } void loop () { }а так работает?:
#include <avr/sleep.h> #include <avr/interrupt.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_IN cbi(DDRB,PB0) #define PB0_HIGH sbi(PORTB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - input data #define PB1_OUT sbi(DDRB,PB1) #define PB1_IN cbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) #define PB1_READ bitRead(PINB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_IN cbi(DDRB,PB2) #define PB2_HIGH sbi(PORTB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3) #define PB3_IN cbi(DDRB,PB3) #define PB3_HIGH sbi(PORTB,PB3) #define PB3_LOW cbi(PORTB,PB3) // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) ISR(PCINT0_vect) { if (PB1_READ == 1) { // LOW level KEY // disable interrupt cbi(GIMSK, PCIE); cbi(PCMSK, PCINT1); PB4_HIGH; } //else PB4_LOW; } void setup () { // pins mode PB0_OUT; PB0_LOW; PB1_IN; PB1_HIGH; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_OUT; PB4_LOW; // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); } void loop () { }я конечно не уверен - но вы реально думаете что сможете увидеть моргание светодиода длительностью 2 мс ?
тупо кнопку на PB1 прицепите - проверьте - от нажатия светодиод загорается?
Так сразу прерывание срабатывает, независимо от того, что подано на вход PB1, т.е сразу после загрузки скетча светодиод на PB4 загорается, специально добавил delay туда чтобы понять, прерывание включается сразу.
я конечно не уверен - но вы реально думаете что сможете увидеть моргание светодиода длительностью 2 мс ?
А мне не надо отслеживать моргание, мне же надо просто замерить длину импульса.
вот в этот скетч если кнопку подцепить - будет загораться при опузкании на ноль PB1? т.е. понять прерывание вообще работает?
http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=2...
Вот набросал что я хочу получить, как это делаю,но ничего не получается((
вот в этот скетч если кнопку подцепить - будет загораться при опузкании на ноль PB1? т.е. понять прерывание вообще работает?
Да, работает, светодиод загорается при замыкании PB1 на землю.
наверное как то так:
#include <avr/sleep.h> #include <avr/interrupt.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_IN cbi(DDRB,PB0) #define PB0_HIGH sbi(PORTB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - input data #define PB1_OUT sbi(DDRB,PB1) #define PB1_IN cbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) #define PB1_READ bitRead(PINB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_IN cbi(DDRB,PB2) #define PB2_HIGH sbi(PORTB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3) #define PB3_IN cbi(DDRB,PB3) #define PB3_HIGH sbi(PORTB,PB3) #define PB3_LOW cbi(PORTB,PB3) // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) byte flag_start; unsigned long timer_end; byte action_flag; ISR(PCINT0_vect) { if ((PB1_READ == 1) && (flag_start == 0)) { // disable interrupt cbi(GIMSK, PCIE); cbi(PCMSK, PCINT1); //- flag_start = 1; timer_end = micros(); action_flag = 0; // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); //- } else if ((PB1_READ == 0) && (flag_start == 1)) { // disable interrupt cbi(GIMSK, PCIE); cbi(PCMSK, PCINT1); //- flag_start = 0; if ((micros() - timer_end) < 1000UL) { action_flag = 1; } else { // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); //- } } } void setup () { // pins mode PB0_OUT; PB0_LOW; PB1_IN; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_OUT; PB4_LOW; // init flag_start = 0; timer_end = micros(); action_flag = 0; // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); } void loop () { if (action_flag == 1) { action_flag = 0; // do everything // enable interrupt sbi(GIMSK, PCIE); sbi(PCMSK, PCINT1); } }Не, не работает.
Не, не работает.
а в 92 строке вписали зажечь светодиод?
хм..интересно, а если в 61 строке поменять условие на > ?
там вообще есть имульсы меньше 1000 мкс ?
а в 92 строке вписали зажечь светодиод?
хм..интересно, а если в 61 строке поменять условие на > ?
там вообще есть имульсы меньше 1000 мкс ?
Вписал, на ардуине уно проверял (скетч выше писал)длительность, импульсы есть, от 98- до 1700мкс.
а в 92 строке вписали зажечь светодиод?
хм..интересно, а если в 61 строке поменять условие на > ?
там вообще есть имульсы меньше 1000 мкс ?
Вписал, на ардуине уно проверял (скетч выше писал)длительность, импульсы есть, от 98- до 1700мкс.
условие на больше 1000 поменяли для тестирования? светодиод загорелся?
ЗЫ. Значит тестируйте на каждом шаге что бы выявить ошибку, например сначала на фронте сигнала, потом на спаде и т.д.
и кстати: смотрю ваш код для UNO - а вы уверены что он корректно работает?
http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=2...
во время отображения могут (и наверняка срабатывают, т.к. Serial.print работает несоизмеримо медленнее ваших замеров) оба прерывания сработать и наверняка переменная start_time дает уже некорректное значение.
если хотим правильные цифры получить - необходимо отключать прерывание сразу после их вызова, и включать после отображения данных.
да и здесь вам ответили что возможно времени меньше 1000 мкс не бывает
http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=2...
На ардуино код работает отлично, импульс который мне надо отследить длительностью 980мкс он четко показывает и выполняет необходимые действия как только этот импульс поймался. На импульсы другой длительности не реагирует, короче то что я хочу и сделать на Attiny13.