Libertà vo cercando, ch'è sì cara, come sa chi per lei vita rifiuta

Categoria: assembly

[PIC 16c57] Contatore a due bit controllato

Progetto per PIC16c57 : contatore controllato da due ingressi : Clear e Jump; dispone di due bit d’uscita.

Se il segnale Clear va ad 1, l’uscita deve azzerarsi e ripartire, se va ad 1 Jump, l’uscita deve portarsi a due stati successivi a quello attuale.
Il segnale Clear è predominante su Jump.

list p=16c57
#include
__CONFIG _XT_OSC & _CP_OFF & _WDT_OFF
; portA(0) = Clock; portA(1) = Clear; portA(2)= Jump
; portB(0) = Out1 portB(1) = Out2


RADIX DEC
CK_PREC EQU 0x08
TEMP EQu 0x09 ; cntrolla indirizzo
CONT EQU 0x0A

ORG 0x7ff
goto START

ORG 0x00
START
CLRW
TRIS PORTB
MOVLW b'111'
TRIS PORTA ; 3 ingressi
CLRF CK_PREC
CLRF CONT

LOOP
BTFSC CK_PREC,0
GOTO UPDATE
BTFSS PORTA,0
GOTO UPDATE
GOTO MAIN

UPDATE
MOVF PORTA,CK_PREC
GOTO LOOP

MAIN
BTFSC PORTA,1 ; CLEAR = ?
GOTO CLEAR ; 1
BTFSC PORTA,2 ; JUMP = ?
GOTO JUMP
INCF CONT,F
GOTO CHECK

CLEAR
CLRF CONT
GOTO STAMPA
JUMP
MOVLW 2
ADDWF CONT,F
GOTO CHECK

CHECK
MOVLW 4
SUBWF CONT,W
BTFSC STATUS,Z ; cont=4 ?
GOTO SET_ONE
MOVLW 5
SUBWF CONT,W
BTFSC STATUS,Z
GOTO SET_TWO
STAMPA
MOVF CONT, PORTB
GOTO LOOP

SET_ONE
MOVLW 1
MOVF W, CONT
GOTO STAMPA
SET_TWO
MOVLW 2
MOVF W,CONT
GOTO STAMPA

END
.inc>

[PIC 16c57] Contatore parcheggio

Progetto per PIC16c57 che monitorizza la situazione di un parcheggio privato.
Il sistema ha 4 ingressi a 1 bit ciascuno: UP, Down, Show e Clock e un’uscita a N bit Q.
Ogni volta che entra una macchina Up va ad 1 per un ciclo di clock, ogni volta che ne esce una va ad uno Down. Quando è attivo Show il sistema deve mostrare in uscita il numero di macchine attuali.
Il parcheggio può contenere al massimo 200 macchine e i segnali d’ingresso non possono mai essere contemporaneamente attivi.

; sistema di controllo parcheggio, max 200 macchine
; per ogni Up incrementa, Down decrementa, Show mostra lo stato (Q)
; 4 entrate: UP, Down, Show, Clock
; 1 uscita da 8 bit
; RA<0> : UP ; RA<1> : DOWN ; RA<2> : SHOW; RC<0> : CK
; l'incremento e il decremento devono essere mutuamente escludenti per un ciclo di ck
list p=16c57
#include

__CONFIG _XT_OSC & _CP_OFF & _WDT_OFF

RADIX DEC
UP EQU 0
DOWN EQU 1
SHOW EQU 2
CK EQU 0 ; sulla porta C
MAX EQU 200
CKP EQU 0x08
Q EQU 0x09

ORG 0x7FF
GOTO START

ORG 0x00
START
CLRW
TRIS PORTB ; output
MOVLW b'0111'
TRIS PORTA ; 3 ingressi
CLRF Q
MOVLW 1
TRIS PORTC ; RC<0> = IN DI CK
MOVF PORTC,W
MOVWF CKP ; salva il CK di partenza (bit 3)

MAINLOOP
BTFSC PORTA,SHOW
GOTO STAMPA ; MOSTRA Q SE SHOW=1
BTFSC PORTA,UP
GOTO INC ; INCREMENTA Q SE UP=1
BTFSC PORTA,DOWN
GOTO DEC
GOTO WAIT

WAIT
MOVF PORTC,W ; metto il ciclo attuale nell'accumulatore
SUBWF CKP,0 ; confronta i due valori di clock
BTFSC STATUS,Z
GOTO WAIT ; se uguali attendi
MOVF PORTC,CKP
GOTO MAINLOOP ; se diversi torna a controllare

STAMPA
MOVF Q,PORTB ; mostra q al pubblico
GOTO WAIT

INC
MOVF MAX,W
SUBWF Q,0
BTFSC STATUS,Z
GOTO WAIT ; parcheggio pieno
INCF Q,1
GOTO WAIT
DEC
BTFSS Q,0
GOTO WAIT; parcheggio già vuoto
DECF Q,1
GOTO WAIT

END

[Assembly] saldo conto bancario

Un semplice programmino in Assembly per pd32, che si occupa di
calcolare il saldo in base ad una serie di movimenti positivi o negativi.


SALDO CONTO BANCARIO
tutti i dati sono a 16 bit; il saldo iniziale è memorizzato in 0000 1b00
i movimenti sono memorizzati in locazioni consecutive a 0000 1f00;
l’ultimo movimento è seguito da una posizione di memoria contente 0

Assunzioni arbitrarie

  • realisticamente il saldo parte da zero;
  • ottimisticamente il saldo termina positivamente.

codice C:

#include 
int main(int argc, char *argv[]){
int saldo=0, i=0;
int mov[]={1,-2,-8,10,20,0};
printf ("saldo = %d \n",saldo);
do{
saldo+=mov[i];
i++;
}while( mov[i]!=0);
printf ("saldo finale= %d \n",saldo);
return 0;
}

che diventa:


org 400h

SALDO equ 1b00h ; indirizzo saldo
MOV equ 1f00H

code
; inserisco movimenti
movl #mov,r0 ; ind movimenti in R0
movw #1,(R0)+
movw #-2,(R0)+
movw #-8,(R0)+
movw #10,(R0)+
movw #20,(R0)+
movw #0,(R0)+ ; fine movimenti

movl #mov,r0 ; r0= indirizzo di MOV
xorw r1,r1 ; azzera r1 (inutile in questo caso)

ADD:
movw (r0)+,r2 ; muovi il valore del mov in r2, incrementa ind. mov
cmpw #0,r2 ; (valore all’indirizzo contenuto in r0) – 0
jz FINE ; se = 0 vai a SAVE

addw r2,r1 ; altrimenti somma movimento a saldo
jmp ADD

FINE:
movw r1,SALDO
halt
end

; risultato 15h = 00010101 = 5+16= 21 😉

codice evidenziato grazie a source-highligth

[Assembly] somma delle righe in una matrice

Un semplice programmino in Assembly per pd32, che si occupa di effettuare delle somme per righe in una matrice data. Ecco le specifiche:

La memoria del PD32 contiene a partire dall’indirizzo DATI dodici valori consecutivi in formato Byte che rappresentano le 12 componenti di una matrice 3 Righe X 4 Colonne.
Calcolare la somma di ciascuna riga trasferendo i tre risultati in formato LongWord a partire dall’indirizzo RISUL.

codice C:

#include 
#define RIGHE 3
#define COL 4

int main(int argc, char *argv[]){
int matrice[RIGHE][COL],i,j,k=0;
int RISUL[RIGHE]={0,0,0};

for (i=0; i<RIGHE; i++) // riempio la matrice 0..11
for (j=0; j<COL; j++, k++)
matrice[i][j]=k;

for(i=0; i<RIGHE; i++){
for (j=0; j<COL; j++)
RISUL[i]+=matrice[i][j];
}
printf (" risultato somme: ");
for (i=0; i<RIGHE; i++) printf(" %d ",RISUL[i]);
return 0;
}

che diventa:

; SOMMA ELEMENTI DELLE RIGHE DI UNA MATRICE 3X4, A PARTIRE DALL'IND. DATI
; E SALVA LE SOMME AGLI INDIRIZZI PUNTATI A PARTIRE DA RISUL
org 400h
; definizione variabili
; ogni indirizzo è da 4 B, quindi 12B mi sposteranno di 2 celle
; (12/4-1 esclusa la 1°) arrivando a 558h
dati equ 550h ; 12 Byte
risul equ 500h
righe equ 3
col equ 4

code

; memorizzo elementi celle
movl #dati,R0 ; qui metto l'indirizzo
xorb R1,R1 ; i
xorb R4,R4
; for(i=0; i<12; i++, r0++) r0=i;
FOR:
cmpb #12,R1
jz ESEGUI
movb R1,(R0)+ ; copia r1 in &R0 e avanza di un byte l'indirizzo puntato
addb #1,R1 ; i++
jmp FOR

; calcolo somma
ESEGUI:
; resetto il puntatore a dati
movl #dati,R0
xorb R1,R1 ; sommaRiga
movl #risul,R2 ; R2=&risul somme
xorb r3,r3 ; i
; sommo prima riga

RIGA:
cmpb #col,r3 ; for (int i=0; i
jz SALVA
addb (r0)+,R1
addb #1,r3
jmp RIGA ; end for

SALVA: ; salva la somma e passa a riga successiva
cmpb #righe,r4
jz FINE
movl r1,(r2)+ ; salva r1 e incrementa &R2
xorb r1,r1 ;resetta la somma(R1)
addb #1,r4 ; incrementa numero riga
xorb r3,r3 ; resetta colonna
jmp RIGA

FINE: halt

end

codice evidenziato grazie a source-highligth

Powered by WordPress & Theme by Anders Norén