Регулировка временных задержек подстроечным резистором???

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Здравствуйте уважаемые коты. Извините если не туда написал. Я начинающий в изучении МК так что очень надеюсь на вашу помощь.
Как базу программы использовал обычное мигание светодиодом, в схему вместо светодиода включил реле, суть задачи - регулировать временные задержки двумя подстроечными резисторами. Покопался в сети и понял что мне нужно использовать АЦП, но так как я не силён в С - возникли проблемы с написанием кода.
Пишу в CVAVR, МК - atmega8.
Вот код который у меня получился (пока для одного резистора, работает как-то неадекватно):

#include <mega8.h>
#include <delay.h>

void main(void)
{
int r;
ACSR=0x80;
SFIOR=0x00;
ADMUX=0;
ADCSR=0x85;
PORTB=0x00;
DDRB=0x1;

while (1)
{
ADCSR |=0x40;
r=ADCW;


PORTB.0=1;
delay_ms(3000*r);
PORTB.0=0;
delay_ms(3000);
}
};

Прикрепляю схему, проект в протеусе и прошивку.
Помогите пожалуйста.
01.jpg
Схема
(137.6 КБ) 494 скачивания
01.zip
Протеус, прошивка
(22.35 КБ) 199 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20104
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Без комментов в коде ничего не понятно что вы хотите сделать.
sanyo.95 писал(а):работает как-то неадекватно
Ничего удивительного :)
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

ну общая идея видимо такая - длительность первой паузы (единички на выходе) должна зависеть от угла поворота подстроечника, выходит, что меняется она от 0 сек до 1 часа если в остальном нет косяков, а вот что хотелось - непонятно
Последний раз редактировалось Morroc Вт апр 01, 2014 12:45:30, всего редактировалось 1 раз.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Друг Кота
Аватара пользователя
Сообщения: 20104
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Общая идея и так понятна.
Интересна её реализация в коде, сам алгоритм.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

считать ацп - сделать пропорциональную паузу

хотелось бы знать чего именно (в цифириях) хотел автор
sanyo.95 писал(а): Пишу в CVAVR, МК - atmega8.
а нужно обязательно на C в CVAVR, ну т.е. цель - научиться работать с мк на низком уровне или это необязательно ? а то можно с "ардуин" начать - ни портов побитно ни прерываний ковырять не надо, все обернуто в готовые функции, r = analogRead(); и вперед, даже инициализировать не нужно особо ничего
sanyo.95 писал(а):Покопался в сети и понял что мне нужно использовать АЦП, но так как я не силён в С - возникли проблемы с написанием кода
лучше покопаться еще и посмотреть пример работы с АЦП - все чутка сложнее, чем в вашем коде
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Реклама
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Morroc писал(а):ну общая идея видимо такая - длительность первой паузы (единички на выходе) должна зависеть от угла поворота подстроечника, выходит, что меняется она от 0 сек до 1 часа если в остальном нет косяков, а вот что хотелось - непонятно
Именно это я хочу осуществить только не до 1 часа, а до 10с максимум , и вторая задержка на которой 0, тоже должна регулироваться.
Gudd-Head писал(а):а нужно обязательно на C в CVAVR, ну т.е. цель - научиться работать с мк на низком уровне или это необязательно ?
Да, обязательно.
Morroc писал(а):хотелось бы знать чего именно (в цифириях) хотел автор
Не понял вопроса?
Gudd-Head писал(а):лучше покопаться еще и посмотреть пример работы с АЦП
Вот именно по той причине, что самостоятельно я не разобрался пишу сюда.
Реклама
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

начал что то писать, но похерилось :) отправлю пока сюда ->

http://radiokot.ru/forum/viewtopic.php?f=20&t=60071

если 10 с надо максимум - зачем 3000 * результат ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Morroc писал(а):начал что то писать, но похерилось :) отправлю пока сюда ->

http://radiokot.ru/forum/viewtopic.php?f=20&t=60071

если 10 с надо максимум - зачем 3000 * результат ?
Ну я по-другому не додумался как управлять задержкой :))

А насчет ссылки, я именно на примере этого устройства и пытался написать свой код, ну никак я не пойму как это работает.
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

Я не про управление задержкой, а про ее длительность. Мы ведь можем из АЦП и 1000 считать, умножим на 3000 и получим 3000000 мс ? многовато

#include <mega8.h>
#include <delay.h>

void main(void)
{
int r;
ACSR=0x80; // это вроде к компаратору относится, оно точно нужно ?
SFIOR=0x00;
ADMUX=0;
ADCSR=0x85;
PORTB=0x00;
DDRB=0x1;


while (1)
{
ADCSR |=0x40;

while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
ADCSRA|=0x10; // <- устанавливаем ADIF

r=ADCW;
PORTB.0=1;
delay_ms(3000*r);
PORTB.0=0;
delay_ms(3000);
}
};

а так работает ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Спасибище!!! Всё работает. Насчет 3000мс ты прав способом подбора поставил 20мс :))
Есть пара вопросов:
Morroc писал(а):Мы ведь можем из АЦП и 1000 считать
А можно как-то определить какое значение идет с АЦП?
Morroc писал(а):ACSR=0x80; // это вроде к компаратору относится, оно точно нужно ?
Это я не знаю, к сожалению :(
Morroc писал(а):while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
Поясни пожалуйста, что означает эта строка?

1. Чтобы регулировать другую задержку нужна ещё одна переменная?
2. Насколько я понимаю АЦП не может работать с двумя входами одновременно - нужны ли прерывания?
3. Регулировка ведь не зависит от номинала резистора?
Пока наверное хватит :sleep:
Спасибо ещё раз что откликнулся :)
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

sanyo.95 писал(а): А можно как-то определить какое значение идет с АЦП?
в такой конфигурации получится от 0 до 1023 (10 бит)
sanyo.95 писал(а):
Morroc писал(а):ACSR=0x80; // это вроде к компаратору относится, оно точно нужно ?
Это я не знаю, к сожалению :(
думаю можно убрать
sanyo.95 писал(а):
Morroc писал(а):while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
Поясни пожалуйста, что означает эта строка?
после запуска измерения нужно обязательно дождаться появления этого бита - он означает окончания измерения и только после этого можно считывать результат, в таком режиме (есть еще другой режим работы ацп - режим непрерывного измерения) после окончания измерения нужно сбросить этот бит, делается это с помощью ADCSRA|=0x10;
sanyo.95 писал(а): 1. Чтобы регулировать другую задержку нужна ещё одна переменная?
лучше бы да - оно понятнее будет
sanyo.95 писал(а): 2. Насколько я понимаю АЦП не может работать с двумя входами одновременно - нужны ли прерывания?
прерывание можно использовать как раз для измерения, а конкретный вход выбирается через ADMUX, в данном коде можно запускать в цикле сначала измерение при ADMUX=0, потом при ADMUX=1 (после переключения и до начала измерения нужно еще сделать delay_us(10);), потом формируем паузы
sanyo.95 писал(а): 3. Регулировка ведь не зависит от номинала резистора?
угу, если взять поменьше - будет ток через него "лишний" течь, если слишком большой - возможны помехи и какое то влияние сопротивления входа меги на измеряемое напряжение, 1к в принципе пойдет, но можно и 10к
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Morroc писал(а):прерывание можно использовать как раз для измерения, а конкретный вход выбирается через ADMUX, в данном коде можно запускать в цикле сначала измерение при ADMUX=0, потом при ADMUX=1 (после переключения и до начала измерения нужно еще сделать delay_us(10);), потом формируем паузы
Про паузы и прерывания чего - то не понял. Куда их писать и как?


В общем из всего, что я понял, слепил код под вторую задержку. В протеусе вроде работает. Выкладываю для исправления "неровностей".
И ещё хочу спросить по поводу Fuse bit - как их настроить?

Код:
#include <mega8.h>
#include <delay.h>

void main(void)
{
int r;
int t;
SFIOR=0x00;
ADMUX=0;
ADMUX=1;
ADCSR=0x85;
PORTB=0x00;
DDRB=0x1;


while (1)
{
ADCSR |=0x40;

while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
ADCSRA|=0x10; // <- устанавливаем ADIF

r=ADCW;
t=ADCW;
PORTB.0=1;
delay_ms(20*t);
PORTB.0=0;
delay_ms(20*r);
}
};
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

sanyo.95 писал(а): В протеусе вроде работает.
да ладно :) и что оно делает ?
sanyo.95 писал(а): И ещё хочу спросить по поводу Fuse bit - как их настроить?
целая тема есть про них - лучше туда, можно ничего не настраивать если устраивает работа от внутреннего генератора на тактовой 1 МГц


#include <mega8.h>
#include <delay.h>

void main(void)
{
int r;
int t;
SFIOR=0x00;
// ADMUX=0; <- тут убираем
// ADMUX=1;
ADCSR=0x85;
PORTB=0x00;
DDRB=0x1;


while (1)
{

//замер по одной ноге
ADMUX=0; // <- вставляем сюда
delay_us(10); // ждем чутка после переключения
ADCSR |=0x40;
while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
ADCSRA|=0x10; // <- устанавливаем ADIF
r=ADCW;

//замер по второй ноге
ADMUX=1; // <- вставляем сюда
delay_us(10); // ждем чутка после переключения
ADCSR |=0x40;
while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
ADCSRA|=0x10; // <- устанавливаем ADIF
t=ADCW;

// теперь длительность состояния 1 регулируется одним подстроечником, а длительность 0 на той же ноге PORTB другим подстроечником - так надо ?

PORTB.0=1;
delay_ms(20*t);
PORTB.0=0;
delay_ms(20*r);
}
};
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Спасибо большое за код, да и вообще за помощь, про фюзы почитаю.

Morroc писал(а):да ладно и что оно делает ?
Нет ну серьёзно работает, незнаю как но работает))) цепляю ,протеус и прошивку, посмотри:
01.rar
Протеус, прошивка
(20.53 КБ) 177 скачиваний
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Ну как, работает?
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

не пробовал, но там дважды одно значение считывается и каналы АЦП не переключаются - работать то может и работает, только длительность 0 и 1 таким кодом должна регулироваться одновременно одним резистором
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Вот почитал про фюзы, и понял что для этой схемы ничего не надо трогать. Исправте мненя, если это не так.
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Извините пожалуйста. Пришлось немного переделать данную программу. Суть такова: если тумблер включен то на определенный промежуток времени включается 1е реле(время его работы регулируется подстроечным резистором) а уже за ним включается 2е реле(время работы и время простоя регулируется подстроечными резисторами). "Написал" код( с вашей помощью), собрал, прошил - работает. Но проблема заключается в том, что программа выполняется только один раз(один цикл). Очень надеюсь на Вашу помощь. Выкладываю код:

#include <mega8.h>
#include <delay.h>

void main(void)
{
int r;
int t;
int w;
SFIOR=0x00;
ADCSR=0x85;

PORTB=0x00;
DDRB=0x1;

PORTB=0x02;
DDRB=0x03;


while (1)
{
//замер по ноге 00
ADMUX=0;
delay_us(10); // ждем после переключения
ADCSR |=0x40;
while((ADCSRA & 0x10)==0);
ADCSRA|=0x10; // устанавливаем ADIF
w=ADCW;

//замер по ноге 01
ADMUX=1;
delay_us(10); // ждем после переключения
ADCSR |=0x40;
while((ADCSRA & 0x10)==0);
ADCSRA|=0x10; // устанавливаем ADIF
r=ADCW;

//замер по ноге 02
ADMUX=2;
delay_us(10); // ждем после переключения
ADCSR |=0x40;
while((ADCSRA & 0x10)==0);
ADCSRA|=0x10; // устанавливаем ADIF
t=ADCW;


if(PINB.2==0) // если тумблер замкнут на 0
{
PORTB.1=1;
delay_ms(20*w); // на ножку РВ1 на время (20*w) подать 1, после отключения РВ1, выполнить следующее:
PORTB.1=0;
}
PORTB.0=1;
delay_ms(20*t);
PORTB.0=0;
delay_ms(20*r);
}
};

Если тумблер замкнут на 1, то выполняться должен только этот цикл:
РORTB.0=1;
delay_ms(20*t);
PORTB.0=0;
delay_ms(20*r);

В Proteus работает, вроде как надо. На реальном устройстве выполняется только раз.

Посмотрите пожалуйста код и посмотрите что не так?
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

а без строчки delay_ms(20*w); работает ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Morroc писал(а):а без строчки delay_ms(20*w); работает ?
Так если я её уберу реле же мгновенно переключиться и всё?
Не могу чего-то скомпилировать пишет "Linker error: the program has no 'main' function"...
Ответить

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