Dis een proggie wat we voor school hebben geschreven, en is bestemd voor de Atmel 2051 mischien hebbie er wat aan.
;=============================================================================
; file: PWM-DEMO.SRC 06-12-2001
;=============================================================================
; Via de serile poort kunnen de waarden van 3 Puls Width Modulation (PWM)
; kanalen worden opgegeven.
; Commando's: A Weergave van PWM waarde voor kanaal A
; B Idem voor B
; C Idem voor C
; xyA Opgave van PWM waarde voor kanaal A (xy = 0 t/m 100)
; xyB Idem voor B
; xyC Idem voor C
;-----------------------------------------------------------------------------
; EQU LIST van Programma: Symbolische namen voor Constanten en Variabelen
;-----------------------------------------------------------------------------
P_OUT_A equ 90h ;PWM poort voor kanaal A (P1.0)
P_OUT_B equ 91h ;B (P1.1)
P_OUT_C equ 92h ;C (P1.2)
P_OUT_D equ 93h ;D (P1.3)
P_OUT_E equ 94h
P_OUT_F equ 95h
P_OUT_G equ 96h
P_OUT_H equ 97h
TXRDY EQU 0 ; (20.0) Transmitter Ready bit
AfTel_1 equ 30H ; Aftelwaarde 1e PWM sectie
AfTel_2 equ 31H ; Aftelwaarde 2e PWM sectie
AfTel_3 equ 32H ; Aftelwaarde 3e PWM sectie
AfTel_4 equ 33H ; Aftelwaarde 4e PWM sectie
AfTel_5 equ 34H ; Aftelwaarde 5e PWM sectie
AfTel_6 equ 35H ; Aftelwaarde 6e PWM sectie
AfTel_7 equ 36H ; Aftelwaarde 7e PWM sectie
AfTel_8 equ 37H ; Aftelwaarde 8e PWM sectie
PWM_1 equ 40H ; Opgegeven PWM waarde voor Poort A
PWM_2 equ 41H ; Opgegeven PWM waarde voor Poort B
PWM_3 equ 42H ; Opgegeven PWM waarde voor Poort C
PWM_4 equ 43H ; Opgegeven PWM waarde voor Poort D
PWM_5 equ 44H ; Opgegeven PWM waarde voor Poort E
PWM_6 equ 45H ; Opgegeven PWM waarde voor Poort F
PWM_7 equ 46H ; Opgegeven PWM waarde voor Poort G
PWM_8 equ 47H ; Opgegeven PWM waarde voor Poort H
InPo equ 50h ; Input Pointer voor Serial Out buffer
OutPo equ 51h ; Output Pointer voor Serial Out buffer
BufBeg equ 52h ; Buffer Begin
BufEnd equ 5Dh ; Buffer Einde
SI_VAL equ 5Eh ; Opgegeven getal via Serial In
SER_CMDS equ 5Fh ; Commando Nummer voor COMMU verwerking
;-----------------------------------------------------------------------------
; START VAN PROGRAMMA CODE (moet altijd met een ORG instructie beginnen)
;-----------------------------------------------------------------------------
org 0000H ; Start code op adres 0
RESET: ljmp Inita ; Goto Power Up initiatie
;-----------------------------------------------------------------------------
; Interrupt Vectoren op vaste adressen met 0 bytes als opvulling
;-----------------------------------------------------------------------------
V_exti_0: db 32H,0,0,0,0,0,0,0 ; (0003) Externe Interrupt 0
V_timer_0: ljmp Timer_0 ; (000B) Timer / Counter 0 interrupt
db 0,0,0,0,0
V_exti_1: db 32H,0,0,0,0,0,0,0 ; (0013) Externe Interrupt 1
V_timer_1: db 32H,0,0,0,0,0,0,0 ; (001B) Timer / Counter 1 interrupt
;=============================================================================
; Adres: 0023H Serile Poort Interrupt Processing
;=============================================================================
SERIAL: jnb TI,Chk_SIN ; Als er geen Verzend interrupt is, Input Testen
clr TI ; Wis alvast verzend Flag
push Acc ; Test of er nog wat te verzenden valt
push Psw ; Save Acc en Psw
mov a,OutPo
cjne a,InPo,$+7 ; Als IN en OUT niet gelijk zijn, jmp
setb TXRDY ; anders TXRDY bit zetten
sjmp TI_X ; en Exit
push 0 ; Save R0
mov R0,a ; R0 wordt de Output pointer
mov SBUF,@R0 ; Karakter uit Buffer naar serile poort
inc R0 ; OUT pointer verhogen
cjne R0,#BufEnd+1,$+5
mov R0,#BufBeg ; Als pointer > BufEnd, dan wordt het BufBeg
mov OutPo,R0
pop 0 ; Herstel R0
TI_X: pop Psw ; Herstel Psw en Acc
pop Acc
reti
;-----------------------------------------------------------------------------
Chk_SIN: jb RI,SerIn ; Bij Input: Ga deze verwerken
reti ; Anders Exit
SerIn: push Acc ; Save Acc en Psw
push Psw
push Dpl ; Save ook DPTR en B
push Dph
push B
clr RI ; Wis Receiver interrupt
mov a,SBUF ; Lees Inputkarakter
cjne a,#13,Cijfers ; Skip next instructions if not <CR>
mov SI_VAL,#-1 ; Maak getal buffer 'Ongebruikt'
lcall Prompt ; Display Prompt (CR/LF + >)
ljmp Serial_X ; en Exit
Cijfers: cjne a,#'0',$+3
jnc $+5
ljmp Serial_X ; Als karakter < '0', geen reactie (Exit)
cjne a,#'9'+1,$+3
jc $+5
ljmp Upperc ; Als karakter > '9' doorgaan bij UpperCase
; CIJFER VERWERKING
Cy_Verw: mov B,a ; Save Input Karakter
mov a,SI_VAL ; Test Inputgetal op leeg (=FF)
inc a
jnz Max_Test
mov SI_VAL,a ; Bij eerste getal ingave: SI_VAL = 0
sjmp Get_Verw ; Naar getal verwerking
Max_Test: mov a,SI_VAL ; Test SI_VAL
cjne a,#10,$+5
sjmp Max_Tst ; Bij 10 ook low byte testen
jc Get_Verw ; Bij < 10 naar getal verwerking
ljmp Serial_X ; Bij > 10 niets doen (Exit)
Max_Tst: mov a,B ; Test Input karakter
anl a,0Fh ; Ascii -> Waarde
jz Get_Verw ; Als 0: dan doorgaan (100 is maximum)
ljmp Serial_X ; Te Groot: (Pop en Exit)
Get_Verw: mov a,B ; Haal Karakter terug van de Stack
lcall Wr_Buf ; Echo Input Karakter
mov Dpl,B ; Bewaar karakter even in Dpl
mov a,SI_VAL ; SI_VAL = SI_VAL x 10 + Nieuwe Cijfer
mov B,#10
mul AB
mov SI_VAL,a ; SI_VAL kan waarde hebben van 0 t/m 100
mov a,Dpl
anl a,#0FH
add a,SI_VAL
mov SI_VAL,a
ljmp Serial_X ; Exit na Cijferverwerking
Upperc: cjne a,#'a',$+3 ; VERANDER E.V. KLEINE LETTERS IN HOOFDLETTERS
jc Upc_X ; Selecteer karaktergebied ['a'..'z']
cjne a,#'z'+1,$+3
jc $+5
ljmp Serial_X ; Niets doen als karakter > 'z'
anl a,#0DFh ; Van ['a'..'z'] wordt bit 5 verwijderd
Upc_X: cjne a,#'Z'+1,$+3
jc $+5
ljmp Serial_X ; Niets doen als karakter > 'Z' (en < 'a')
mov B,a ; Bewaar Karakter in B
mov SER_CMDS,#0
mov dptr,#Cmd_Kars
Ser_Vgl: inc SER_CMDS ; A=1, B=2, enz
clr a
movc a,@a+dptr
jz Ser_Noc ; Bij 0, geen geldig commando
inc dptr
cjne a,B,Ser_Vgl
mov a,SER_CMDS ; SER_CMDS bevat nu waarden van 1..3
clr REN ;
mov a,B
lcall Wr_Buf ; Display Karakter
sjmp Serial_X
Ser_Noc: mov SER_CMDS,#0 ; Wis SER_CMDS: Geeft geen Aktie bij COMMU
Serial_X: pop B
pop Dph
pop Dpl ; Restore Diversen
pop Psw
pop Acc
reti
Cmd_Kars: db 'ABCDEFGH',0 ; Geldige karakters, afgesloten met 0
;=============================================================================
; Timer 0 Interrupt Afwerking / Tijdbasis: 100 cycli
;=============================================================================
Timer_0: push Acc ; Save Acc + Psw
push Psw
clr c ; 1e PWM aktie op Poort P_OUT_A
mov a,AfTel_1
subb a,PWM_1 ; Te sturen met PWM_1 byte (0..100)
cpl c
mov P_OUT_A,c
jc $+4
add a,#100
mov AfTel_1,a
clr c ; 2e PWM aktie op Poort P_OUT_B
mov a,AfTel_2
subb a,PWM_2 ; Te sturen met PWM_2 byte (0..100)
cpl c
mov P_OUT_B,c
jc $+4
add a,#100
mov AfTel_2,a
clr c ; 3e PWM aktie op Poort P_OUT_C
mov a,AfTel_3
subb a,PWM_3 ; Te sturen met PWM_3 byte (0..100)
cpl c
mov P_OUT_C,c
jc $+4
add a,#100
mov AfTel_3,a
clr c ; 4e PWM aktie op Poort P_OUT_D
mov a,AfTel_4
subb a,PWM_4 ; Te sturen met PWM_4 byte (0..100)
cpl c
mov P_OUT_D,c
jc $+4
add a,#100
mov AfTel_4,a
clr c ; 5e PWM aktie op Poort P_OUT_E
mov a,AfTel_5
subb a,PWM_5 ; Te sturen met PWM_5 byte (0..100)
cpl c
mov P_OUT_E,c
jc $+4
add a,#100
mov AfTel_5,a
clr c ; 6e PWM aktie op Poort P_OUT_F
mov a,AfTel_6
subb a,PWM_6 ; Te sturen met PWM_6 byte (0..100)
cpl c
mov P_OUT_F,c
jc $+4
add a,#100
mov AfTel_6,a
clr c ; 7e PWM aktie op Poort P_OUT_G
mov a,AfTel_7
subb a,PWM_7 ; Te sturen met PWM_7 byte (0..100)
cpl c
mov P_OUT_G,c
jc $+4
add a,#100
mov AfTel_7,a
clr c ; 8e PWM aktie op Poort P_OUT_H
mov a,AfTel_8
subb a,PWM_8 ; Te sturen met PWM_8 byte (0..100)
cpl c
mov P_OUT_H,c
jc $+4
add a,#100
mov AfTel_8,a
pop Psw ; Herstel eerder opgeslagen variabelen
pop Acc
reti ; Exit van Timer interrupt
;-----------------------------------------------------------------------------
; PROMPT schrijft CR/LF > en zet e.v. REN bit weer aan (als deze uit was)
;-----------------------------------------------------------------------------
Prmpt_Msg: db 13,10,'>',0 ; Prompt karakter reeks
PROMPT: setb REN ; e.v. REN bit aanzetten
mov dptr,#Prmpt_Msg ; Zet dptr op begin van reeks
ljmp STRM_BUF ; exit via RET van STRM_BUF
;-----------------------------------------------------------------------------
; Schrijven naar Serial Output Buffer van 16 karakters (incl. 2 Pointers)
;-----------------------------------------------------------------------------
Wr_Buf: push 0 ; Save R0
mov R0,InPo ; Schrijfpointer naar R0
mov @R0,a ; karakter wordt in Buffer geplaatst
inc R0 ; IN pointer verhogen
cjne R0,#BufEnd+1,$+5
mov R0,#BufBeg ; Als pointer > BufEnd, dan wordt het BufBeg
mov InPo,R0
pop 0 ; Herstel R0
jbc TXRDY,$+4
ret
setb TI ; Als TXRDY: RXRDY=0 en TI=1
ret
;-----------------------------------------------------------------------------
; String, afgesloten door 0 karakter, overbrengen naar Output Buffer
;-----------------------------------------------------------------------------
STRM_BUF: clr a ; Door DPTR aangegeven string naar Ser_Buf
movc a,@a+dptr ; Haal karakter op uit Code Segment
jnz $+3
ret ; Bij 0 byte: Exit
lcall Wr_Buf ; Zolang er karakters te verzenden zijn ...
inc dptr
sjmp STRM_BUF ; ... terug naar begin.
;-----------------------------------------------------------------------------
; Initiren van Timer 0 en Seriele Interrupt en Werkvariabelen
;-----------------------------------------------------------------------------
Inita: mov SP,#5Fh ; Stack pointer op 60H (Stk = 32 bytes)
mov TH0,#-100 ; Timer 0 op 100 counts (Auto Reload)
mov TL0,#-100
mov TH1,#-3 ; Geeft baudrate van 9600 bij 11.0592 MHz
mov TL1,#-3
mov TMOD,#00100010b ; Beide Timers in Mode 2
mov TCON,#01010000b ; Beide Timers activeren
mov SCON,#01010000b ; Verzenden en Ontvangen aktief
mov R0,#7Fh ; Wis het totale interne geheugen 00..7Fh
clr a ; =======================================
mov @R0,a ; Alles wat in het begin 0 moet worden
djnz R0,$-1 ; hoeven we niet meer te doen
mov SI_VAL,#-1 ; Waarde -1 betekent LEEG voor SI_VAL
mov InPo,#BufBeg ; Input Pointer
mov OutPo,#BufBeg ; en Output Pointer op begin waarde
setb TXRDY
; Zet aan einde van initiatie het interrupt systeem aan
mov IE,#10010010b ; EA + Seriel en Timer 0 Interrupts
;-----------------------------------------------------------------------------
; Hoofdprogramma (Voert nu alleen COMMU uit)
;-----------------------------------------------------------------------------
Main: lcall COMMU ; Kijk of COMMU nog iets te doen heeft
sjmp Main ; Dat is de enige taak van Main
;-----------------------------------------------------------------------------
; COMMU als verdeler van taken, die binnen het Serial Interrupt zijn opgegeven
;-----------------------------------------------------------------------------
COMMU: clr a ; Acc = 0
xch a,SER_CMDS ; Verwissel Acc met SER_CMDS (SER_CMDS nu 0)
jnz $+3 ; Sla volgende instr. over bij <> 0
ret ; Bij 0 niets doen (terug via 'ret')
mov B,#3
mul AB ; Acc x 3 voor juiste positie 'ljmp Tabel'
mov dptr,#Cmnd_Tbl-3
jmp @a+dptr ; Spring naar Adres: 'DPTR + A'
Cmnd_Tbl: ljmp A_Comnd ; Als SER_CMDS 1 was
ljmp B_Comnd ; Als SER_CMDS 2 was
ljmp C_Comnd ; Als SER_CMDS 3 was
ljmp D_Comnd ; Als SER_CMDS 4 was
ljmp E_Comnd ; Als SER_CMDS 5 was
ljmp F_Comnd ; Als SER_CMDS 6 was
ljmp G_Comnd ; Als SER_CMDS 7 was
ljmp H_Comnd ; Als SER_CMDS 8 was
;-----------------------------------------------------------------------------
; Diverse Opdrachten behorend bij de ingegeven letter
;-----------------------------------------------------------------------------
A_Comnd: mov R0,#PWM_1 ; R0 pointer naar 1e PWM waarde
sjmp ABC_Cmds
B_Comnd: mov R0,#PWM_2 ; R0 pointer naar 2e PWM waarde
sjmp ABC_Cmds
C_Comnd: mov R0,#PWM_3 ; R0 pointer naar 3e PWM waarde
sjmp ABC_Cmds
D_Comnd: mov R0,#PWM_4 ; R0 pointer naar 4e PWM waarde
sjmp ABC_Cmds
E_Comnd: mov R0,#PWM_5 ; R0 pointer naar 5e PWM waarde
sjmp ABC_Cmds
F_Comnd: mov R0,#PWM_6 ; R0 pointer naar 6e PWM waarde
sjmp ABC_Cmds
G_Comnd: mov R0,#PWM_7 ; R0 pointer naar 7e PWM waarde
sjmp ABC_Cmds
H_Comnd: mov R0,#PWM_8 ; R0 pointer naar 8e PWM waarde
;-----------------------------------------------------------------------------
; Gemeenschappelijk voor de drie commando's
;-----------------------------------------------------------------------------
ABC_Cmds: mov a,SI_VAL ; Test of er een getal was ingegeven
inc a
jnz ABC_Chng ; Zo ja: Ga verder bij Change
mov a,#'=' ; Als alleen LETTER, dan waarde weergeven
lcall Wr_Buf
mov a,@R0
mov B,#10 ; Byte weergave in 2 karakters Ascii
div ab
add a,#30h
lcall Wr_Buf
mov a,B
add a,#30h
lcall Wr_Buf
sjmp ABC_X ; Goto Exit via PROMPT
ABC_Chng: mov @R0,SI_VAL ; SI_VAL (0..100) naar @R0 = Waarde Invullen
mov SI_VAL,#-1 ; Maak SI_VAL 'oningevuld'
ABC_X: ljmp PROMPT ; Exit via PROMPT
;-----------------------------------------------------------------------------
END ; PWM-DEMO.SRC
;-----------------------------------------------------------------------------