Как в программе выполнить несколько действий всего один раз.

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 19
Зарегистрирован: Вт сен 10, 2013 18:12:58

Сообщение Sergik07 »

Прошу помочь с решением задачи.
Условия такие: при значении АЦП 990 PB.3 переключается с высокого уровня на низкий. Одновременно с этим на PB.0 подаем высокий уровень,ждём 5 сек. и подаем низкий уровень. Действия с PB.0 должны происходить всего один раз,пока на PB.3 низкий уровень. При значении АЦП меньше 990 на PB.3 устанавливается высокий уровень и все повторяется при подаче на PB.3 низкого уровня. С АЦП я разобрался,но вот с как заставить выполнить 3 действия с PB.0 всего один раз в течение всего времени, пока на PB.3 низкий уровень, сообразить не могу. Совсем забыл, всё действие происходит в Bascom на tiny13. Может знающие люди натолкнут на идею, а уж за пример и совсем спасибо.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Добавить флаг срабатывания РВ.0 и анализировать его состояние и состояние РВ.3 перед переключением.
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

Перечитал условие (надо писать яснее) - наверное хотите скорее так (это лишний раз показывает гибкость автомата состояний)

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

switch(state)
{
case COMPARISON_HIGH:
if(adc_read()>=990) state=ADC_HIGH;
break;

case COMPARISON_LOW:
if(adc_read<990)state=COMPARISON_HIGH;
break;

case ADC_HIGH:
PB.0=1;
_delay_ms(5000);
PB.0=0;
state=COMPARISON_LOW;
break;

default:
break;

}
Может я ошибаюсь, но Ваш код на Баскоме?
Нет конечно, это псевдо Си код. Перегоняйте на баском самостоятельно, тем более, как пишут его апологеты, он не менее гибок чем Си, тем более псевдо )))
Последний раз редактировалось Goodefine Вт сен 10, 2013 20:06:10, всего редактировалось 1 раз.
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Родился
Сообщения: 19
Зарегистрирован: Вт сен 10, 2013 18:12:58

Сообщение Sergik07 »

Goodefine писал(а):

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

switch(state)
{
case COMPARISON:
if(adc_read()>=990) state=ADC_HIGH else state=ADC_LOW;
break;

case ADC_LOW:
PB.3=1;
state=COMPARISON;
break;

case ADC_HIGH:
PB.3=0;
PB.0=1;
_delay_ms(5000);
PB.0=0;
state=COMPARISON;
break;

default:
break;

}
Задержку лучше сделать по таймеру, тупо ждать и ничего не делать - не по фэншую
Может я ошибаюсь, но Ваш код на Баскоме?
Реклама
Эиком - электронные компоненты и радиодетали
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

См. выше
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Реклама
Родился
Сообщения: 19
Зарегистрирован: Вт сен 10, 2013 18:12:58

Сообщение Sergik07 »

Goodefine писал(а): Перегоняйте на баском самостоятельно, тем более, как пишут его апологеты, он не менее гибок чем Си, тем более псевдо )))
Спасибо. Не уверен,что справлюсь,но буду пробовать.
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

Главное поймите принцип и что дает такой подход
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Родился
Сообщения: 19
Зарегистрирован: Вт сен 10, 2013 18:12:58

Сообщение Sergik07 »

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

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

$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 16
$swstack = 16
$framesize = 20
$sim
Config Adc = Single , Prescaler = Auto , Reference = Internal       

Config Portb.0 = Output
Config Portb.2 = Output
Config Portb.3 = Output
Led Alias Portb.0
Dd_on Alias Portb.2
Svet_on Alias Portb.3

Dim Zn As Word
Dim D As Bit
Dim R As Byte

Start Adc                                                   

Do

Zn = Getadc(2)                                              'PB.4  Pin.3 ÍÅ òðîãàòü!
If Zn >= 1010 Then
Reset Dd_on : Set Led
Else
Set Dd_on : Reset Led
End If

If Dd_on = 0 Then
Set Svet_on
Wait 4
Reset Svet_on
End If

Loop

End
хотел сделать так,что при Dd_on = 0
вот это

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

Set Svet_on
Wait 4
Reset Svet_on
выполнялось всего один раз. Пока сделать так у меня не получается.
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

Поскольку Dd_on (кстати, не стесняйтесь давать переменным более информативные имена, не из одной-трех букв, а константы писать большими буквами) устанавливается в 0 только при определенном значении АЦП, то и указанные действия можно делать при проверке АЦП, не обязательно проверять Dd_on:

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

Dim flag as Bit
flag=1

If Zn >= 1010 Then
Reset Dd_on : Set Led

if flag=1 Then
Set Svet_on
Wait 4
Reset Svet_on
flag=0
End If

Else
Set Dd_on : Reset Led
flag=1
End If
Если хотите по своему, то такой вариант:

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

Dim flag as Bit
flag=1

If Zn >= 1010 Then
Reset Dd_on : Set Led
Else
Set Dd_on : Reset Led
flag=1
End If

If Dd_on = 0 And flag=1 Then
Set Svet_on
Wait 4
Reset Svet_on
flag=0
End If
Но я бы посоветовал разобраться с автоматом состояний, пригодится в дальнейшем - он позволяет делать довольно сложные и понятные при этом ветвления.
ЗЫ - баском не знаю и Вам его не советую
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Родился
Сообщения: 19
Зарегистрирован: Вт сен 10, 2013 18:12:58

Сообщение Sergik07 »

Goodefine писал(а): ЗЫ - баском не знаю и Вам его не советую
Огромное спасибо за пример. Это именно то, что нужно.
Так как я совсем начинающий, мне показалось, что Bascom мне более понятен.
Ещё раз спасибо.
Ответить

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