Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
VlTag
7 / 7 / 1
Регистрация: 30.04.2012
Сообщений: 113
1

Данные АЦП в ATmega128 надо отобразить на MT-16S2H по 8-ми линиям. На Assembler

19.12.2018, 03:10. Просмотров 209. Ответов 5

Имеются микроконтроллер ATmega128 и индикатор MT-16S2H. Надо данные с выхода АЦП микроконтроллера отображать на LCD. Программа должна быть на Assembler.
Есть программа, которая проходит компиляцию и в которой работает АЦП и работает индикатор. Но надо данные с выхода АЦП подать на индикатор по 8-ми линиям.
Кто может подсказать как доработать код программы.
)))
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
;
; Сопряжение АЦП и индикатора LCD
 
;=======================================
.device ATmega128
.include    "m128def.inc"
; f= 8 MHz
 
;=========================================
.def temp  = r16
 
.equ        lcd_data    =PORTA
.equ        lcd_upr     =PORTB
.equ        lcd_E       =PB7
.equ        lcd_R_W     =PB5
.equ        lcd_A0      =PB4
.equ        bit_BS      =7
 
;======================================
.CSEG
 
jmp RESET ;    = $000
nop ;INT0addr  = $002   
nop ;INT1addr  = $004   
nop ;INT2addr  = $006   
nop ;INT3addr  = $008   
nop ;INT4addr  = $00a   
nop ;INT5addr  = $00c   
nop ;INT6addr  = $00e   
nop ;INT7addr  = $010    
nop ;OC2addr   = $012    
nop ;OVF2addr  = $014    
nop ;ICP1addr  = $016    
nop ;OC1Aaddr  = $018    
nop ;OC1Baddr  = $01a    
nop ;OVF1addr  = $01c   
nop ;OC0addr   = $01e   
nop ;OVF0addr  = $020 
nop ;URXC0addr = $024   
nop ;UDRE0addr = $026   
nop ;UTXC0addr = $028
.ORG $002A  
jmp ADC_intupt ;ADCCaddr  = $02a
nop ;ERDYaddr  = $02c    
nop ;ACIaddr   = $02e    
nop ;OC1Caddr  = $030    
nop ;ICP3addr  = $032    
nop ;OC3Aaddr  = $034    
nop ;OC3Baddr  = $036    
nop ;OC3Caddr  = $038    
nop ;OVF3addr  = $03A    
nop ;URXC1addr = $03C    
nop ;UDRE1addr = $03E    
nop ;UTXC1addr = $040    
nop ;TWIaddr   = $042    
nop ;SPMRaddr  = $044    
 
;======================================
 
ADC_intupt:
 
   in temp, ADCH     
   out PORTC,temp    
    
   sbi ADCSR, ADSC  
   
   reti              
 
;***** Строки в памяти программ *******
string1:
.db "0123456789ABCDEF",0
string2:
.db "0123456789ABCDEF",0
;*********************************************************
;Подпрограмма посылки команды в индикатор из регистра R16
;*********************************************************
LCD_comm:
    sbi lcd_upr,lcd_E   ;установка в 1 вывода Е индикатора
    out lcd_data,temp   ;вывод команды на шину данных
    rcall   lcd_deley   ;задержка для формирования сигнала Е
    cbi lcd_upr,lcd_E   ;сброс в 0 вывода Е, для защелкивания команды
    ret
;********************************************************************
;Подпрограмма записи данных в индикатор из регистра R16
;********************************************************************
LCD_w_d:
    sbi lcd_upr,lcd_A0  ;установка в 1 вывода А0 индикатора
    sbi lcd_upr,lcd_E   ;установка в 1 вывода Е индикатора
    out lcd_data,temp   ;вывод данных на шину
    rcall   lcd_deley   ;задержка для формирования сигнала Е
    cbi lcd_upr,lcd_E   ;сброс в 0 вывода Е, для защелкивания данных
    cbi lcd_upr,lcd_A0  ;сброс в 0 вывода А0
    ret
;********************************************************************
;Подпрограмма проверки бита занятости индикатора
;********************************************************************
LCD_read_BS:
    clr temp
    out lcd_data-1,temp ;перевлючение шины данных на вход
LCD_read1:
    sbi lcd_upr,lcd_R_W ;установка в 1 вывода R/W индикатора
    sbi lcd_upr,lcd_E   ;установка в 1 вывода Е индикатора
    rcall   lcd_deley   ;задержка для формирования сигнала Е
    cbi lcd_upr,lcd_E   ;сброс в 0 вывода Е
    in  temp,lcd_data-2 ;считывание данных из индикатора
    cbi lcd_upr,lcd_R_W ;сброс в 0 вывода R/W
    sbrc    temp,bit_BS ;проверяем бит готовности индикатора
    rjmp    LCD_read1   ;если занят, начинаем все сначала
    sbr temp,$FF            ;если готов переводим шину данных 
    out lcd_data-1,temp ;на вход и выходим
    ret
;********************************************************************
;Подпрограмма задержки для импульса на выводе E
;********************************************************************
lcd_deley:
    ldi R24,3
lcd_deley1:
    dec R24
    brne    lcd_deley1
    ret
;********************************************************************
;Подпрограмма длинной задержки для инициализации индикатора
;********************************************************************
lcd_deley40:
    clr R24
lcd_deley41:
    dec R24
    brne    lcd_deley41
    ret
;********************************************************************
;Подпрограмма начальной инициализации индикатора
;********************************************************************
LCD_init:
    rcall   lcd_deley40
    ldi temp,0b00110000
    rcall   LCD_comm
    rcall   lcd_deley40
    ldi temp,0b00110000
    rcall   LCD_comm
    rcall   lcd_deley40
    ldi temp,0b00110000
    rcall   LCD_comm
    rcall   lcd_deley40
 
    ldi temp,0b00111010
    rcall   LCD_comm
    rcall   LCD_read_BS
 
    ldi temp,0b00001100
    rcall   LCD_comm
    rcall   LCD_read_BS
 
    ldi temp,0b00000001
    rcall   LCD_comm
    rcall   LCD_read_BS
 
    ldi temp,0b00000110
    rcall   LCD_comm
    rcall   LCD_read_BS
 
    ret
;***** Основная программа**********************************************
RESET:  
    ldi temp,High(RAMEND);инициализация стека
    out SPH,temp            ;
    ldi temp,Low(RAMEND)    ;
    out SPL,temp        ;
    
;----настройка портов для работы с индикатором------------------------- 
    in  temp,lcd_upr-1  ;
    sbr temp,(1<<lcd_E|1<<lcd_R_W|1<<lcd_A0)
    out lcd_upr-1,temp
    cbi lcd_upr,lcd_E
    cbi lcd_upr,lcd_R_W
    cbi lcd_upr,lcd_A0
 
    sbr temp,$FF            ;установка всех линий данных на выход
    out lcd_data-1,temp ;разрешение работы линии порта на выход
 
 
;==== АЦП   АЦП   АЦП   АЦП =============
 
    in temp, DDRE           
    sbr temp, (1<<PE5)  
    out DDRE, temp
 
    sbr temp, $FF       
    out DDRC, temp  
    out PORTC, temp 
 
 
 
    in temp, ADCSR       ; Настройка Регистра АЦП
    sbr temp, (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    out ADCSR, temp 
 
 
    in  temp , ADMUX      ; Выравнивание по левому краю (т.е. Старший байт)  и ещё код для Вход_0
    sbr temp, (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0)                            
    out ADMUX, temp
    
    sei
 
    sbi ADCSR, ADSC
 
; ====== Конец АЦП   Конец АЦП ========
 
;**********************************************************************
 
    rcall   LCD_init    ;инициализация индикатора
 
out_str:
;вывод первой строки на индикатор
    ldi ZH,high(2*string1)  ;загружаем указатель адресом первой строки  
    ldi ZL,low(2*string1)   
out_str1:
    lpm temp,Z+         ;загружаем из памяти символ в регистр R16
    tst temp                ;проверяем, если 0 строка закончилась 
    breq    next_str    ;переход к выводу следующей строки  
    rcall   LCD_w_d     ;выводим символ на индикатор
    rcall   LCD_read_BS ;ожидаем готовности индикатора
    rjmp    out_str1        ;переходим к выводу следующего символа в строке
next_str:
;вывод второй строки на индикатор
    ldi temp,0xC4       ;устанавливаем курсор на вторую строку
    rcall   LCD_comm    ;в четвертое знакоместо
    rcall   LCD_read_BS ;ожидаем готовности индикатора
    ldi ZH,high(2*string2)  ;загружаем указатель адресом первой строки  
    ldi ZL,low(2*string2)   
out_str2:
    lpm temp,Z+         ;загружаем из памяти символ в регистр R16
    tst temp                ;проверяем, если 0 строка закончилась
    breq    _stop       ;переход к очистке индикатора
    rcall   LCD_w_d     ;выводим символ на индикатор
    rcall   LCD_read_BS ;ожидаем готовности индикатора
    jmp out_str2    ;переходим к выводу следующего символа в строке
 
 
_stop:
    jmp  _stop  
 
 
.EXIT
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.12.2018, 03:10
Ответы с готовыми решениями:

АЦП Atmega128
По жизненной необходимости столкнулся с МК. Есть куча непоняток. Прошу Вас помочь мне. Необходимо...

ATMega128. Работа с АЦП
Помогите, пожалуйста, найти информацию по написанию прошивки для контроллера atmega128, при...

ШИМ на atmega128, АЦП MCP3204
Всем привет! Помогите пожалуйста с программой. Есть цель разработать программу, генерирующую...

Внешний АЦП и ATmega128
Здравствуйте! Возникла необходимость подключить несколько внешних АЦП к микроконтроллеру ATmega128...

Секундомер на Assembler от 0 до 999 (AVR Studio, atmega128)
Разработка МП системы, высвечивающей в трех разрядах ЖК-индикатора десятичный секундомер в...

5
pyzhman
785 / 480 / 65
Регистрация: 15.05.2012
Сообщений: 2,718
19.12.2018, 09:27 2
C
1
LCD_init:
Переписать на 8 бит.
0
spvert
213 / 96 / 34
Регистрация: 25.11.2017
Сообщений: 335
Завершенные тесты: 1
19.12.2018, 17:15 3
Цитата Сообщение от pyzhman Посмотреть сообщение
Переписать на 8 бит.
Я могу ошибаться, но оно сейчас на 8 бит работать должно.
Может речь о переходе на 4 бита?

Добавлено через 8 минут
Цитата Сообщение от VlTag Посмотреть сообщение
Но надо данные с выхода АЦП подать на индикатор по 8-ми линиям
Автор, что имелось ввиду?
Подключение индикатора по 8 линиям (так оно сейчас так и запрограммировано, как я вижу)?
Или отображение на индикаторе данных с 8 входных каналов АЦП?
0
VlTag
7 / 7 / 1
Регистрация: 30.04.2012
Сообщений: 113
19.12.2018, 18:10  [ТС] 4
Спасибо! Поясняю. Вообще, это нужно для обучения (т.е. не очень строгая задача).
У меня проблема - из двух отдельных (работающих) исходных программ создать одну общую работающую программу.
Одна исходная программа - демонстрация работы АЦП. Вторая исходная программа - демонстрация работы индикатора.
И всё это на базе одного ATmega128.
Порознь обе упомянутые программы работают в этом моём коде (я добился нормальной компиляции). Но данные с выхода АЦП не подаются на индикатор, который просто выводит фиксированные две строки символов. Пишу ниже более точно.
В строке 65 видно, что данные с выхода АЦП (из регистра ADCH) записываются в порт C (строка 66), а порт C их выводит (строка 194) на элементы одного разряда (выбор разряда в строке 190) 7-сегментного индикатора - просто зажигать эти элементы когда на входе АЦП напряжение изменятся потенциометром от 0 до 5 В (на один и только один вход АЦП подаётся регулируемое напряжение от источника +5 В). Это - про АЦП.
Про индикатор. Он (после инициализации) фиксировано выводит две строки символов (строки 74, 76) и НЕ получает данных от упомянутого регистра ADCH (это - старший байт, но младший байт не буду использовать).
Но что надо? Надо, не переходя на 4 линии для передачи данных, так изменить код, чтобы данные с регистра ADCH стали поступать на вход индикатора.
Уточнение.
Данные на индикатор должны поступать через порт A (см. строка 12), а управляться индикатор должен линиями порта B (см. строки 13, 14, 15, 16).
0
spvert
213 / 96 / 34
Регистрация: 25.11.2017
Сообщений: 335
Завершенные тесты: 1
19.12.2018, 18:30 5
Значит в строке 63 заменить вывод в порт С на укладку во внутреннюю переменную.
А далее перед строков 210 вставляем код преобразования байта внутренней переменной в число (реализация на ассемблере функции itoa() или sprintf(buf, "%d")). Самый дурной вариант - объявить в памяти массив в 256 трехзнаковых строк и выводить строку по индексу определяемому значением внутренней переменной. Менее дурной - формировать строку справа налево из остатков от последовательного деления значения внутренней переменной на 10. Ну и эту строку, терминированную байтом 0, выводить кодом со строки 210.
0
VlTag
7 / 7 / 1
Регистрация: 30.04.2012
Сообщений: 113
19.12.2018, 20:10  [ТС] 6
Огромное СПАСИБО!
0
19.12.2018, 20:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2018, 20:10

И снова LCD MT-16S2H
Добрый день. Прошу помощи. Собрал часы по схеме http://rodyokot.ru/circuit/digital/home/54/ ЖКИ...


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

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

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