Страница 1 из 11
Программирование ATtiny13
Добавлено: Вт ноя 05, 2019 16:42:54
Евгений07
Здравствуйте, помогите пожалуйста разобраться с задержкой, пишу прогу для тини13, у меня две кнопки пин3 и пин4 и один выход порт 0. Нужно при нажатом пин3 горит светодиод на порту0 а при отпускании гаснет, следующий алгоритм при нажатом пине3 нажимаем пин4 и светодиод на порту 0 через 20сек должен погаснуть, использовал функцию иф и вайл задержку ставил в вайл но она работает ка при нажатии и при отпускании пин4 а надо только при нажатии,
Re: Программирование ATtiny13
Добавлено: Вт ноя 05, 2019 17:41:43
NStorm
Хорошо, делайте. Мы не против.
Вопрос-то в чем?
https://www.opennet.ru/docs/RUS/smart_question/
Re: Программирование ATtiny13
Добавлено: Вт ноя 05, 2019 20:01:03
Евгений07
[uquote="NStorm",url="/forum/viewtopic.php?p=3731184#p3731184"]Хорошо, делайте. Мы не против.
Вопрос-то в чем?
https://www.opennet.ru/docs/RUS/smart_question/[/uquote]
как поставить задержку выключения светодиода на порте 0 при нажатой кнопке пин4 а при отпускании он должен снова сразу включиться т,к, пин 3 кнопка нажата постоянно а она отвечает за порт 0 (нажата то =лог-1 если нет то лог-0), сам не могу осилить уже пять дней мучаюсь, я файл атмел студио прикрепил!
Добавлено after 5 minutes 5 seconds:
https://drive.google.com/drive/folders/ ... sp=sharing Вот мой исходник.
Re: Программирование ATtiny13
Добавлено: Вт ноя 05, 2019 21:44:47
NStorm
Такое впечатление, что цифры 07 в нике - год рождения.
PS: Файл atsln никому не нужен, там нет "исходника".
Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 11:11:41
Евгений07
Одни умники смотрю собрались, а помочь некому!
Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 11:21:47
Ivanoff-iv
открой свой атмел студио, скопируй свой код оттуда, здесь в редакторе его вставь, только не забуь завернуть в теги "код" и "спойлер" тогда коты хотя-бы
смогут тебе помочь...
Добавлено after 5 minutes 50 seconds:
хотя, если честно, ответ
NStormа мне понравился...

Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 11:58:55
BOB51
Ни схемы ни прожки...
Адуринья что-ли?

Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 16:14:09
Dimon456
Евгений07 писал(а):я файл атмел студио прикрепил!
Спойлер
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
#define Bit(bit) (1<<(bit))
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))
#define BitIsClear(reg, bit) ((reg & (1<<(bit))) == 0)
#define PAUZA 200 // 200 * 100ms =20 000ms
int main()
{
static uint8_t a;
SetBit(DDRB, DDB0) ; ClearBit(PORTB, PB0);
ClearBit(DDRB ,DDB4); ClearBit(DDRB, DDB3); SetBit(PORTB, PB4); SetBit(PORTB, PB3);
while (1) {
if (BitIsClear(PINB,PINB3)) {
if ( a== PAUZA ) { ClearBit(PORTB, PB0);
} else { SetBit(PORTB, PB0); }
if (BitIsClear(PINB,PINB4)) {
if( ++a > PAUZA) { a=PAUZA; }
_delay_ms (100);
} else { a = 0; }
} else { ClearBit(PORTB, PB0); a = 0; }
};
}
Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 20:07:53
Евгений07
<# define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB |= (1<<0);
PORTB &= ~ (1<<0);
DDRB &= ~((1<<3) | (1<<4));
PORTB &= ~ ((1<<3) | (1<<4));
while (1)
{
if (PINB & (1<<3))
{
PORTB |= (1<<0);
}
else
{
PORTB &= ~ (1<<0);
}
while (PINB & (1<<4))
{
PORTB &= ~ (1<<0);
_delay_ms(2000);
}
}
}>
Добавлено after 6 minutes 11 seconds:
Вы меня извините, но я только начал во всем этом разбираться и как тут правильно просить о помощи еще не знаю!
По этому коду пин 4 гасит сразу порт 0 а при отпускании пина 4 через 2 сек зажигает а надо наоборот!
Добавлено after 1 minute 16 seconds:
Пин 4 нажимаю только тогда когда зажат пин3
Re: Программирование ATtiny13
Добавлено: Ср ноя 06, 2019 20:52:25
dr.doc
как поставить задержку выключения светодиода на порте 0 при нажатой кнопке пин4 а при отпускании он должен снова сразу включиться т,к, пин 3 кнопка нажата постоянно а она отвечает за порт
Спойлер
if(!((PORTB & (1<<PB3)) && (PORTB & (1<<PB4)))) // проверка на нажатие двух кнопок
{
unsigned int count = 1000; // us delay - количество микросекунд задержки
while(count)
{
delay_us(1);
if(1<<PB4) // как только отпущена - включим светодиод
{
PORTB |=(1<<PB0);
count=1; // и установим счетчик для выхода из задержки
}
count--; // или тупо ждем в цикле положенное время
}
}
код не отлаживал, писал прямо тут, поэтому за мелкие баги прошу прощения
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 19:52:17
olegue
У меня такая проблема. Я хочу на тиньке 13 (сабж) сделать небольшую программулю, наподобии той что хотел ТС, но даже проще.
Я взял готовую прогу с Атмеги 8 с этого сайта
https://radioparty.ru/programming/avr/c/225-lesson2
Т.е нажимаю на кнопку, загорается диод, нажимаю еще раз - диод гаснет. Все.
С зажиганеим диодом я разобрался. А вот с кнопками нет.
Я взял ПРОТЕУС 8.5 и загрузил туда этого код для Атмеги8 что бы проверить его, а затем переложить на Тиньку13
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 0x00; // Порт D вход
PORTD = 0xFF; // Подключаем подтягивающие резисторы
DDRB = 0xFF; // Порт B выход
PORTB = 0x00; // Лог. 0 на выходе
while(1)
{
while ((PIND&(1 << PD0)) == 1){} // Ждем пока на выводе PDO лог. 1
_delay_ms(200); // Задержка 200мс
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
}
while ((PIND&(1 << PD0)) == 0){} // Ждем пока на выводе PDO лог. 0
_delay_ms(200); // Задержка 200мс
}
}
Добавлено after 25 minutes 26 seconds:
Я начал перекладывать код на Тинку, с сохранением логики
Самое главное это отличие в портах
это код из Атмега 8
DDRD = 0x00; // Порт D вход
PORTD = 0xFF; // Подключаем подтягивающие резисторы
DDRB = 0xFF; // Порт B выход
PORTB = 0x00; // Лог. 0 на выходе
У меня на тиньке столько портов нету поэтому все приходится делать на порте PORTB
к PB0 я подключу светодиод через резистор 220 ом и сделаю этот порт выходом
к PB1 я подключу кнопку сразу на массу и сделаю этот порт входом
DDRB = 0x00000001 (последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод)
PORTB= 0x11111110 (по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
Теперь там где ((PIND&(1 << PD0)) == 1) меняю на PINB и PB1
те. вот так
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
//DDRD = 0x00; // Порт D вход
//PORTD = 0xFF; // Подключаем подтягивающие резисторы
//DDRB = 0xFF; // Порт B выход
//PORTB = 0x00; // Лог. 0 на выходе
DDRB = 0x00000001; //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод)
PORTB= 0x11111110; //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while(1)
{
while ((PINB&(1 << PB1)) == 1){} // Ждем пока на выводе PDO лог. 1
_delay_ms(200); // Задержка 200мс
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
}
while ((PINB&(1 << PB1)) == 0){} // Ждем пока на выводе PDO лог. 0
_delay_ms(200); // Задержка 200мс
}
}
Ошибки компилятор не дает, но именно на цикле while не сработки. Цикл while (ожидание нажатие) просто пролетает до следующий строки
Что у меня тут не так?
Добавлено after 23 minutes 52 seconds:
т. е сейчас так: я нажимаю на кнопку - начинается миганием светодиода, нажимаю другой раз и третий и тд мигание продолжается.
Должно быть: нажал - светодиод вспыхнул, нажал еще раз - погас.
Сейчас задержка которая для устранения дребезга фактически является причиной мигания светодиода.
Непонятненько.
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 20:00:16
NStorm
Не надо магических цифр. Особенно писать в биты регистра, которые помечены как read-only. Не надо сравнивать с 1 результат AND (&). 1<<PB1 равно 2, а никак не 1. А в исходном работало, потому что там были PD0/PB0, которые = 1. Но это изначально убогий код был.
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
//DDRD = 0x00; // Порт D вход
//PORTD = 0xFF; // Подключаем подтягивающие резисторы
//DDRB = 0xFF; // Порт B выход
//PORTB = 0x00; // Лог. 0 на выходе
DDRB = (1 << PB0); //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод)
PORTB= (1 << PB1); //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while(1)
{
while ((PINB&(1 << PB1))); // Ждем пока на выводе PDO лог. 1
_delay_ms(200); // Задержка 200мс
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
}
while (!(PINB&(1 << PB1))); // Ждем пока на выводе PDO лог. 0
_delay_ms(200); // Задержка 200мс
}
}
PS: Чисто для этого тинька не нужна, это обычный триггер.
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 20:18:49
olegue
Да, все работает как часы. Спасибо. Теперь есть хороший пример.
Полдня провозился. Может и еще бы неделю.
NStorm писал(а):Особенно писать в биты регистра, которые помечены как read-only
а что вы здесь имели ввиду. Биты pb6 и pb7, которым ног не досталось?
NStorm писал(а):Не надо сравнивать с 1 результат AND (&). 1<<PB1 равно 2, а никак не 1
здесь тоже не понял, если честно
NStorm писал(а):Но это изначально убогий код был.
это Вы про использование прерываений намекаете?
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 20:53:09
NStorm
[uquote="olegue",url="/forum/viewtopic.php?p=3734954#p3734954"]а что вы здесь имели ввиду. Биты pb6 и pb7, которым ног не досталось?[/uquote]
Вроде того. Только таких бит нет. В ДШ загляните, там написано что их просто нет, они RESERVED и только для чтения. Проблема была не в этом, но в целом подобного надо избегать. Где-нибудь, в другом месте, на другом МК это можно вызвать проблему.
[uquote="olegue",url="/forum/viewtopic.php?p=3734954#p3734954"]
NStorm писал(а):Не надо сравнивать с 1 результат AND (&). 1<<PB1 равно 2, а никак не 1
здесь тоже не понял, если честно[/uquote]
((PIND&(1 << PD0)) == 1) - конструкция плохая. Нельзя так писать. Потому что в случае с
((PIND&(1 << PD1)) == 1) - она уже никогда не будет равна 1. Она будет равна 0 или 2. Поэтому нет смысла сравнивать с цифрой. Просто if/while ([!](PIND&(1 << PD0))) - если 0, оно и так НЕТ, если отличное от нуля, оно ДА.
На пальцах - 1 << PD1 = 0b00000010, это понятно? Потому что PD1 = 1, но сдвинув 1 на 1 позицию влево получаем 2. Операция лог. И (&) с PIND в данном случае ну никак не может дать нам 1. Если на PD1 высокий уровень, в PIND будет 0bxxxxxx1x, где x - любое значение. В этом случае PIND & (1 << PD1) будет равен тому же 0b00000010 = 2.
Надеюсь понятно, такие вещи тыщу раз уже описаны везде.
[uquote="olegue",url="/forum/viewtopic.php?p=3734954#p3734954"]это Вы про использование прерываений намекаете?[/uquote]
Нет, в данном случае они не обязательны (разве что если нет желания экономить энергию и переводить МК в сон), см. выше.
EDIT: Ну и плюс вместо всего этого:
Код: Выделить всё
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
}
Пишется просто
PORTB ^= (1 << PB0);
Ну и форматировании я молчу )
Добавлено after 9 minutes 53 seconds:
В итоге хотя бы так должен выглядеть этот код:
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = (1 << PB0); //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод)
PORTB = (1 << PB1); //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while (1) {
while ((PINB & (1 << PB1))); // Ждем пока на выводе PB1 лог. 1
_delay_ms(200); // Задержка 200мс
PORTB ^= (1 << PB0);
while (!(PINB & (1 << PB1))); // Ждем пока на выводе PB1 лог. 0
_delay_ms(200); // Задержка 200мс
}
}
Только в реално железе скорее всего не помешают еще и внешние подтяжки посильнее, чем в аврке.
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 22:35:39
olegue
NStorm писал(а):Пишется просто
PORTB ^= (1 << PB0);
ну это вообще хит.
Добавлено after 36 seconds:
Не сегодня думаю хватит открытий.
Добавлено after 1 minute 31 second:
Счас думаю, как включить мигание и выключить мигание. Только дайте мне сначала самому подумать.
Добавлено after 1 hour 29 minutes 40 seconds:
Максимум что удалось придумать это включение мигания, Выключение не получается. Не знаю как из цикла мигания выйти
захожу в цикл мигания
while (1){
PORTB ^= (1 << PB0);
_delay_ms(200);
}
Код: Выделить всё
while(1)
{
while ((PINB&(1 << PB1))){} // Ждем пока на выводе PDO лог. 1 (Жднем нажатия)
_delay_ms(200); // Задержка 200мс
while (1){
PORTB ^= (1 << PB0);
_delay_ms(200);
}
while ((PINB&(1 << PB1))) {}
_delay_ms(200); // Задержка 200мс
}
Re: Программирование ATtiny13
Добавлено: Пн ноя 11, 2019 22:43:57
NStorm
olegue, варианты на выбор для размышления:
1. Прерывание на кнопку для "выхода из цикла". Она как раз на INT0 висит.
2. Таймер вместо delay.
3. Проверка кнопки в цикле мигания, выход по нажатию. Чтобы снизить время реакции, можно ждать "шагами":
Код: Выделить всё
while (1){
uint8_t i = 0, btn_flag = 0;
PORTB ^= (1 << PB0);
while (i <= 10) {
i++;
_delay_ms(20);
if (!((PINB & (1 << PB1)))) {
btn_flag = 1;
PORTB &= ~(1 << PB0);
break;
}
}
if (btn_flag) break;
}
Не супер точно 200 мс будет, потому что на i++ и if будут такты расходоваться, но думаю не принципиально в данном случае. Если принципиально, то это вар. 1 и 2.
Re: Программирование ATtiny13
Добавлено: Вт ноя 12, 2019 02:44:50
radteh
olegue, если не секрет, ты пишешь эту программу для того что-бы разобраться с МК или для практической задачи? Если второе, то тебе для включения\выключения достаточно взять к561тм2 или её аналог и с минимум обвеса добиться результата. Для мигания просто добавить генератор на к561ла7 например.
А если хочешь разобраться с МК, то предусмотри или в коде или аппаратное подавление дребезга от кнопки.
Re: Программирование ATtiny13
Добавлено: Вт ноя 12, 2019 08:58:24
olegue
radteh писал(а):если не секрет, ты пишешь эту программу для того что-бы разобраться с МК или для практической задачи?
какие уж тут секреты. Хочу разобраться с МК. И если дело пойдет, но наверняка гдето в далеке может замаячить что-то практическое.
Но, вот на данном уровне мигания диодов говорить об этом сильно преждевременно.
Пару дней вожусь, вижу,ч то элементарные, казалось бы задачи уже вызывают затруднения
Допустим, что бы просто зажечь диоды, тут с помощью интернета, кое как получилсь
А с кнопкой вообще беда. Тут еще и дребез нужно учитывать
с помощью
NStorm продвинулся может на месяц вперед.
Вот пример, казалось бы, на мой розум, должно все работать как надо
Вот код, в нем я жду нажатия кнопки.
Кнопка нажата, т.е PB стало 0, я вхожу в следующий цикл, где мигаю диодом, пока не нажму кнопку
Код: Выделить всё
while ((PINB & (1 << PB1))){
PORTB^=(1<<PB0);
_ms_delay(200);
};
После нажатия я должне опять перейти к строке первого цикла ожидания нажатия, но этого не происходит.
Добавлено after 2 minutes 4 seconds:
Код: Выделить всё
while(1)
{
while ((PINB&(1 << PB1))){} // Ждем пока на выводе PDO лог. 1 (Жднем нажатия)
_delay_ms(200); // Задержка 200мс
while ((PINB&(1 << PB1))){ /// Вот в этом цикле, как я полагаю должно быть мигание, которое выключится по нажатию кнопки.
PORTB ^= (1 << PB0);
_delay_ms(200);
}
}
вот полный код.
Добавлено after 1 minute 56 seconds:
т.е мигания нет. Происходит просто включения и выключения светодиода.
Добавлено after 11 minutes 43 seconds:
Такое впечатление, что этот цикл не крутиться
Код: Выделить всё
while ((PINB & (1 << PB1))){
PORTB^=(1<<PB0);
_ms_delay(200);
};
Re: Программирование ATtiny13
Добавлено: Вт ноя 12, 2019 09:07:19
BOB51
Ежли охота Си освоить - то тинька 13я не самое лучшее из имеющегося.
Другое дело - на чистом ассемблере в АВР студии 4.19 - там и симулятор работает
и места будет в достатке, и понятнее на уровне "железа".

Re: Программирование ATtiny13
Добавлено: Вт ноя 12, 2019 09:20:02
Ivanoff-iv
а что должно это делать? это генератор случайного состояния?
пока кнопка нажата у тебя по очереди быстро быстро проверяются оба условия, какой из циклов будет исполняться при отпускании кнопки - воля случая...
если хочешь стабильности, между циклами ожидающими отпускания кнопки вставь циклы, ожидающие нажатия...
пока(1){
пока (нажата){};
немного ждем; // антидребезг
пока (отпущена){};
немного ждем;
пока (нажата){};
немного ждем;
пока (отпущена){мигаем;};
гасим светодиод;
немного ждем;
}
примерно так...