пока один вопрос:
зачем в исходник вставлять inc-файл? есть же директива .include.
Вот, откопал и на ASM, хотя на нём уже давно не пишу. ПочтиMTF писал(а):Инфы в инете много , но через int как делать инфы особо нет , либо на Си, разве что товарищь Ридико полуописал как он делал через int на at89с2051
Код: Выделить всё
;блок для вывода через 74LS164
ldi r17,8 ;
74LS: cbi PORTD,5 ;
sbrc r16,7 ;
sbi PORTD,PD5 ;
lsl r16 ;
sbi PORTD,6 ;
cbi PORTD,6 ;
dec r17 ;
brne 74LS ;
1. Длительность свечения 1 разряда должна быть не более 1/25 сек, отсюда и высчитывай частоту.MTF писал(а): возникло несколько вопросов:
какую частоту таймера лучше выбрать для 2 разрядов ???
еще я так понимаю мне надо изобрести некий преобразователь числа в семисегментный код для
74LS164 ???
Основная моя проблема не дошло как работать с двумя разрядами , для загрузки например числа 65 , если не трудно помогите разобратся
Код: Выделить всё
.equ OutPort = PORTB
.def tmp = r16
.def tmp1 = r17 ;
T0_OVF:
.....
.....
;================ INDICATION =====
;------------------- OFF IND ------------------------------
in tmp , portb ;чтение portB
ori tmp , 0x03 ;в 1 pb0 , pb1
out portb, tmp ;погасить индикатор
; вопрос так можно делать или не надо ????
sbi OutPort, (0<<OutPin , 1<<OutPin )
;здесь надо определять что должен показывать индикатор и какой должен светится ???
;в tmp код цифры для 74LS164
;------------- Вывод в 74LS164 --------------------
ldi tmp1 , 8 ;8 bits
LS164:
cbi portd , 5 ;DATA "0" => 74LS164
sbrc tmp , 7 ;если bit 7=0 выход
sbi portd , 5 ;DATA "1" => 74LS164
lsl tmp ;Shift left r16
sbi portd , 6 ;CLOCK strobe for 74LS164
cbi portd, 6 ;CLOCK strobe for 74LS164
dec tmp1 ;dec
brne LS164 ;если не 0 то LS164
;------------------- ON IND ------------------------------
in tmp , portb ;
...............
????????????????????????
...............
out portb , tmp ;ON IND
Как вариант во флэш:MTF писал(а):Если не трудно покажите пожалуйста как мне загрузить во flash либо в EEPROM коды семисегментника , и как потом их выбирать и позиционировать ????
Код: Выделить всё
.equ OutPort = PORTB
.equ dg1 =pb1
.equ dg2 =pb0
.def tmp = r16
.def tmp1 = r17 ;
;****************
.equ pin_dat =pd5 ;*** оч.рекомендую делать именно так
.equ pin_clk =pd6
.def n =<какой нибудь регистр>
.def flags =r19 ;*** определяем регистр флагов
.equ tind =7 ;*** и назначаем флаг индикации
; main prog
.....
.....
call display ;***вызов процедуры индикации
.....
.....
jmp <начало>
;=================
T0_OVF:
.....
.....
sbr flags,tind ;*** установить бит, время индикации истекло
reti
;================ INDICATION =====
display:
;здесь надо определять что должен показывать индикатор и какой должен светится ???
;в tmp код цифры для 74LS164
;*** для этого нужно организовать еще один цикл
ldi n,2 ;*** у нас 2 разряда
clr r0 ;*** пригодится для сложения
next_digit:
; вопрос так можно делать или не надо ????
;sbi OutPort, (0<<OutPin , 1<<OutPin ) ;*** вообще не понял для чего ЭТО
;*** вот здесь в tmp надо зарузить значение
;*** не знаю как у тебя организовано хранение выводимых значений
;*** поэтому оставляю на твое усмотрение
;*** вариант если коды размещены во flash-памяти
ldi ZL,low(tabl_code*2)
ldi ZH,high(tabl_code*2) ;*** теперь Z указывает на начало таблицы с кодами индикатора
;*** находим код нужного нам символа
add ZL, tmp
adc ZH,r0 ;*** теперь Z указывает на нужный символ
;*** и загружаем семисегментный код в tmp
lpm tmp,Z
;------------- Вывод в 74LS164 --------------------
ldi tmp1 , 8 ;8 bits
LS164:
;*** с чего ты взял что выводишь здесь свои данные?
; cbi portd , 5 ;DATA "0" => 74LS164
; sbrc tmp , 7 ;если bit 7=0 выход
; sbi portd , 5 ;DATA "1" => 74LS164
; lsl tmp ;Shift left r16
;****
cbi portd,pin_dat ;*** сбрасываем пин в 0
lsl tmp ;***выдавливаем бит в СY
brcc ls164_0
sbi portd,pin_dat ;*** устанавливаем в 1 если CY=1
ls164_0:
sbi portd , pin_clk ;CLOCK strobe for 74LS164
cbi portd, pin_clk ;CLOCK strobe for 74LS164
dec tmp1 ;dec
brne LS164 ;если не 0 то LS164
;*** в регистре нужный код , приступаем к индикации
;*** сбрасываем флаг индикации
cbi flags,tind
cpi n,2
breq digit2
cbi OutPort, dg1 ;*** включаем разряд1
ls_tout1: sbis flags,tind ;*** и ждем переполнения счетчика
rjmp ls_tout1
rjmp ls_next
digit2: cbi OutPort, dg2 ;*** включаем разряд2
ls_tout2: sbis flags,tind ;*** и ждем переполнения счетчика
rjmp ls_tout2
ls_next:
;------------------- OFF IND ------------------------------
in tmp , portb ;чтение portB ;*** здесь все норм.
ori tmp , 0x03 ;в 1 pb0 , pb1
out portb, tmp ;погасить индикатор
dec n
brne next_digit
ret ;*** выход
;=================
.cseg
tabl_code:
.db <код нуля>
.db <код 1>
...............
; и т.д. максимум 256 кодовКод: Выделить всё
.equ pin_dat =pd5 ;*** оч.рекомендую делать именно такКод: Выделить всё
#define RS portX,NКод: Выделить всё
sbi RS
cbi RSДело вкуса. Если препроцессор не приделан к ассемблеру "чтобы было" с минимальным функционалом, а нормально поддерживает операцию склейки ## и делает разбор "ну точно как С-шный" (ну или именно С-шный и используется, как в IAR или avr-gcc/WinAVR), то, на мой вкус, так лучше:Pooher писал(а):[А ещё лучше вот так:Тогда можно обращаться так:Код: Выделить всё
#define RS portX,NКод: Выделить всё
sbi RS cbi RS
Код: Выделить всё
#define A_PORT(p,b) PORT##p,b
#define PORT(pb) A_PORT(pb)
#define A_PIN(p,b) PIN##p,b
#define PIN(pb) A_PIN(pb)
#define A_DDR(p,b) DDR##p,b
#define DDR(pb) A_DDR(pb)
#define A_MASK(p,b) (1<<b)
#define MASK(pb) A_MASK(pb)
// ну это так, для полнты комплекта, используется редко
#define A_BIT(p,b) (b)
#define BIT(pb) A_BIT(pb)Код: Выделить всё
#define KEY B,0
#define ALARM B,1
#define LED B,2
#define SCL B,4
; можем и маску собрать для одного обращения к DDR
outi DDRB, MASK(ALARM) | MASK(LED)
sbi DDR(SCL) ; и обратиться к биту DDR
sbic PIN(KEY)
sbi PORT(LED)
sbi PIN(ALARM) ; а это на новых кристаллх - инверсия ноги
Код: Выделить всё
#define SDA_DDR DDRB,5
#define SDA_PORT PORTB,5
#define SDA_PIN PINB,5
Код: Выделить всё
.cseg
tabl_code:
.db 0xDB ; 0
.db 0x48 ; 1
.db 0xE3 ; 2
db 0xEA ; 3
display:
...................
...................
ldi ZL , low(tabl_code*2)
ldi ZH , high(tabl_code*2) ;*** теперь Z указывает на начало таблицы с кодами индикатора
;*** находим код нужного нам символа
add ZL , tmp
adc ZH , r0 ;*** теперь Z указывает на нужный символ
;*** и загружаем семисегментный код в tmp
lpm tmp , Z
;---------- вывод в 74LS164------------------
.........
.........
Код: Выделить всё
add ZL , tmp
Код: Выделить всё
.cseg
tabl_code:
.db 0xDB ; 0
.db 0x48 ; 1
.db 0xE3 ; 2
...........
...........
.db 0x48 , 0xFB ; 18
Естессно, числа, как правило, выводятся по одному десятичному разряду, напр. "1" в десятках и "8" в единицах. Для преобразования 8-битного числа в два (три) (четырёхбитных) надо его преобразовать. Пример есть в аппноте AVR204 (вроде) - bin_to_BCD или как-то так. Тогда в памяти надо хранить коды всего 10 цифрMTF писал(а):тогда надо как то смещать что ли , для показа двух разных чисел , или есть какой то другой метод , а то все 99 чисел надо писать в массив !!!
мне так кажется надо как то расклдывать число 18 например на 1 и 8 и как то по одному числу выводить ????
Правильно мыслишьMTF писал(а): мне так кажется надо как то расклдывать число 18 например на 1 и 8 и как то по одному числу выводить ????
Код: Выделить всё
; в tmp число 18
; гасим одну тетраду, ну скажем младшую
andi tmp,0xF0
swap tmp ; теперь в tmp получилась 1
Код: Выделить всё
ldi tmp , 18
andi tmp,0x0F ; гасим старшую
swap tmp ; в tmp почему то не получилось 8
MTF писал(а):GP1
экперементировал в avrstudio
может не так что делаю ???Код: Выделить всё
ldi tmp , 18 andi tmp,0x0F ; гасим старшую swap tmp ; в tmp почему то не получилось 8