Но с портом D она же работает... Как правильно записать эту строку?ее результат - не логическая константа
Нескольно простых вопросов о программировании AVR на Си.
- Реклама
Код: Выделить всё
while (PINB&(1 << PB4)){}Она С портом D она работает только потому, что это PD0, а не другой пин. (1<<PD0) как раз равен 1, вот и "повезло".
Лучше сравнивать либо как выше Карбофос предложил, или:
Лучше сравнивать либо как выше Карбофос предложил, или:
Код: Выделить всё
while (PINB & (1 << PB4) == (1 << PB4)){}Спасибо!
А строку не нужно менять?
А строку не нужно менять?
Код: Выделить всё
while ((PINB&(1 << PB4)) == 0){} // Ждем пока на выводе PB4 лог. 0Можно не менять, а можно короче записывать:
Код: Выделить всё
while (!(PINB & (1 << PB4)); // висим, пока на пине 0
while (PINB & (1 << PB4); // висим, пока на пине 1- Реклама
Спасибо! Запустил смену светодиода по тактовой кнопке... ну и не только.
Вот полный говнокод:
Самое противное, что не работают последние четыре строчки. Я не настоящий сварщик. Образумьте, подскажите, в чем ошибся.
Вот полный говнокод:
Спойлер
Код: Выделить всё
#define F_CPU 9216000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main()
{
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPCE) | (0 << CLKPS3) | (0 << CLKPS2) | (1 << CLKPS1) | (0 << CLKPS0);//Делим на 4
DDRB= 0b01101110;
PORTB=0b001011101;
TCCR0A=0;
TCCR0B=0;
TCCR0A|= (1<<WGM01); //Выставляем режим CTC
TCCR0A|= (1<<COM0A0); //Инвертируем значение OC0A по срабатыванию таймера.
TCCR0B|= (1<<CS02); //Ставим предделитель на значение 256. Запускаем генерацию
OCR0A=134;
TCCR1A = (1 << COM1A1) | (1 << WGM12) | (1 << WGM10); // Выставляем FAST PWM
TCCR1B = (1 << CS12) | (1 << CS10); // Предделитель
TCNT1=0; // clear counter
ICR1=23039; // 100 Hz from 9216000/4 MHz clock
TCCR1A=0b10000010; // non-inverting, fast PWM
TCCR1B=0b00011001; // fast PWM, full speed
OCR1A=20000; // 86% strobe
while(1) {
while (PINB&(1 << PB4)){} // Ждем пока на выводе PB4 лог. 1
_delay_ms(50); // Задержка
if ((PINB&(1 << PB6)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB6); // Лог. 1 на выводе PB0
PORTB &= ~(1 << PB5); // Лог. 0 на выводе PB1
OCR0A=134;
}
else
{
PORTB &= ~(1 << PB6); // Лог. 0 на выводе PB0
PORTB |= (1 << PB5); // Лог. 1 на выводе PB1
OCR0A=99;
}
while (!(PINB & (1 << PB4))) // Ждем пока на выводе PDO лог. 0
_delay_ms(50);}// Задержка
if (PORTB &= ~(1 << PB0))
{PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);}
}
Последний раз редактировалось slonek Ср ноя 17, 2021 00:55:15, всего редактировалось 1 раз.
Код: Выделить всё
if (!(PORTB & (1 << PB0)))
{
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);
}
} // Задержка
Фигурная скобка.
Надо так:
Точка с запятой.
Код: Выделить всё
} // ЗадержкаКод: Выделить всё
while (!(PINB & (1 << PB4))); // Ждем пока на выводе PDO лог. 0
_delay_ms(50);}// Задержка
Так у меня так и есть....
Это другая тактовая кнопка. Переключающая светодиоды и подающее высокое на PB1 - это разные кнопки. Их две.
Это другая тактовая кнопка. Переключающая светодиоды и подающее высокое на PB1 - это разные кнопки. Их две.
Просто словами опишите, где кнопки, и что хотите получить.
Иначе, получается разговор глухого с немым.
И, вот такие конструкциивы сами сможете их завтра понять?
Вот это что было?
Вот эток чему?
Вот это тож что за писец?
Дальше не хочу смотреть.
Иначе, получается разговор глухого с немым.
И, вот такие конструкции
Код: Выделить всё
TCCR1A = 0b10000010; // non-inverting, fast PWM
TCCR1B = 0b00011001; // fast PWM, full speedКод: Выделить всё
TCCR0A = 0;
TCCR0B = 0;
TCCR0A |= (1 << WGM01); //Выставляем режим CTC
TCCR0A |= (1 << COM0A0); //Инвертируем значение OC0A по срабатыванию таймера.
TCCR0B |= (1 << CS02); //Ставим предделитель на значение 256. Запускаем генерациюВот это
Код: Выделить всё
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPCE) | (0 << CLKPS3) | (0 << CLKPS2) | (1 << CLKPS1)
| (0 << CLKPS0); //Делим на 4Вот это
Код: Выделить всё
TCCR1A = (1 << COM1A1) | (1 << WGM12) | (1 << WGM10); // Выставляем FAST PWM
TCCR1B = (1 << CS12) | (1 << CS10); // Предделитель
TCNT1 = 0; // clear counter
ICR1 = 23039; // 100 Hz from 9216000/4 MHz clock
TCCR1A = 0b10000010; // non-inverting, fast PWM
TCCR1B = 0b00011001; // fast PWM, full speed
Дальше не хочу смотреть.
МК представляет собой два генератора. Один из них постоянно шарашит 100Гц на выводе OC1A (PB3).Просто словами опишите, где кнопки, и что хотите получить.
Иначе, получается разговор глухого с немым.
Второй может выдавать 45 Гц и 33,33 Гц на выводе OC0A (PB2). Смена значения частоты производится нажатием кнопки (PB4). В зависимости от текущего значения частоты производится индикация на выводах PB5 или PB6.
Также, к выводу PB0 подключена вторая кнопка. При ее нажатии на выводе PB1 напряжение меняется от 0 до 5В на заданное время (500ms).
[uquote="slonek",url="/forum/viewtopic.php?p=4123649#p4123649"]Спасибо! Запустил смену светодиода по тактовой кнопке... ну и не только.
Вот полный говнокод:
***
Самое противное, что не работают последние четыре строчки. Я не настоящий сварщик. Образумьте, подскажите, в чем ошибся.[/uquote]
Эти что-ли?
Так они и не будут работать. Вы в самом условии меняете бит PB0 в регистре PORTB, а не проверяете его.
if ( (PORTB & (1 << PB0)) != 0 ) - Перевожу на человеческий:
1. Берем регистр PORTB.
2. Применяем к нему побитовое "И" со значением, полученным от выражения (1 << PB0), таким образом, отбрасывая все биты, кроме PB0
3. Если после пункта 2 у нас получилось не нулевое значение, то выполняем действия. А иначе, пропускаем их.
Ввиду того, что в выражении (1 << PB0) оба значения являются константами, то это выражение выполнит компилятор, а не микроконтроллер, и подставит готовый результат оператору "&" (PORTB & value), который выполнит уже сам микроконтроллер.
Вот полный говнокод:
***
Самое противное, что не работают последние четыре строчки. Я не настоящий сварщик. Образумьте, подскажите, в чем ошибся.[/uquote]
Эти что-ли?
Код: Выделить всё
if (PORTB &= ~(1 << PB0))
{
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);
}
Код: Выделить всё
if ( (PORTB & (1 << PB0)) != 0 ) // Сработает, если PB0 = 1. Если нужно наоборот, то писать нужно так: if ( (PORTB & (1 << PB0)) == 0 )
{
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);
}
if ( (PORTB & (1 << PB0)) != 0 ) - Перевожу на человеческий:
1. Берем регистр PORTB.
2. Применяем к нему побитовое "И" со значением, полученным от выражения (1 << PB0), таким образом, отбрасывая все биты, кроме PB0
3. Если после пункта 2 у нас получилось не нулевое значение, то выполняем действия. А иначе, пропускаем их.
Ввиду того, что в выражении (1 << PB0) оба значения являются константами, то это выражение выполнит компилятор, а не микроконтроллер, и подставит готовый результат оператору "&" (PORTB & value), который выполнит уже сам микроконтроллер.
I am DX168B and this is my favourite forum on internet!
байт с четвертым битом, равным 1, имеет значение, не равное 1! результат наложения маски на байт надо проверять на 0: равно - бит сброшен, не равно - бит установлен.
а еще лучше пользоваться макросами bit_is_set и bit_is_clear
а еще лучше пользоваться макросами bit_is_set и bit_is_clear
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
ARV такой вопрос по поводу этих макросов (bit_is_set / bit_is_clear). Они случайно не превращаются после компиляции в инструкции SBRC / SBRS для регистров РОН и SBIC / SBIS для регистров I/O?
I am DX168B and this is my favourite forum on internet!
- Сообщения: 1430
- Зарегистрирован: Вт июн 07, 2011 08:03:18
[uquote="ARV",url="/forum/viewtopic.php?p=4124350#p4124350"]а еще лучше пользоваться макросами bit_is_set и bit_is_clear[/uquote]
ARV, думаю, лучше говорить "А ВОТ МНЕ лучше/удобнее пользоваться..."
Или объяснить чем же лучше.
ARV, думаю, лучше говорить "А ВОТ МНЕ лучше/удобнее пользоваться..."
Или объяснить чем же лучше.
для человека, не вполне понимающего, что X & (1<<3) никогда не может быть равно 1, однозначно лучше пользоваться готовыми макросами
Добавлено after 2 minutes 9 seconds:
Добавлено after 2 minutes 9 seconds:
честно говоря, мне по барабану, во что они превращаются - хоть в тыкву... хотя предположу, что таки да, в эти ассемблерные конструкции (если аргументы однобайтовые, конечно)DX168B писал(а):Они случайно не превращаются после компиляции
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Камрады! По совету DX168B испробовал два варианта. Итак:
При коде:
На кнопку PB0 реакции нет. Но при нажатии на кнопку PB4 вместе со сменой частоты (на PB3) и индикации на светодиодах (PB5 и PB6), включается PB1 на указанное время. Каждый раз при смене частоты (нажатии на PB4).
При коде
При нажатии на PB4 меняются частота и индикация. Реакции на кнопку PB0 нет. Индикация PB1 на кнопку PB4, в отличии от предыдущего случая, не реагирует.
Напомню. Есть кнопки. PB4 и PB0. PB4 меняет генерируемую частоту и индикацию на PB5, PB6. Кнопка PB0 должна на заданное время выдавать высокое на PB1.
Что хочу получить:
По нажатию на PB4 - меняется частота генерации, меняется индикация
По нажатию PB0 - на выходе PB1 подается высокое на заданное время.
Кнопки не зависимы друг от друга.
Полный говнокод выкладывал несколькими постами ранее.
При коде:
Код: Выделить всё
if ( (PORTB & (1 << PB0)) != 0 )
{
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);
}При коде
Код: Выделить всё
if ( (PORTB & (1 << PB0)) == 0 )
{
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB1);
}Напомню. Есть кнопки. PB4 и PB0. PB4 меняет генерируемую частоту и индикацию на PB5, PB6. Кнопка PB0 должна на заданное время выдавать высокое на PB1.
Что хочу получить:
По нажатию на PB4 - меняется частота генерации, меняется индикация
По нажатию PB0 - на выходе PB1 подается высокое на заданное время.
Кнопки не зависимы друг от друга.
Полный говнокод выкладывал несколькими постами ранее.
подскажите пожалуйста
почему команда
очищает строку
а команда
НЕТ
почему команда
Код: Выделить всё
char str[] = "\0";а команда
Код: Выделить всё
char *str = "\0";Tell Me The Truth
обе эти строки не очищают ничего, они присваивают указателю значение, равное адресу, по которому находится нолик. очистка строки, как по мне, так это заполнение всего массива символов строки нулями или пробелами - смотря что под очисткой понимать
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


