Stránka 1 z 1

Uprava assembleru - log. 1

Napsal: 02 kvě 2013, 23:04
od Peedros
Ahoj,
chtěl bych poprosit někoho, kdo umí pracovat s Atmel assemblerem, zda by mi nepomohl s následující věcí. Níže je uveden kód assembleru pro řízení zesilovače dálkovým ovládáním (Zdroj: http://svetelektro.com/Forum/dialkove-o ... t2725.html). Potřeboval bych poradit, jak docílit toho, aby po zapnutí on/off byl výstupní bit stdby_bit v log. 1. Ovšem za boha mi to nejde. Poradí někdo zkušenější? Předem díky. Zkoušel jsem úpravu v této části kódu,nicméně jsem nepochodil:
"out ddrb, temp ; nastav konfiguraciu
clr temp
ldi temp,0b00300000
out out_port, temp ; log0 na vsetky vystupy
clr temp
"
.include "tn2313def.inc"
;-----------------------------------------
; definicia konstant a premennych
.equ XTAL = 4000000 ;clock freq in Hz
;-------------------------------
;
;-------------------------------
; pin/port definicia pre tlacidla
.equ keys_port = pind
.equ key1 = 0
.equ key2 = 1
.equ key3 = 2
.equ key4 = 3
.equ key5 = 4
.equ key6 = 5
;.equ infra_port = pind
;.equ input = 6 ; infra vstup
;-------------------------------
; konstanty a premenne pre INFRA
.equ infra_port = pind
.equ INPUT = 6 ;PD6
.equ SYS_ADDR = 8 ;The system address
.def inttemp = R1 ; Temporary variable for ISR
.def ref1 = R2
.def ref2 = R3 ; Reference for timing
.def timerL = R18 ; Timing variable updated every 14 us
.def timerH = R19 ; Timing variable updated every 16 ms
.def system = R20 ; Address data received
.def command = R21 ; Command received
.def bitcnt = R22 ; Counter
;-------------------------------
;definicia vstup/vystup.pinov
.equ out_port = portb ; portb je vystup
.equ on_bit = 0 ;pb0 je vystup na ovladanie zosika, log.1 znamena, ze je zap.
.equ mute_bit = 1 ;pb1
.equ stdby_bit = 2
.equ input_bit1 = 3
.equ input_bit2 = 4
.equ input_bit3 = 5
.equ volume_up_bit= 6
.equ volume_dwn_bit= 7
;---------------------------
.def status_reg = r16 ; pomocny reg pre uchovanie flagu "toggle_flag"
.equ toggle_flag = 7 ; toggle flag od ir,
;
.def temp = r23 ; pomocny register
.def temp_adr = r24
.def key_press = r25 ; cislo klavesy
.def key_temp = r26
;
;-----------------------------------------
; datove premenne
;.dseg
;
;-----------------------------------------
; programovy segment
.cseg
.org 0
rjmp start
.org OVF1addr
rjmp prerus_1
;.org OC0Aaddr
; rjmp prerus_0
;********************************************************************
; prerusenie od c/c 0
.org OVF0addr
TIM0_OVF: in r0,sreg ; Store SREG
inc timerL ; Updated every 64us
inc inttemp
brne TIM0_OVF_exit
inc timerH ; if 256th int inc timer
TIM0_OVF_exit: out sreg,r0 ; Restore SREG
reti
;********************************************************************
;
;-----------------------------------------
start: ldi temp, low(ramend)
out spl, temp ; zsobnik na koniec ram
;
ser temp ; portb vystup
out ddrb, temp ; nastav konfiguraciu
clr temp
out out_port, temp ; log0 na vsetky vystupy
; ldi temp,0b11111110
clr temp
out ddrd, temp ; port D vstup
ser temp
out keys_port, temp ; port D pull/up
;----------------------------------------
ldi temp, 0b00000010 ; timer 1 = clk/8, automat. reset on overflow 65536
out tccr1b, temp
;----------------------------------------
ldi temp,1 ;Timer/Counter 0 clocked at CK
out TCCR0B,temp
ldi temp,((1<<TOIE0) | (1<<TOIE1)) ;Enable Timer0 and Timer1 overflow interrupt
out TIMSK,temp
;----------------------------------------
; nastavenie eeprom
in temp, EECR
andi temp, ~((1<<EEPM1)|(1<<EEPM0)) ; nastav.> erase & write in one operation
out EECR, temp
;----------------------------------
; nastavenie "idle mode"
ldi temp, 0b00100000
out mcucr, temp ; idle mode
; premazeme premenne
clr key_temp
clr key_press ; to same
clr status_reg
; ori status_reg, 1<<input_bit1; maskovanie po resete, akoze zapnuti zos a vstup 1
;out portb, reg ; to same,
sei ; povolime global prerusenie
;------------------------------------
; precitame z EEPROM, kontrolny bajt
rd_ee_c_byte: ldi temp_adr, 0 ; na adrese 0 je kontrolny bajt
rcall EEPROM_read ; precitame hodnotu
cpi temp,0x40 ; test ci je hodnota 40h
breq Eeprom_control_ok ; ano precitali sme spravnu hodnotu, tak skocime
First_power_on: ; prvy krat zapnuty mcu, treba zapisat signatura a data na adresy
ldi temp_adr, 0
ldi temp, 0x40
rcall EEPROM_write ; zapis dat signatury
ldi temp_adr, 1
clr temp
ori temp, 1<<input_bit1 ; prvy vstup
rcall EEPROM_write ; zapis cisla vstupu
rjmp rd_ee_c_byte ; a znova test
Eeprom_control_ok: ; dobre
;
;------------------------------------------
;
;---------------------------------------------------------------------------------
; hlavna slucka
;---------------------------------------------------------------------------------
main: sleep ; idle mod
; in temp, TIMSK
; push temp
; andi temp, ~(1<<TOIE1)
; out TIMSK, temp
rcall detect ;Call RC5 detect routine
cpi system, SYS_ADDR ; ak nastala chyba pri zistovani kodu, tak skonci
brne main_2 ; ak je Z nastavene, tak hodnoty sa rovnaju
;--------------------------------
; test klaves od infra ovladaca
main_1: ; treba ulozit aktualny ir toggle do status registra
bst command, 6 ; aktual.toggle bit do T-bitu
andi command,0x3F ;Remove control bit
brtc act_togg_clr ; skoci ak je aktualne zisteny toggle nulovy
act_togg_set: sbrc status_reg, toggle_flag
rjmp ir_key7 ; rovnake bity
;--------------
; ulozi aktua. toggle do status_reg
bld status_reg, toggle_flag
rjmp ir_key1
;--------------
act_togg_clr: sbrs status_reg, toggle_flag
rjmp ir_key7 ;rovnake bity
;--------------
; ulozi toggle
bld status_reg, toggle_flag
;----------------------
ir_key1: cpi command, 0x0C ; on/off key
brne ir_key2
ldi key_press, 1
rjmp ir_key_end
;----------------------
ir_key2: cpi command, 0x0D ; mute key
brne ir_key3
ldi key_press, 2
rjmp ir_key_end
;----------------------
ir_key3: cpi command, 0x01 ; input_1 key
brne ir_key4
ldi key_press, 3
rjmp ir_key_end
;----------------------
ir_key4: cpi command, 0x02 ; input_2 key
brne ir_key5
ldi key_press, 4
rjmp ir_key_end
;----------------------
ir_key5: cpi command, 0x03 ; input_3 key
brne ir_key6
ldi key_press, 5
rjmp ir_key_end
;----------------------
ir_key6: cpi command, 0x04 ; input_4 key
brne ir_key7
ldi key_press, 6
rjmp ir_key_end
;----------------------///////////////////////////////// nasledujuce prikazy sa opakuju pri drzani tlacidlo ovladaca
ir_key7: cpi command, 0x10 ; volume up key
brne ir_key8
ldi key_press, 7
rjmp ir_key_end
;----------------------
ir_key8: cpi command, 0x11 ; volume down key
brne ir_key_end
ldi key_press, 8
;rjmp main_2
;----------------------
ir_key_end: ; koniec
;-----------------------------------------
; test lokalnej klavesnice
main_2: ; pop temp
; out TIMSK, temp ;zapneme prerusenie od C/C 1
; cpi key_press, 0
; breq main ;ak je 0, tak skoci na zaciatok
sbis out_port, on_bit ; ak je log.1, tak mame zapnuty zos
rjmp key_p8 ; ak je off, tak testuje iba, klavesu on>off
;------------------
key_p1: cpi key_press, 2
brne key_p2
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall mute_on_off
rjmp key_p_end
;------------------
key_p2: cpi key_press, 3
brne key_p3
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_stdby_mod
rjmp key_p_end
;------------------
key_p3: cpi key_press, 4
brne key_p4
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_input_2
rjmp key_p_end
;------------------
key_p4: cpi key_press, 5
brne key_p5
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_input_3
rjmp key_p_end
;------------------
key_p5: cpi key_press, 6
brne key_p6
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_input_4
rjmp key_p_end
;------------------
key_p6: cpi key_press, 7
brne key_p7
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_volume_up
rjmp key_p_end
;------------------
key_p7: cpi key_press, 8
brne key_p8
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall set_volume_down
rjmp key_p_end
;------------------
key_p8: cpi key_press, 1
brne key_clr_end
;--------------
cp key_press, key_temp ;
breq key_p_end ; ano stlacena rovnaka klavesa
mov key_temp, key_press ;update key?temp
;-------------
rcall on_off ; on/off
rjmp key_p_end
;---------------------
key_clr_end: clr key_temp
;clr key_press
sbis out_port, on_bit ; ak je log.1, tak mame zapnuty zos
rjmp main ; ak je off, nemaze ovl.vodice pre motor
cbi out_port, volume_up_bit ; log. nula na vodicoch
cbi out_port, volume_dwn_bit
rjmp main
;----------------------
key_p_end: ;clr key_press ;
rjmp main ;
;---------------------------------------------------------------------------------
; Podprogramy pre ovladanie jednotlivych vstupov
;---------------------------------------------------------------------------------
; ovladanie samotneho zosilnovaca
on_off: ; neguje vystup daneho pinu
sbis out_port, on_bit
rjmp set_on
; vypne zosik
clr_on: clr temp
out out_port, temp ; vsetko vypneme
ret
; zapne zosilovac
set_on: ldi temp_adr, 1 ; precitame cislo vstupu
rcall EEPROM_read
ori temp, 1<<on_bit ; maska pre bit zapnutia zos
out out_port, temp ; a vykoname
ret
;--------------------------------------------------
; ovladanie mute zosilnovaca
mute_on_off: ; neguje vystup daneho pinu
sbis out_port, mute_bit
rjmp set_mute
; zrusi mute
clr_mute: cbi out_port, mute_bit
ret
; dame mute
set_mute: sbi out_port, mute_bit
ret
;--------------------------------------------------
; volume up
set_volume_up: sbi out_port, volume_up_bit
cbi out_port, volume_dwn_bit ;pre istotu
ret
;--------------------------------------------------
; volume down
set_volume_down: sbi out_port, volume_dwn_bit
cbi out_port, volume_up_bit ; pre istotu
ret
;--------------------------------------------------
; nastavi 1 vstup
set_stdby_mod: ; neguje vystup daneho pinu
sbis out_port, stdby_bit
rjmp set_stdby
; zrusi mute
clr_stdby: cbi out_port, stdby_bit
ret
; dame mute
set_stdby: sbi out_port, stdby_bit
ret
; nastavi 2 vstup
set_input_2: sbi out_port, input_bit1 ;prvni vstup
cbi out_port, input_bit2
cbi out_port, input_bit3
rjmp save_input
;ret
; nastavi 3 vstup
set_input_3: sbi out_port, input_bit2 ;druhy vstup
cbi out_port, input_bit1
cbi out_port, input_bit3
rjmp save_input
;ret
; nastavy 4 vstup
set_input_4: sbi out_port, input_bit3 ;treti vstup
cbi out_port, input_bit1
cbi out_port, input_bit2
;ret
;---------------------------
; po vykonani prepnutia vstupu, zapise do EEPROM aktual. cislo vstupu
save_input: ldi temp_adr, 1 ; adresa v eeprom
in temp, out_port ; treba ulozit cislo vstupu
andi temp, ~((1<<on_bit)|(1<<mute_bit)|(1<<volume_up_bit)|(1<<volume_dwn_bit)) ; vybrane bity do log.0
rcall EEPROM_write
ret
;--------------------------------------------------
;---------------------------------------------------------------------------------
;podprogramy pre INFRA
;---------------------------------------------------------------------------------
; zisti prijimanz kod od ovladaca, v "command" je cislo kodu a v "system" je adresa
detect: clr inttemp ; Init Counters
clr timerH
detect1: clr timerL
detect2: cpi timerH,8 ;If line not idle within 131ms
brlo dl1
rjmp fault ;then exit
dl1: cpi timerL,55 ;If line low for 3.5ms
brge start1 ;then wait for start bit
sbis infra_port,INPUT ;If line is
rjmp detect1 ;low – jump to detect1
rjmp detect2 ;high – jump to detect2
start1: cpi timerH,8 ;If no start bit detected
brge fault ;within 130ms then exit
sbic infra_port,INPUT ;Wait for start bit
rjmp start1
clr timerL ;Measure length of start bit
start2: cpi timerL,17 ;If startbit longer than 1.1ms,
brge fault ;exit
sbis infra_port,INPUT
rjmp start2 ;Positive edge of 1st start bit
mov temp,timerL ;timer is 1/2 bit time
clr timerL
mov ref1,temp
lsr ref1
mov ref2,ref1
add ref1,temp ;ref1 = 3/4 bit time
lsl temp
add ref2,temp ;ref2 = 5/4 bit time
start3: cp timerL,ref1 ;If high period St2 > 3/4 bit time
brge fault ;exit
sbic infra_port,INPUT ;Wait for falling edge start bit 2
rjmp start3
clr timerL
ldi bitcnt,12 ;Receive 12 bits
clr command
clr system
sample: cp timerL,ref1 ;Sample INPUT at 1/4 bit time
brlo sample
sbic infra_port,INPUT
rjmp bit_is_a_1 ;Jump if line high
bit_is_a_0: clc ;Store a '0'
rol command
rol system
;Synchronize timing
bit_is_a_0a: cp timerL,ref2 ;If no edge within 3/4 bit time
brge fault ;exit
sbis infra_port,INPUT ;Wait for rising edge
rjmp bit_is_a_0a ;in the middle of the bit
clr timerL
rjmp nextbit
bit_is_a_1: sec ;Store a ’1’
rol command
rol system
;Synchronize timing
bit_is_a_1a: cp timerL,ref2 ;If no edge within 3/4 bit time
brge fault ;exit
sbic infra_port,INPUT ;Wait for falling edge
rjmp bit_is_a_1a ;in the middle of the bit
clr timerL
nextbit: dec bitcnt ;If bitcnt > 0
brne sample ;get next bit
;All bits sucessfully received!
mov temp,command ;Place system bits in "system"
rol temp
rol system
rol temp
rol system
bst system,5 ;Move toggle bit
bld command,6 ;to "command"
;Clear remaining bits
andi command,0b01111111
andi system,0x1F
ret ; a von z rutiny
;---------------------------------
; chyba
fault: ser command ;Both "command" and "system"
ser system ;0xFF indicates failure
ret
;---------------------------------------------------
;Podprogramy pre ovladanie EEPROM
;---------------------------------------------------
; v TEMP je byte na ZAPIS/CITANIE, adresa je v temp_adr
;zapis DO pamate
EEPROM_write: ; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_write
; Set up address in address register
out EEAR, temp_adr
; Write data to data register
out EEDR,temp
; Write logical one to EEMWE
sbi EECR,EEMWE
; Start eeprom write by setting EEWE
sbi EECR,EEWE
ret
;----------------------------
; citanie Z pamate
EEPROM_read: ; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_read
; Set up address in address register
out EEAR, temp_adr
; Start eeprom read by writing EERE
sbi EECR,EERE
wait_read: sbic EECR,EERE
rjmp wait_read
; Read data from data register
in temp,EEDR
ret
;---------------------------------------------------
; obsluha prerusenia od c\c1 (obsluha klavesnice)
;---------------------------------------------------
prerus_1: in r0,sreg ; Store SREG
; push temp
; test tlacitok
sbis keys_port, key1 ; ak je bit jedna tak skoci
rjmp key_1
sbis keys_port, key2
rjmp key_2
sbis keys_port, key3
rjmp key_3
sbis keys_port, key4
rjmp key_4
sbis keys_port, key5
rjmp key_5
sbis keys_port, key6
rjmp key_6
; ziadna klavesa stlacena
clr key_press ; indikacia, ze prebehol test klaves bez stlacenej klavesy
prerus_end: ;pop temp
out sreg,r0 ; Restore SREG
reti ; a von z obsluhy prerusenia
;---------------------------------
key_1: ; tlacidlo 1
ldi key_press, 1
rjmp prerus_end
;----------------------
key_2: ; tlacidlo 2
ldi key_press, 2
rjmp prerus_end
;----------------------
key_3: ; tlacidlo 3
ldi key_press, 3
rjmp prerus_end
;----------------------
key_4: ; tlacidlo 4
ldi key_press, 4
rjmp prerus_end
;----------------------
key_5: ; tlacidlo 5
ldi key_press, 5
rjmp prerus_end
;----------------------
key_6: ; tlacidlo 6
ldi key_press, 6
rjmp prerus_end
;----------------------
;-----------------------------
;
;

Napsal: 02 kvě 2013, 23:16
od Peedros
dle mě by stačilo vložit sem příkaz na nastavení log. jedničky pro ten stdby_bit.


set_on: ldi temp_adr, 1 ; precitame cislo vstupu
rcall EEPROM_read
ori temp, 1<<on_bit ; maska pre bit zapnutia zos
out out_port, temp ; a vykoname
ret



Tudíž sbi out_port, stdby_bit ? Jenže stejně mám smůlu :/ Nejsem v tom kovanej :)

Napsal: 03 kvě 2013, 07:16
od AB1
clr temp
ldi temp,0b00300000
out out_port, temp ; log0 na vsetky vystupy
Byl jsi skoro na dobré cestě, ale máš nějakou divnou binární soustavu.

Místo řádků

Kód: Vybrat vše

clr temp
out out_port, temp ; log0 na vsetky vystupy
dej

Kód: Vybrat vše

ldi temp, 0b00000100
out out_port, temp ; log0 na vsetky vystupy kromě portb.2


PS:
Bity v binárním čísle se počítají zprava.
Úplně vpravo je bit0.
A v binárním čísle jsou jenom jedničky a nuly.

Napsal: 03 kvě 2013, 07:57
od Peedros
AB1 diky. Ta trojka v bin. zapisu mi dosla a pak jsem to v kodu opravil, nicmene to,ze se to bere zprava ne :D Blbec no:D Jsem si rikal,ze to bude nejaka hovadina :D Jeste jednou diky,vyzkousim a dam vedet