Программирование ATtiny13

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15585
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Программирование ATtiny13

Сообщение BOB51 »

Насчет "чистого Си" не ведаю...
Однако в адуринье на основе АВРок любое прерывание "перекрывает кислород" функциям контроля времени.
Ведь в прерывании ВЛОЖЕННЫЕ прерывания по умолчанию запрещены.
Там или вложенные прерывания разрешать надо или делать тайм-слоты на основе программного подсчета тактов в командах.
:dont_know:
Может для первичной обучалки адуринка сгодится?
Там и симулятор приличный имеется с полным фаршем внешней аппаратной обвязки...
https://www.sites.google.com/site/unoardusim/
И чего б поднабросать можно (правда не для тиньки - но основа алгоритмов одинакова будет... и просмотр пошаговый удобен...)...
:roll:
Помимо прочего помним о предделителях счетчиков. Ибо те предделители тикают и переполняются сами по себе независимо - работает счетчик или нет.
При запуске интервалометра необходимо предварительно сбрасывать предделитель соответствующего счетчика.
Под ассемблером и с учетом тини13...
Можно использовать цифровые компараторы таймера - заложить в них длительность положительной части измерямного импульса.
С приходом фронта внешнего сигнала запуск таймера
Прерывание по совпадению с одного компаратора - 0 (если не имело место большее по величине) - ставим флаг 0
Прерывание со второго - 1. ставим флаг 1
Общее прерывание по переполнению - ошибка интервала ставим флаг 3 и останов таймера по переполнению
С момента фронта внешнего импульса запускаем программное ожидание спада положительного интервала.
По окончании импульса останов счета и смотрим флаги, а уж по ним принимаем решение о том, что у нас было.
8)
Последний раз редактировалось BOB51 Сб ноя 28, 2020 22:12:56, всего редактировалось 2 раза.
Реклама
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

BOB51, с ардуинкой я дружу digitalwrite(), digitalread(). Кстати на ардуинке на а328 это все решено у меня с использованием библиотеке типа virtualwave или чтото похоже, ну немало я их перебла. пробовал даже в Тиньку13 прошил bootloader, но там ограниченный набор комманд, а переделка библиотек потребовала большей квалификации. Это все понятно. Но как бы чувствую в себе силы решить эту задачку на чисмтом С. Кажется, что хожу вокруг да олоко, но вот никак не могу нащупать как оно работает.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15585
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Программирование ATtiny13

Сообщение BOB51 »

Попробуйте тот вариант, что я выше предложил...
Под ассемблером сие вполне работоспособно...
:roll:
emax
Первый раз сказал Мяу!
Сообщения: 38
Зарегистрирован: Пт мар 07, 2014 18:37:20
Откуда: Пермь

Re: Программирование ATtiny13

Сообщение emax »

рабочий код для attiny13 под AS4
Спойлер#include <avr/io.h>
#include <avr/interrupt.h>

#define OUTPORT PORTB //PORTB
#define OUT2 3 //pinout 2
#define OUT1 4 //pinout 3
#define OUT4 2 //pinout 7
#define OUT3 0 //pinout 5

#define PWMPIN PINB //PINB
#define PWM 1 //pinout 6

volatile unsigned char time; //текущее значение счетчика
volatile unsigned char time_begin; //время начала PWM импульса
volatile unsigned char ch; //длительность PWM импульса
volatile int tick4; //счетчик переполнений от последнего изменения на входе PWM
volatile unsigned char timer_mig; //таймер для мигания
//-------------------------------------------------------------------
// обработка прерывания от переполнения счетчика
ISR(TIM0_OVF_vect) //прерывание переполнения счетчика
{
tick4++;
timer_mig++; //3.413*256 = 876 ms
}
//-----------------------------------------------------------------
// обработка прерывания от изменения на входе PWM
ISR(PCINT0_vect)
{
time=TCNT0; //сохраняем текущее время

if ((PWMPIN & _BV(PWM))==0)
{
ch= time-time_begin; // это спад, определяем длительность импульса PWM
}
else
{
time_begin=time; // это фронт, запоминаем текущее время
}
tick4=0; //сброс счетчика переполнений
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// ГЛАВНАЯ ПРОГРАММА
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int main(void)
{
CLKPR=0x80; //частота 4 800 000 гц
CLKPR=0x00;

DDRB = _BV(OUT1) | _BV(OUT2) | _BV(OUT3) | _BV(OUT4) ; //настроить выходы на вывод

// Настройка Timer0
TCCR0B= _BV(CS01) | _BV(CS00); // Частота счетчика: 4 800 000/256 = 75 000 Hz или 13.3mks
// 13.33*256 = 3,413 ms максимальная длина,которую можно измерить
// Настройка прерывания
GIMSK= _BV(PCIE); // прерывание по изменению

PCMSK=_BV(PWM); //маска - какой пин отслеживаем
GIFR= _BV(INTF0) | _BV(PCIF); //очистить все флаги прерываний

TIMSK0= _BV(TOIE0); //разрешаем прерывания по переполнению
// Global enable interrupts
sei();
// === ГЛАВНЫЙ цикл ========
while (1)
{
//1000/13.33=75
//1200/13.33=90
//1400/13.33=105
//1500/13.33=112.5
//1600/13.33=120
//1800/13.33=135
//2000/13.33=150
//.....................
if (tick4 > 300)
{
OUTPORT &= ~_BV(OUT1); //если счетчик переполнений больше чем 300*3.4 ~ 1сек
OUTPORT &= ~_BV(OUT2); //выключаем оба выхода
OUTPORT &= ~_BV(OUT3); //выключаем оба выхода
OUTPORT &= ~_BV(OUT4); //выключаем оба выхода
}
else
{
//включить-выключить
if (ch <76)
{
OUTPORT &= ~_BV(OUT1); //1-выключить
OUTPORT &= ~_BV(OUT2); //2-выключить
OUTPORT &= ~_BV(OUT3); //3-выключить
OUTPORT &= ~_BV(OUT4); //4-выключить
}
//.......
if ((ch > 78) && (ch <106))
{
OUTPORT |= _BV(OUT1); //1-включить
OUTPORT &= ~_BV(OUT2); //2-выключить
OUTPORT &= ~_BV(OUT3); //3-выключить
OUTPORT &= ~_BV(OUT4); //4-выключить
}
//.......
if (ch > 108)
{
OUTPORT |= _BV(OUT1); //1-включить
OUTPORT |= _BV(OUT2); //2-включить
if((timer_mig & 0x80) == 0)
{
if ((timer_mig & 0x68) == 0) OUTPORT |= _BV(OUT3);
else OUTPORT &= ~_BV(OUT3);
}
else
{
if ((timer_mig & 0x68) == 0) OUTPORT |= _BV(OUT4);
else OUTPORT &= ~_BV(OUT4);
}

}
}
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Реклама
Эиком - электронные компоненты и радиодетали
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Программирование ATtiny13

Сообщение dgrett »

А тинька точно тактируется 1,2 МГц? Может, 9,6 (это как раз в 8 раз, как у Вас)? Тогда фьюзы.
Я всё-всё узнAю и стану профессором.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15585
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Программирование ATtiny13

Сообщение BOB51 »

9,6/8=1,2 фузы и предделитель "по умолчанию"при выпуске изделия.
8)
Реклама
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Программирование ATtiny13

Сообщение dgrett »

А помигать светиком да сравнить расчётную частоту с наблюдаемой? А может, все- таки 9,6 ?
Я всё-всё узнAю и стану профессором.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

[uquote="olegue",url="/forum/viewtopic.php?p=3932431#p3932431"]ок, а зачем мне конролить переполнение есил я TTCR0B=0x05 делитель на 1024[/uquote]
В реальности всегда что-то может пойти не так. По какой-то причине "залипнет" импульс - получите непредсказуемый эффект. По-хорошему надо всегда предусматривать внештатные ситуации.

[uquote="olegue",url="/forum/viewtopic.php?p=3932431#p3932431"]например если я подаю на вход частоту 50гц -это период 20мс. Это 2 длительности по 10м (high и low)
счет 8 битный -256 значений (0-255) испльзуя делитель на 1024 =имею 1172 кгц. ОДин оборот счетчика даст мне вычислить длительность 0.000853*256=0.218с =218мс. Значит ожидаемо,что 256*10мс/0.218= примерно 11-12 единиц счетчика. А я получаю 92. Т.е 92*0.000853= пример 80 мс. Откуда эти 80мс хоть стрэляй не пойму.
Кроче, что то не так а где концы искать по ка не знаю.[/uquote]
Такое впечатление, что у вас и правда CKDIV8 снят и тактовая просто 9.6 МГц, а не 1.2 МГц. Проверьте фьюзы. Раньше возможно прошивали их уже в этот МК и сняли этот бит.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

emax писал(а):рабочий код для attiny13 под AS4
Спойлер#include <avr/io.h>
#include <avr/interrupt.h>

#define OUTPORT PORTB //PORTB
#define OUT2 3 //pinout 2
#define OUT1 4 //pinout 3
#define OUT4 2 //pinout 7
#define OUT3 0 //pinout 5

#define PWMPIN PINB //PINB
#define PWM 1 //pinout 6

volatile unsigned char time; //текущее значение счетчика
volatile unsigned char time_begin; //время начала PWM импульса
volatile unsigned char ch; //длительность PWM импульса
volatile int tick4; //счетчик переполнений от последнего изменения на входе PWM
volatile unsigned char timer_mig; //таймер для мигания
//----------
// обработка прерывания от переполнения счетчика
ISR(TIM0_OVF_vect) //прерывание переполнения счетчика
{
tick4++;
timer_mig++; //3.413*256 = 876 ms
}
//----------
// обработка прерывания от изменения на входе PWM
ISR(PCINT0_vect)
{
time=TCNT0; //сохраняем текущее время

if ((PWMPIN & _BV(PWM))==0)
{
ch= time-time_begin; // это спад, определяем длительность импульса PWM
}
else
{
time_begin=time; // это фронт, запоминаем текущее время
}
tick4=0; //сброс счетчика переполнений
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// ГЛАВНАЯ ПРОГРАММА
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int main(void)
{
CLKPR=0x80; //частота 4 800 000 гц
CLKPR=0x00;

DDRB = _BV(OUT1) | _BV(OUT2) | _BV(OUT3) | _BV(OUT4) ; //настроить выходы на вывод

// Настройка Timer0
TCCR0B= _BV(CS01) | _BV(CS00); // Частота счетчика: 4 800 000/256 = 75 000 Hz или 13.3mks
// 13.33*256 = 3,413 ms максимальная длина,которую можно измерить
// Настройка прерывания
GIMSK= _BV(PCIE); // прерывание по изменению

PCMSK=_BV(PWM); //маска - какой пин отслеживаем
GIFR= _BV(INTF0) | _BV(PCIF); //очистить все флаги прерываний

TIMSK0= _BV(TOIE0); //разрешаем прерывания по переполнению
// Global enable interrupts
sei();
// === ГЛАВНЫЙ цикл ========
while (1)
{
//1000/13.33=75
//1200/13.33=90
//1400/13.33=105
//1500/13.33=112.5
//1600/13.33=120
//1800/13.33=135
//2000/13.33=150
//...
if (tick4 > 300)
{
OUTPORT &= ~_BV(OUT1); //если счетчик переполнений больше чем 300*3.4 ~ 1сек
OUTPORT &= ~_BV(OUT2); //выключаем оба выхода
OUTPORT &= ~_BV(OUT3); //выключаем оба выхода
OUTPORT &= ~_BV(OUT4); //выключаем оба выхода
}
else
{
//включить-выключить
if (ch <76)
{
OUTPORT &= ~_BV(OUT1); //1-выключить
OUTPORT &= ~_BV(OUT2); //2-выключить
OUTPORT &= ~_BV(OUT3); //3-выключить
OUTPORT &= ~_BV(OUT4); //4-выключить
}
//.......
if ((ch > 78) && (ch <106))
{
OUTPORT |= _BV(OUT1); //1-включить
OUTPORT &= ~_BV(OUT2); //2-выключить
OUTPORT &= ~_BV(OUT3); //3-выключить
OUTPORT &= ~_BV(OUT4); //4-выключить
}
//.......
if (ch > 108)
{
OUTPORT |= _BV(OUT1); //1-включить
OUTPORT |= _BV(OUT2); //2-включить
if((timer_mig & 0x80) == 0)
{
if ((timer_mig & 0x68) == 0) OUTPORT |= _BV(OUT3);
else OUTPORT &= ~_BV(OUT3);
}
else
{
if ((timer_mig & 0x68) == 0) OUTPORT |= _BV(OUT4);
else OUTPORT &= ~_BV(OUT4);
}

}
}
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
да, примерно мой уровень понимаю. Надо распечатать внимательно посмотреть код.
увидел там эти строки

Код: Выделить всё

CLKPR=0x80; //частота 4 800 000 гц
CLKPR=0x00;

DDRB = _BV(OUT1) | _BV(OUT2) | _BV(OUT3) | _BV(OUT4) ; //настроить выходы на вывод

// Настройка Timer0
TCCR0B= _BV(CS01) | _BV(CS00); // Частота счетчика: 4 800 000/256 = 75 000 Hz или 13.3mks
// 13.33*256 = 3,413 ms максимальная длина,которую можно измерить
и начал думать

BOB51, dgrett, NStorm,
dgrett писал(а):А помигать светиком да сравнить расчётную частоту с наблюдаемой? А может, все- таки 9,6 ?
да, так и сделал. Настроил счетчик, подключил осцилограф и начал считать клеточки.

в итого пришел сюда
Изображение

тут стояло 9.6. Я поставил 4.8. И все у меня получилось -47 условных единиц счетчика на 10мс
т.е 4.8/1024=4687.5 кгц или 21.3мкс. Это измеряемая длительность 256*21.3=54.6мс.
Я измеряю 10мс, то должен получить на счетчике 256*10/54.6=46.8
Как в аптеке!
Такое впечатление, что у вас и правда CKDIV8 снят и тактовая просто 9.6 МГц, а не 1.2 МГц. Проверьте фьюзы. Раньше возможно прошивали их уже в этот МК и сняли этот бит.
это все пока в Протеусе.

устроил сразу небольшой брутфорс. Проверяю 3 имупльса на длительность. Если все 3 соответствуют пеерключаю лампочку.

Код: Выделить всё

ISR(PCINT0_vect)
     
{
  // проверяю импульсы по  LOw
     if ( !(PINB & (1<<BUTTON2)) == 0  ) // если встретился high  То нужно сбросить счетчик что бы не учитывть длительность
  { 
    statHigh=TCNT0;
    TCNT0=0x00;
     }
   
  if (ii==0)
  {
   if ( (PINB & (1<<BUTTON2)) == 0) // если LOW
      { 
     statLow=TCNT0;
     if (statLow==47){ii=ii++;} // измерим и получим первый имупльс ii=1;
     TCNT0=0x00; 
     }
  } 
     
     
   if (ii==1)   
   { 
      if ( (PINB & (1<<BUTTON2)) == 0) // если LOW
      { 	
     statLow=TCNT0;
     if (statLow==47){ii=ii++;} // измерим и получим второй имупльс ii=2;
     TCNT0=0x00; 
     }
  }
     
   if (ii==2)   
   { 
      if ( (PINB & (1<<BUTTON2)) == 0) // если LOW
      { 	
     statLow=TCNT0;
     if (statLow==47){ii=ii++;} // измерим и получим второй имупльс ii=2;
     TCNT0=0x00; 
     }
  }
     
     
     
     
     if (ii==3) // Набралось 3 "правильных" импульса. Можно включать лампочку
     {
	
	 PORTB ^= (1<<LED); //переключаем состояние светодиода (вкл./выкл.)
	ii=0; // Обнулим счетчик "правильных" импульсов. Ждем следующую комманду.
	}
  

}
По меньшей мере это работает. Меняю частоту генератора хоть на 1 мс и лампочка уже не управляется.
Интересно ка к это будет выглядеть в железе?
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

Код: Выделить всё

ii=ii++;
Ох так не стоит делать. Просто ii++; - это уже увеличит значение ii на 1. А то неровен час до вот этого дойти.

В реальном железе вместо ровно 47 проверку стоит проводить с допущением некоего отклонения. Хотя у вас довольно-таки долгие импульсы, всё-равно на +-1 стоит хотя бы допущение сделать.

Счетчик "правильных" импульсов стоит обнулять не только когда приходят 3 правильных, но и когда приходит любой "неправильный". Иначе из-за накопления какой-нибудь ошибки/помех и т.п. может опять не так как надо работать. Просто при проверке statLow добавить else ii = 0;

Добавлено after 7 minutes 15 seconds:
И как я уже говорил - всегда предусматривайте внештатные ситуации и их обработку. В реальности всё не бывает так идеально, как в симуляторах. Еще стоит добавить прерывание по переполнению таймера, где как минимум сбрасывать ii тоже.
В реальности у вас будет не идеальный генератор, а радио модуль. Там и эфирные помехи и чужой эфир может быть и т.д. Модуль может затупить, зависнуть. Много вариантов может быть. Их стоит предусматривать.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm, счас подергал еще тот код что я выше написал и нашел ошибку, обнуление счетчика нужно только когда попадаю на ВЫсокий уровень.

Код: Выделить всё

ISR(PCINT0_vect)
     //|| (PINB & (1<<BUTTON2)) == 0
{
     jj=jj+1;
     if ( !(PINB & (1<<BUTTON2)) == 0  ) // если high
      { 
	 statHigh=TCNT0;
	 TCNT0=0x00;
      }
    if ( ((PINB & (1<<BUTTON2)) == 0) & (jj==2) & (TCNT0==66)) // если LOW
      { 
     	 stat1=TCNT0; t1=1;
	}
	
      if ( ((PINB & (1<<BUTTON2)) == 0 )&  (jj==4) & (TCNT0==57) ) // если LOW
	    { 	
	       stat2=TCNT0; t2=1;
	      }
      if ( ((PINB & (1<<BUTTON2)) == 0 ) & (jj==6)  & (TCNT0==52)) // если LOW
		     { 	
		     stat3=TCNT0; t3=1;
		     } 
     if (t1==t2==t3)
     {
	PORTB ^= (1<<LED); //переключаем состояние светодиода (вкл./выкл.)
	//ii=5;
	}
}
ну вот с этого варианта можно дальше плясать.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

Вот есть такая запись
IF ( (PINB & (1<<PB0))==0) {}
Она, как я понимаю указывает на то , что на ножке PB0 низкий уровень

т.е проверяем состояние порта PB0 используя регистр PINB

Не могу раскусить что значит ==0

Например у нас есть регистр PINB, он равен 0b0000 0000
есть PB0 равное 0
делаю 1<<PB0 , 0b0000 00001<<0, получаю 0b0000 0001

делаю операцию И ((PINB & 0b0000 0001)) между 0b0000 0000 И 0b0000 0001, получаю 0b0000 0001

А в каком месте тут должно быть ==0
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Программирование ATtiny13

Сообщение ARV »

olegue писал(а):делаю операцию И ((PINB & 0b0000 0001)) между 0b0000 0000 И 0b0000 0001, получаю 0b0000 0001
изучите битовые операции хорошенько

1 & 0 = 0, а не 1, как вы думаете
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

[uquote="ARV",url="/forum/viewtopic.php?p=3935717#p3935717"]изучите битовые операции хорошенько

1 & 0 = 0, а не 1, как вы думаете[/uquote]

да, верно . Я долго писал этот пост, отходил по пять раз .
т.е получаем в данном конкретном случает 0b0000 0000

а к чему тогда ==0, к чему этот 0 относится?

К конкретному пину? PB0?
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

olegue, ко всему выражению. Вместо инверсии.
Вы ведь пишете:
т.е получаем в данном конкретном случает 0b0000 0000
Вот к этому и относится. 0b00000000 = 0, поэтому выражение будет истиной.
Если бы пин был в высоком уровне, получили бы:
0b00000001 & 1 = 1
Что уже НЕ РАВНО 0, поэтому условие IF не выполняется.

На самом деле лучше писать

Код: Выделить всё

if (!(PINB & (1<<PB0))) {}
когда надо проверить, что бит НЕ установлен и тоже самое, без !, когда надо проверить, что бит установлен.
Потому что с ==0 еще будет работать, а когда захотите проверить что бит установлен и напишите == 1 оно будет работать только для PB0, где-то прям в этой теме я уже по-моему вам об этом писал.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Программирование ATtiny13

Сообщение ARV »

для avr-gcc всех версий есть "стандартный" макрос bit_is_set (или его антогонист - bit_is_clear), который по меньшей мере при прочтении не введет в заблуждение:

Код: Выделить всё

if(bit_is_set(PINB, PB0)){
}

if(bit_is_clear(PINB, PB3){
}
понятно без комментариев каждому, кто знает 25 английских слов...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm, перечитал много раз. Ну не понимаю я

пускай не PB0 , а PB2

(1<<PB2) - это 0b0000 0100

пускай состояние PINB - 0b1111 1111

и мне нужно узнать состояние пина PB2 (3й бит)

0b1111 1111 И 0b0000 0100 =0b0000 0100, т.е не 0, т.е в этом байте есть хотя бы одна единица это не ==0

если состояние PINB - 0b1111 1001

0b1111 1001 И 0b0000 0100 =0b0000 0000, т.е все 0. т.е ==0

Дошло!!! Полезно писать посты. Позволяет собрать мысли до кучи.

Добавлено after 1 minute 54 seconds:
NStorm писал(а):а когда захотите проверить что бит установлен и напишите == 1 оно будет работать только для PB0,
0b1111 1111 И 0b0000 0100 =0b0000 0100, т.е не 0, т.е в этом байте есть хотя бы одна единица это не ==0


работает и для PB2 , разве нет?

или нужна именно единица младшего бита что бы приравнять к 1 (==1)?
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

или нужна именно единица младшего бита что бы приравнять к 1 (==1)?
Ну а вы как думаете? Разве 0b0000 0100 равно 1?
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm писал(а):Разве 0b0000 0100 равно 1?
001
010
011
100

это походу 100=4. Вот оно как.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15585
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Программирование ATtiny13

Сообщение BOB51 »

У адуринки есть другой способ побитовых проверок/операций с битами:

Код: Выделить всё

Bits and Bytes

lowByte()
highByte()
bitRead()
bitWrite()
bitSet()
bitClear()
bit()
:roll:
Ответить

Вернуться в «AVR»