Здравствуйте уважаемые коты. Извините если не туда написал. Я начинающий в изучении МК так что очень надеюсь на вашу помощь.
Как базу программы использовал обычное мигание светодиодом, в схему вместо светодиода включил реле, суть задачи - регулировать временные задержки двумя подстроечными резисторами. Покопался в сети и понял что мне нужно использовать АЦП, но так как я не силён в С - возникли проблемы с написанием кода.
Пишу в CVAVR, МК - atmega8.
Вот код который у меня получился (пока для одного резистора, работает как-то неадекватно):
ну общая идея видимо такая - длительность первой паузы (единички на выходе) должна зависеть от угла поворота подстроечника, выходит, что меняется она от 0 сек до 1 часа если в остальном нет косяков, а вот что хотелось - непонятно
Последний раз редактировалось Morroc Вт апр 01, 2014 12:45:30, всего редактировалось 1 раз.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
хотелось бы знать чего именно (в цифириях) хотел автор
sanyo.95 писал(а):
Пишу в CVAVR, МК - atmega8.
а нужно обязательно на C в CVAVR, ну т.е. цель - научиться работать с мк на низком уровне или это необязательно ? а то можно с "ардуин" начать - ни портов побитно ни прерываний ковырять не надо, все обернуто в готовые функции, r = analogRead(); и вперед, даже инициализировать не нужно особо ничего
sanyo.95 писал(а):Покопался в сети и понял что мне нужно использовать АЦП, но так как я не силён в С - возникли проблемы с написанием кода
лучше покопаться еще и посмотреть пример работы с АЦП - все чутка сложнее, чем в вашем коде
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Morroc писал(а):ну общая идея видимо такая - длительность первой паузы (единички на выходе) должна зависеть от угла поворота подстроечника, выходит, что меняется она от 0 сек до 1 часа если в остальном нет косяков, а вот что хотелось - непонятно
Именно это я хочу осуществить только не до 1 часа, а до 10с максимум , и вторая задержка на которой 0, тоже должна регулироваться.
Gudd-Head писал(а):а нужно обязательно на C в CVAVR, ну т.е. цель - научиться работать с мк на низком уровне или это необязательно ?
Да, обязательно.
Morroc писал(а):хотелось бы знать чего именно (в цифириях) хотел автор
Не понял вопроса?
Gudd-Head писал(а):лучше покопаться еще и посмотреть пример работы с АЦП
Вот именно по той причине, что самостоятельно я не разобрался пишу сюда.
если 10 с надо максимум - зачем 3000 * результат ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Спасибище!!! Всё работает. Насчет 3000мс ты прав способом подбора поставил 20мс
Есть пара вопросов:
Morroc писал(а):Мы ведь можем из АЦП и 1000 считать
А можно как-то определить какое значение идет с АЦП?
Morroc писал(а):ACSR=0x80; // это вроде к компаратору относится, оно точно нужно ?
Это я не знаю, к сожалению
Morroc писал(а):while((ADCSRA & 0x10)==0); // <- чего то такого по идее не хватает тут
Поясни пожалуйста, что означает эта строка?
1. Чтобы регулировать другую задержку нужна ещё одна переменная?
2. Насколько я понимаю АЦП не может работать с двумя входами одновременно - нужны ли прерывания?
3. Регулировка ведь не зависит от номинала резистора?
Пока наверное хватит
Спасибо ещё раз что откликнулся
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к
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
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
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 другим подстроечником - так надо ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
не пробовал, но там дважды одно значение считывается и каналы АЦП не переключаются - работать то может и работает, только длительность 0 и 1 таким кодом должна регулироваться одновременно одним резистором
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Извините пожалуйста. Пришлось немного переделать данную программу. Суть такова: если тумблер включен то на определенный промежуток времени включается 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 работает, вроде как надо. На реальном устройстве выполняется только раз.
Посмотрите пожалуйста код и посмотрите что не так?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /