最近用的是PIC24FJ64GA002, 能做很多好玩的东西。。先把最近算作helloworld的东西放上来好了。
这个code实现的功能是,按一个键,然后里面生成一个随机数,LSB 8bits输出到LED。 分别用汇编和C写了两遍,一共两个Lab。一开始以为比较容易实现的,但是debug的时候遇到了不少问题。
1.BoilerPlate一定要写进去,第二次用c写的时候,和lab partner 搞了好久,只有6个led是对的的,7 8 怎么都不显示,最后发现是没放BP
2.要考虑debounce和release press time,每次按下去之后,应该有code等用户release button
3.多看reference manual,比datasheet好
其实code写的有点不规范,没有做优化,凑合着看怎么实现的就好。。
.equ __P24FJ64GA002,1
.include "p24Fxxxx.inc"
#include "xc.inc"
config __CONFIG2, POSCMOD_EC & I2C1SEL_SEC & IOL1WAY_OFF & OSCIOFNC_ON & FCKSM_CSECME & FNOSC_FRCPLL & SOSCSEL_LPSOSC & WUTSEL_FST & IESO_OFF
config __CONFIG1, WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & COE_ON & BKBUG_ON & GWRP_ON & GCP_ON & JTAGEN_OFF
.bss
c: .space 2 ;a 16 bits variables
x: .space 8 ;a 64 bits variables
a: .space 8 ;a 64 bits variables
stack: .space 32 ;this will be our stack area
.text
.global _main
cleanmem: ;clean memory from 0x900 to 0x91E
push w0
push w2
mov #0x0000, w0
mov #0x900, w2
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
mov W0, [w2++]
pop w2
pop w0
return
memsetup: ;test file!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mov #0x0002, w3
mov #0x0004, w2
mov #0x0003, w1
mov #0x0008, w6
mov #0x0005, w5
mov #0x0009, w4
return
peri_initilize: ;initilize peri setting and variables
push w0 ;protect working register value
push w1
mov #0xffff,w0
mov w0,LATB
mov #0x0003, w0
mov w0, TRISB ;make RB 2-9 are output
mov #0x9fff,w0
mov w0,AD1PCFG ;make PORTB all digital
mov #0xFFFF, w0
mov w0, TRISA ;all RA as input
bset CNPU1, #2 ;turns on internal pull up on CN01 (RA0)
pop w1
pop w0
return
vari_initilize: ;initilize all values x,a,c
push w1 ;protect stack
push w2
push w3
mov #0x0,w3 ;initilize x
mov #0x1,w2
mov #0x330e,w1
mov w1,x
mov w2,x+2
mov w3,x+4
mov #0x5,w3 ;initilize a
mov #0xDEEC,w2
mov #0xE66D,w1
mov w1,a
mov w2,a+2
mov w3,a+4
mov #11,w1 ;initilize c
mov w1,c
pop w3
pop w2
pop w1
return
mult_48_bit: ;w3:w2:w1 * w6:w5:w4,, result=w9:w8 final result will be store in 0x900-0x91E
push w8
push w9
push w7
mov #0x0000, w8
mov #0x0000, w9
mov #0x900, w7
btst.c [w7],#0x1
mul.uu w1, w4, w8 ; we divide mul in three steps
addc w8, [w7], [w7++]
addc w9, [w7], [w7]
mul.uu w4,w2,w8
addc w8, [w7], [w7++]
addc w9, [w7], [w7]
mul.uu w4,w3,w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mov #0x902, w7
mul.uu w1, w5, w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mul.uu w5,w2,w8
addc w8,[w7], [w7++]
addc w9, [w7],[w7]
mul.uu w5,w3,w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mov #0x904, w7
mul.uu w1, w6, w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mul.uu w6,w2,w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mul.uu w6,w3,w8
addc w8,[w7], [w7++]
addc w9,[w7], [w7]
mov #0x900,w0
mov #0xb,w1
add w1,[w0],[w0]
mov #0x900, w7
mov [w7],w8
mov w8, x
mov #0x902, w7
mov [w7],w8
mov w8, x+2
mov #0x904, w7
mov [w7],w8
mov w8, x+4
pop w7
pop w9
pop w8
return
rand48generator:
mov #0x0005, w3 ;a
mov #0xDEEC, w2
mov #0xE66D, w1
mov #0x0000, w6 ;X first
mov #0x0001, w5
mov #0x330E, w4
call mult_48_bit
return
;mov 0x800, w0
;mov #0x000B, w1
;add w1, [w0], [w0]
msec: ;this isn't where we start - it's a subroutine
push w1 ;save WREG1
mov #14000,w1
msloop:
sub #1,w1
bra NZ,msloop
nop
pop w1 ;restore WREG1
return
; msecs does nothing for W0 milliseconds
msecs: ;another subroutine
push w0 ;save WREG0
mssloop:
sub #1,w0
bra N,mssdone
call msec
bra mssloop
mssdone:
pop w0 ;restore WREG0
return
makenextx:
mov x+4,w6
mov x+2,w5
mov x,w4
mov a+4,w3
mov a+2,w2
mov a,w1
call mult_48_bit
return
loop:
call msec ;we wanna check user input with a delay of 40ms to prevent debouncing
btss PORTA,#0
bra loop
call makenextx
call cleanmem
mov x, w0
sl w0,#2,w0
mov w0,PORTB
call msec
bra loop
usefull_loop:
call rand48generator
_main:
call cleanmem
call peri_initilize
call vari_initilize
bra loop
goto $
.end