Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
Васил16
0 / 0 / 0
Регистрация: 25.12.2013
Сообщений: 6
1

ATMega16 (ASM). Плавное управление яркостью, генерация звука и отображение на семисегментнике

13.01.2014, 18:17. Просмотров 1534. Ответов 2
Метки нет (Все метки)

Всем привет!!! помогите пож-та. у меня такая проблема. необходимо объединить 3 пункта программы и чтобы работало в протеусе. вот собственно задание само. оно сделано, нужно только их объединить

1) при нажатии на кнопку SB 1 (кратковременно) светодиод набирает яркость от нулевой до максимальной в течении следующих 5 секунд. Плавно гаснет, это происходит до следующего нажатия на кнопку SB 1.
вот программа сама:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
.include "m16def.inc"
rjmp start
.org OVF0addr
rjmp obrab
.org $30
start:
ldi R16, high (ramend)
out SPH, R16
ldi R16,low(ramend)
out SPL, R16
ldi R16,1<<PC1
out PortC,R16
ldi R17,1<<PB3
out DDRB,r17
 
 
ldi R16,(1<<com01)|(1<<wgm00)|(0<<wgm01)|(1<<cs02)
out TCCR0,R16
ldi R16,(1<<TOIE0)
out TIMSK, R16
sei
 
 
 ldi R17,0//dlya sravn a s0
 Ldi R18,1//c
 ldi R20,24    //dlya sravn a s 24
 ldi R21,5//+5
 
 
end:
rjmp end
obrab:
 
inc R19
CP R19,R20
brne konec
ldi R19,0
nop
CPi R18,0
breq otnim5
add R22,R21
nop
out OCR0,r22
nop
CPI R22,255 
brne konec
 
ldi R18,0
rjmp konec
otnim5:
sub R22,R21
nop
out OCR0,r22
CPI R22,0
brne konec
ldi R18,1
konec:
 reti
2) при кратковременном нажатии на кнопку SB 3 при зажатой кнопке SB 2 динамик издаёт звук с частотой 440 Гц. Это продолжается до следующего аналогичного нажатия
3) При кратковременном нажатии SB 1 при зажатой SB 3 на семисегментном индикаторе появляется цифра 1, при последующих кратковременных нажатиях SB 1, если SB 3 по прежнему зажата, цифра на индикаторе увеличивается
Вот объединнёная программа 2 и 3 пункта:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
; Программа Динамик, светодиод, семисегментный индикатор
 
.include "m16def.inc"    ;загружаем файл m16def.inc
 
.def F2HzCount = R22
.def LedCount = R23
.def flags = R20
.def tmp1 = R16           ;задаём символьные значения регистрам
.def count = R17
.def tmp2 = R18
.def tmp3 = R19
.def digit = R21
 
;---Назанчение выводов портов------------------------------------------------
.equ    Zummer = PA0
.equ    SB1 = PC1
.equ    SB2 = PC2         ;сопоставление имён выводов портов,битов и флагов
.equ    SB3 = PC3
.equ    LED = PB4
 
;---Описание битов регистра флагов-------------------------------------------
.equ    fBeep = 0
.equ    fSB3_NotPress = 1
.equ    fSB1_NotPress = 2
.equ    fdivLED = 3
.equ    fLongPress = 4
 
;---Описание констант--------------------------------------------------------
.equ    Fosc = 16000000         ;частота мк
.equ    Fd = 444/2                ;частота динамика 
.equ    Fdiv = 256              ;предделитель частоты
.equ    tms = 300               ;время кратковременного нажатия кнопки SB2
 
;---Формулы вычисления констант----------------------------------------------
.equ    F2Hz = Fd/2             ;
.equ    F888Hz = (Fosc/(2*Fd))/Fdiv - 1  ;вычисляем частоту для динамика  
.equ    k = (tms*Fosc/1000-11)/5
 
;============================================================================
;   Перенаправление векторов
;============================================================================
.org 0                         ;Задание нулевого адреса старта программы
    rjmp start
;----------------------------------------------------------------------------
.org OVF0addr   ;размещаем вектор прерываний
    rjmp    obrab  ;переход на обработчик
 
.org $30
 
;   Обработчик прерываний от таймера
obrab:
    push    tmp1        
    push    tmp2                             ;чтоб не нарушить выполнение основной программы, всё нужное сохраняем в стек
    in      tmp1,SREG
    push    tmp1
 
    sbrs    flags,fBeep ;Проверяем флаг подачи зв. сигнала
    rjmp    offBeeep    ;Если не установлен переходим 
 
    ldi     tmp1,1<<Zummer
    in      tmp2,PORTA          ;инвертирование порта А
    eor     tmp2,tmp1
    out     PORTA,tmp2
 
offBeeep:
    cbi     PORTA,Zummer   ;выключаем динамик
 
End_Int:
    pop     tmp1
    out     SREG,tmp1  ;извлекаем из стека для дальнейшего использования.
    pop     tmp2
    pop     tmp1
 
    reti
 
 
;   Инициализация мк
start:
    cli                                 ;Запрещаем прерывания
 
    ldi tmp1,high(RAMEND)               ;Инициализируем стек
    out SPH,tmp1
    ldi tmp1,low(RAMEND)
    out SPL,tmp1
 
 
    ldi tmp1, 0                         ;Обнуляем порт
    out PORTD,tmp1
 
    ldi tmp1,0b11111111                     ;Все выводы на выход
    out DDRD,tmp1
 
 
 
    ldi tmp1, 1<<SB3 | 1<<SB2 | 1<<SB1  ;Подключаем подтягивающие резисторы
    out PORTC,tmp1
 
    ldi tmp1,0<<SB3 | 0<<SB2 | 0<<SB1   ;Выводы к которым подключены резисторы на вход
    out DDRC,tmp1
 
 
    ldi tmp1,1<<Zummer                  ;Вывод к которым подключен зумер на вход
    out DDRA,tmp1
 
 
    ldi tmp1, (1<<WGM01 | 0<<WGM00 | 0<<COM01 | 1<<COM00 | 1<<CS02 | 0<<CS01 | 0<<CS00) ;Предделитель 256
    out TCCR0,tmp1
 
    ldi tmp1,(1<<TOIE0)                 ;Разрешаем прерывания от переполнения таймера
    out TIMSK,tmp1
 
    ldi tmp1,F888Hz                     ;Записываем расчитанное значение в компаратор таймера
    out OCR0,tmp1
    
    clr flags                           ;Очищаем регистр флагов
 
 
    clr     digit
    rcall   ViewDigit
 
    sei                                 ;Разрешаем прерывания
 
;   Основной цикл
Loop:
    sbic    PINC,SB2                    ;Кнопка SB2 нажата?
    rjmp    NotPress                    ;Нет! Возврат.
 
    sbrc    flags,fLongPress            ;Если длительное нажатие зарегистрированно 
    rjmp    LongPress                   ;Пропускаем проверку 
 
    rcall   Delay                       ;Поверяем на длительное нажатие
 
 
    sbr     flags,1<<fLongPress         ;Да! Устанавливаем признак длительного нажатия
 
LongPress:
    sbis    PINC,SB3                    ;Да! Кнопка SB3 нажата?
    rjmp    mBeep                       ;Да! Переходим к включению/выключению зумера.
    sbr     flags,1<<fSB3_NotPress      ;Нет! Устанавливаем признак отжатия кнопки
 
    rjmp    Loop                        ;Возврат.
 
NotPress:
    cbr     flags,1<<fLongPress         ;Сбрасываем признак длительного нажатия
 
    sbis    PINC,SB1                    ;Кнопка SB1 нажата?
    rjmp    TestSB3                     ;Нет! Возврат.
    cbr     flags,1<<fSB1_NotPress
    rjmp    Loop                        ;Возврат.
 
TestSB3:
    sbic    PINC,SB3                    ;Да! Кнопка SB3 нажата?
    rjmp    Loop                        ;Да! Переходим к включению/выключению зумера.
 
    sbrc    flags,fSB1_NotPress         ;Кнопка была ожата?
    rjmp    Loop                        ;Нет! Возврат.
 
    sbr     flags,1<<fSB1_NotPress      ;Устанавливаем признак отжатия кнопки
    inc     digit                       ;Увиличиваем значение выводимой цифры на 1
    cpi     digit,10                    ;Если значение выводимой цифры не равно 10
    brne    PrintDigit                  ;Переходим к выводу цифры
    clr     digit                       ;Иначе, очищаем значение выводимой цифры
 
PrintDigit:
    rcall   ViewDigit
    rjmp    Loop                        ;Возврат.
 
mBeep:
    sbrs    flags,fSB3_NotPress         ;Кнопка была ожата?
    rjmp    Loop                        ;Нет! Возврат.
 
    cbr     flags,1<<fSB3_NotPress      ;Да! Сбрасывваем признак отжатия кнопки
 
    sbrs    flags,fBeep                 ;Зумер включен?
    rjmp    set_fBeep                   ;Нет! Переходим к его включению
    cbr     flags,1<<fBeep              ;Да! Выключаем зумер
    rjmp    Loop                        ;Возврат.
 
set_fBeep:
    sbr     flags,1<<fBeep              ;Включаем зумер
 
    rjmp    Loop                        ;Возврат.
 
 
;   ПП задержки
Delay:                                  ;Начало подпрограммы задержки
    ldi tmp1, Low(k)                    ;Загрузка значения в регистр tmp1
    ldi tmp2, High(k)                   ;Загрузка значения в регистр tmp2
    ldi tmp3, k/0xFFFF                  ;Загрузка значения в регистр tmp3
 
dloop:                                  ;Цикл задержки
    subi tmp1, 1                        ;Вычитание 1 из регистра tmp1
    sbci tmp2, 0                        ;Вычитание 0 из регистра tmp2 с учетом переноса
    sbci tmp3, 0                        ;Вычитание 0 из регистра tmp3 с учетом переноса
 
    brcc dloop                          ;Если не было переноса вернуться к метке del
 
    ret                                 ;Возврат из подпрограммы
 
;   ПП вывода значения цифры
ViewDigit:
    ldi     ZH,high (TableLCD<<1)       ;Записываем в регистр Z
    ldi     ZL,low (TableLCD<<1)        ;адрес начала таблицы
    clr     tmp1
    add     ZL,digit                    ;Прибавляем к адресу смещение
    adc     ZH,tmp1
    lpm     tmp1,Z                      ;Получаем значение из таблицы с учетом смещения 
    out     PortD,tmp1                  ;Выводим в порт
    ret
 
;   Таблица символов
TableLCD:
    .db 0b00111111, 0b00000110; 0,1
    .db 0b01011011, 0b01001111; 2,3
    .db 0b01100110, 0b01101101; 4,5
    .db 0b01111101, 0b00000111; 6,7
    .db 0b01111111, 0b01101111; 8,9
Буду очень благодарен=)
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.01.2014, 18:17
Ответы с готовыми решениями:

Последовательное плавное управление яркостью светодиодов
Нужно написать программку на Atmega48 в CodevisionAVR Используя PORTD 0 1 2 С начало загорается...

Управление яркостью лампочки
Здравствуйте. Есть контроллер, который через оптопару и симистор будет управлять яркостью обычной...

Управление яркостью экрана
Как можно программно изменить яркость экрана, а также получить текущую?

Управление яркостью галогенной лампы
Здравствуйте, уважаемые форумчане! Прошу прощения, если подобный вопрос уже задавался где-то на...

Управление яркостью подсветки дисплея
Здраствуйте. Интересует такая информация, как из java-приложения можно управлять подсветкой...

2
korsaj
152 / 119 / 11
Регистрация: 16.08.2013
Сообщений: 576
14.01.2014, 09:29 2
Где то я уже это видел, а точнее сказать писал такую прогу, только ШИМа не было..
0
Васил16
0 / 0 / 0
Регистрация: 25.12.2013
Сообщений: 6
14.01.2014, 10:12  [ТС] 3
так и есть. только у меня один пункт отличается про светодиод, соответственно и шим вылезло=). у меня её объединить никак не получается(((
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.01.2014, 10:12

BAM. Управление яркостью светодиодов.
Подкиньте, пожалуйста идей, как лучше сделать. Хочу чтобы параллельно обрабатывалось какое-то...

Управление яркостью лампы через USB
Привет, киберфорум. Пишу на С++, задача стоит такая: лампочка подключена к usb порту компьютера,...

Управление яркостью через триммер и АЦП
Суть задания-используя переменный резистор стенда(подключенный к ацп) управлять яркостью...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru