Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Attiny 2313 переключение режимов кнопкой


Attiny 2313 переключение режимов кнопкой

Сообщений 31 страница 58 из 58

31

если никто не против - ворвусь со своими боляками:
код управления одной кнопкой. беда - по первому нажатию кнопки нужное действие выполняется, а по второму - как игнорирует. что куда?

$Regfile="attiny85.dat"
$Crystal=8000000
$hwstack=40
$swstack=16
$framesize=32

Config Portb.0 = Output 'R
config portb.1 = output 'G
config portb.4 = output 'B
Config PORTB.3 = output 'áåëûé ñâåò
Config PINB.2 = input 'êíîïêà

Config Int0 = Falling : On INT0 Button
Config Timer1 = Timer , Prescale = 1 : On Timer1 Pwm_prog : Enable Timer1 : Enable Interrupts : start timer1 : Enable Int0

Dim S As Byte , A as Byte , C(3) as byte , B as Byte

1:
B=0
PORTB.3=0
for A=0 to 63                            'óâåëè÷èâàåì êðàñíûé
       C(1)=lookup(A , TAB_PWM)
       waitms 20
next

Do

If B=2 Then
for A=0 to 63                            'óâåëè÷èâàåì çåëåíûé
    C(2)=lookup(A , TAB_PWM)
    waitms 20
next

for A=63 to 0 step -1                    'óìåíüøàåì êðàñíûé
       C(1)=lookup(A , TAB_PWM)
       waitms 20
next
waitms 100
for A=0 to 63                             'óâåëè÷èâàåì ñèíèé
    C(3)=lookup(A , TAB_PWM)
    waitms 20
next

for A=63 to 0 step -1                     'óìåíüøàåì çåëåíûé
    C(2)=lookup(A , TAB_PWM)
    waitms 20
next
waitms 100
for A=0 to 63                             'óâåëè÷èâàåì êðàñíûé
       C(1)=lookup(A , TAB_PWM)
       waitms 20
next

for A=63 to 0 step -1                     'óìåíüøàåì ñèíèé
    C(3)=lookup(A , TAB_PWM)
    waitms 20
next
waitms 200
End If

loop

2:
If B=1 Then
PORTB.0 = 0 : PORTB.1 = 0 : PORTB.4 = 0 : PORTB.3 = 1 'âêëþ÷àåì áåëûé ñâåò
End if

end

Pwm_prog:
Incr S

if S=255 then S=0

If S<C(1) Then Set Portb.0 Else Reset Portb.0

If S<C(2) then Set Portb.1 Else Reset Portb.1

If S<C(3) then Set Portb.4 Else Reset Portb.4

Return

Button:
Incr B
'waitms 10
if B>2 then B = 1
if B=1 Then goto 2
if B=2 Then goto 1
Return

TAB_PWM:
Data 0 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 5 , 6 , 7 , 8 , 10 , 12 , 14 , 15
Data 17 , 20 , 22 , 24 , 27 , 30 , 32 , 35 , 38 , 42 , 45 , 48 , 52 , 56 , 59 , 63
Data 67 , 71 , 76 , 80 , 85 , 89 , 94 , 99 , 104 , 109 , 115 , 120 , 126 , 131 , 137 , 143
Data 149 , 155 , 161 , 168 , 174 , 181 , 188 , 195 , 202 , 209 , 216 , 224 , 231 , 239 , 247 , 255

0

32

Кто же из прерывания выходит через Goto? Как же стек?
Допустим из прерывания произошел переход на метку 2. Какой участок программы будет выполнятся после условия If - End If?

0

33

никакой не будет до следующего нажатия кнопки. ну то есть должен крутиться DoLoop. (а, это очередной промежуточный вариант. (кусок с меткой 2 уже был внутри цикла - не помогает). кнопка нажалась - В инкрементировалось до 2, должен состояться переход на метку 1 - но он не происходит. вообще ничего не происходит

0

34

IDok написал(а):

вообще ничего не происходит

Потому что

Пётр написал(а):

Кто же из прерывания выходит через Goto? Как же стек?

Такой переход мало того что портит стек, так еще и прерывания остаются запрещенными.

0

35

гм. то есть правильным будет

Код:
Do
If b=2 then
; тут у нас длинный софтовый ШИМ
end if

if b=1 then
; тут мы включаем порт.3
end if
Loop
End

Button:
Incr B
If b>2 then b=0
return


так?

0

36

Сколько значений у переменной кнопки (В)? Два?
Сделайте ее типа бит, т.е. ее значение будет  0 и 1.
Можно будет использовать оператор TOGGLE. Он инвертирует значение переменной.
Был 0, стало 1...При следующем нажатии - обратный процесс.
Удобно использовать для всякого рода флагов...
И тогда подпрограмма обработки прерывания станет еще короче...

Button:
TOGGLE B
return

0

37

Павел, я пытаюсь логику асилить, а как потом красоту навести - вопрос будущих поколений. вечерком попробую

0

38

pavel1969 написал(а):

Сделайте ее типа бит, т.е. ее значение будет  0 и 1.


битовые операции занимают больше времени, лучше byte.

0

39

друзья, не выходит каменная чаша. как правильно все же организовать управление двумя режимами одной кнопкой?

0

40

сейчас получается следующее:
- медленно работает ШИМ
- нажимаю кнопку, срабатывает прерывание, переменная В увеличивается, идет возврат туда, где прервались
- и пока ШИМ не докрутит до конца, переход по новому значению В не состоится.
пробовал запихать все в две подпрограммы - результата вообще никакого. и почему-то не могу погасить порт командой PORTB.0 = 0

0

41

есть мысль, что по нажатию кнопки надо записывать состояние переменной в память а потом ресетить МК, что бы он перешел в начало программы, и там считывать переменную из памяти. тогда (наверное) все поучится. но чот сложно, сложно...

0

42

IDok написал(а):

как правильно все же организовать управление двумя режимами одной кнопкой?

Длинное нажатие -  изменение режима
Короткое нажатие -  изменение переменной в режиме

0

43

sasha_1973 вот с этим что делать?

IDok написал(а):

сейчас получается следующее:- медленно работает ШИМ- нажимаю кнопку, срабатывает прерывание, переменная В увеличивается, идет возврат туда, где прервались- и пока ШИМ не докрутит до конца, переход по новому значению В не состоится

0

44

http://lightportal.at.ua/publ/chasy/qlo … 19-1-0-122
Здесь есть код однокнопочного управления. С прерыванием, длинным и коротким нажатием.
Рабочий код.

0

45

сделал. получилось некрасиво, но зато работает

0

46

друзья, помогите навести красоту на программу:

$Regfile="attiny85.dat"
$Crystal=8000000
$hwstack=40
$swstack=16
$framesize=32

Config Portb.0 = Output 'R
config portb.1 = output 'G
config portb.4 = output 'B
Config PORTB.3 = output 'фонарик
Config PINB.2 = input 'кнопка
Config Int0 = Falling : On INT0 Button
Config Timer1 = Timer , Prescale = 1 : On Timer1 Pwm_prog : Enable Timer1 : Enable Interrupts : start timer1 : Enable Int0

Dim S As Byte , A as Byte , C(3) as byte , B as Byte , R as Byte

for A=0 to 63
C(1)=lookup(A , TAB_PWM)
waitms 20
next

Do

If R=0 then
PORTB.3 = 0
for A=0 to 63 'тут ШИМ, режим 1 (по умолчанию)
if R=0 then
C(2)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next

for A=63 to 0 step -1 'óìåíüøàåì êðàñíûé
if R= 0 then
C(1)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next
waitms 100
for A=0 to 63 'óâåëè÷èâàåì ñèíèé
if R=0 then
C(3)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next

for A=63 to 0 step -1 'óìåíüøàåì çåëåíûé
if R=0 then
C(2)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next
waitms 100
for A=0 to 63 'óâåëè÷èâàåì êðàñíûé
if R=0 then
C(1)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next

for A=63 to 0 step -1 'óìåíüøàåì ñèíèé
if R=0 then
C(3)=lookup(A , TAB_PWM)
waitms 20
else
goto 1
end if
next
waitms 200
end if

1:
If R=1 Then
C(1) = 0 : C(2) = 0 : C(3) = 0 : PORTB.3 = 1 'тут фонарик (режим2)
End if

loop

end

Pwm_prog:
Incr S

if S=255 then S=0

If S<C(1) Then Set Portb.0 Else Reset Portb.0

If S<C(2) then Set Portb.1 Else Reset Portb.1

If S<C(3) then Set Portb.4 Else Reset Portb.4

Return

Button:
Incr R
waitms 75 'потому что кнопка плохая, вот и 75
if R>1 then R = 0
GIFR = 64
Return

TAB_PWM:
Data 0 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 5 , 6 , 7 , 8 , 10 , 12 , 14 , 15
Data 17 , 20 , 22 , 24 , 27 , 30 , 32 , 35 , 38 , 42 , 45 , 48 , 52 , 56 , 59 , 63
Data 67 , 71 , 76 , 80 , 85 , 89 , 94 , 99 , 104 , 109 , 115 , 120 , 126 , 131 , 137 , 143
Data 149 , 155 , 161 , 168 , 174 , 181 , 188 , 195 , 202 , 209 , 216 , 224 , 231 , 239 , 247 , 255

она работает, но в программе ШИМ приходится постоянно проверять переменную прерывания на значение, иначе до окончания программы переход не состоится. наверняка есть способ лучше и красивее. режимы можно вынести в подпрограммы, но в данном случае это ничего не меняет.

0

47

Жуть.
Ох лучше бы вы просто словами описали алгоритм работы. :) Или табличку нарисовали...

0

48

словами.... "лампа настроения"+белый свет. т.е. ШИМом управляется RGB-диод (режим1, плавное переливание из пустого в порожнее, один цикл примерно 10 секунд), по нажатию кнопки должен отключаться ШИМ и включаться белый диод(режим2). еще раз нажали - все обратно. и так пока кнопка не отвалится. проблема ровно одна - по нажатию копки СРАЗУ перейти в режим 2, а не ждать пока ШИМ отдуплится. вот, все....
(точнее проблема у меня решена - но крайне тупо. в ШИМе в каждом цикле проверяется условие на переход)

0

49

Exit For посмотрите.

0

50

даблин. как выйти из цикла я найду. но их же там 6 штук. что по if-then выходить что по exit-for какая разница?
давайте еще проще скажу, что хочу
Do
Debounce PINB.2,0,Button,Sub 'вместо прерывания INT0
if B=1 then gosub 2 'переход в режим 2
if B=0 then gosub 1 'возврат в режим 1
Loop
End

1:
ШИМ
Return

2:
фонарик
return

Button:
Incr B
If B>1 then B=0
Return

0

51

Подобное уже было в этой теме Attiny 2313 переключение режимов кнопкой
А из цикла лучше выходить по Exit For. И да - 6 раз.

0

52

IDok написал(а):

"лампа настроения"+белый свет. т.е. ШИМом управляется RGB-диод (режим1, плавное переливание из пустого в порожнее, один цикл примерно 10 секунд), по нажатию кнопки должен отключаться ШИМ и включаться белый диод(режим2). еще раз нажали - все обратно. и так пока кнопка не отвалится. проблема ровно одна - по нажатию копки СРАЗУ перейти в режим 2, а не ждать пока ШИМ отдуплится. вот, все....
(точнее проблема у меня решена - но крайне тупо. в ШИМе в каждом цикле проверяется условие на переход)

Ничего не понятно по существу только белый цвет. :D
И то, что RGB управляется ШИМом.
Ладно, видимо у вас там "коммерческая тайна" в идеи.

0

53

max написал(а):

И да - 6 раз

ну вот. а я надеялся на волшебство :( ну 6 раз так 6 раз

RDW написал(а):

Ладно, видимо у вас там "коммерческая тайна" в идеи.

никакой тайны. лампа настроения с переключением в белый свет. в планах еще ждущий режим и выключение по фиксированному таймеру. вот кстати, длинное нажатие так организовать будет хорошо:
Button: 'подпрограмма прерывания кнопки
If PINB.2 = 0 Then 'проверяем, нажата ли кнопка
waitms 600 'ждем
If PINB.2 = 0 Then B=3 'проверяем, если кнопка все еще нажата присваиваем значение 3
Else
incr B                   'если длинное нажатие не подтвердилось - работаем с коротким по плану выходного дня :)
If B>1 then B=0
End If
End If
Return

0

54

а вот безумный вопрос: если я  в самом начале программы напишу Idle (что бы девайс изначально спал, просыпался по короткому нажатия и снова засыпал по длинному) но где-то накосячу - программатор потом разбудит МК для перепрошивки? а то чота боязно мене....

0

55

ну и могу ли я одновременно использовать INT0 для кнопки и Timer0 для прерывания по таймеру?

0

56

IDok написал(а):

одновременно использовать INT0 для кнопки и Timer0 для прерывания

Уже давали ссылку: Attiny 2313 переключение режимов кнопкой

0

57

max
ага, спасибо, узрел :)

0

58

не могу заставить МК спать :(
прерывание кнопки LowLevel, по длинному нажатию хочу что бы в Powersave, а оно никак. само длинное нажатие работает, все лампочки могу по нему погасить, а вот режим сна - нет :(
Config PowerMode  прописал

0


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Attiny 2313 переключение режимов кнопкой