DSP56F80x系列DSP介绍
DSP56F80x系列DSP(以下简称 '80x)包括DSP56F801、3、5、7,2003年初,Motorola在该系列中又新增了一个片种DSP56F802。'80x集成了 Motorola的16位定点DSP微控制器内核DSP56800,而DSP56800内核的指令集面向DSP和控制领域的应用均进行了优化。 DSP56800内核为双哈佛结构,共有3个并行的执行单元,分别为算逻运算单元(ALU)、地址产生单元(AGU)和程序控制单元(PCU)。每个指令周期这3个执行单元共可完成6次操作。在一个指令周期内,DSP内核即可执行一次16位×16位的乘法累加操作(MAC)。另外,DSP内核还提供了硬件循环操作。芯片内核最高可工作于80MHz,在此工作频率下,指令执行速度可达40MIPS。内核的这种高效结构和高速运算能力,为 '80x系列DSP在运算复杂、实时性较强的控制领域中的应用提供了保证。
源代码
;50%占空比输出:FP_PULSE_OUT
;输入量:FP_PULSE(5k_10k)
;输出量:
;说明:T=F_MAX/(FP_PULSE*nowf*1000) 我们选1分频,T(s)=N*25(ns)*2,后面*2是因为我们输出的是50%占空比
;N即为我们要设的预计记数值
;N=F_MAX*1,000,000,000/(nowf*FP_PULSE*1000*50)=F_MAX*20000/(nowf*FP_PULSE)
;我们对<3Hz的频率不于考虑。也就是说N<=#$65b9aa(合理范围)N范围#$7d0-#$65b9aa
;我们对于3Hz以下的频率不考虑,也就是不输出,对应的最大0.24Hz以下不发波!(0.24)/40000=3/5k
;我们采用自动分频发送
;==================================
FP_PULSE_OUT:
;**************************************
move x:nowf,x0
cmp #0,x0
jeq FP_CLOSE
cmp #10,x0
jcs jump
;--nowf当前频率,修改发波频率,我们把数据都转化成末尾为0.04发送,显示比较稳定。除了#1.20数据比较特殊显示抖动厉害,过滤掉
move x:nowf,a0
move #0,a1
;分不同情况来四舍五入数据,100上限以上的我们0.2精度,100上限以下的0.1精度
move x:F_MAX,x0
cmp #10001,x0
jcs s_max
move #20,x0
jmp j_n
s_max:
move #10,x0
j_n:
asl a
bfclr #$1,sr
rep #16
div x0,a
move a0,y1
add x0,a
; asr a ;我们不调整了,直接判断四舍五入
move a1,y0
cmp y0,x0
jcc small_ok_f
add #1,y1
small_ok_f:
mpysu x0,y1,a
asr a ;得到最终结果
move a0,y0
cmp #130,y0
jcs go_go
move x0,b ;加末尾0.05或者0.02,反正是x0的一半
asr b
sub #2,b
move b1,b0
move #0,b1
add b,a
jmp go_go
jump:
cmp #5,x0
jcs too_small
move #10,x0
jmp go_go
too_small:
jmp FP_CLOSE
go_go:
move a0,b0
;**************************************
move x:F_MAX,y0 ;我们先做上限频率*#20000(可以提高精度)这里我们应该乘#40000是因为采集的是一个周期的时间,放到最后调整
move #20000,x0
mpysu x0,y0,a
asr a
move a0,y0
move a1,a0
move b0,x0
;--准备调用div_32by16
jsr div_32by16
move a0,b1
move y0,b0 ;将结果放入b中最大值#$2faf0800
move x:FP_PULSE,y0
move #1,y1 ;这里可以调整分频率,1为1分频
mpysu y0,y1,a
asr a ;得到的结果肯定a1=0,最大值10
;--准备调用div_32by16
move a0,x0
move b1,a0
move b0,y0
jsr div_32by16
move a0,a1
move y0,a0 ;得到的结果最大为#$9896800,结果保存在a中
;--判断如果小于5Hz则可以不考虑,也就是不发波
move #$65,x0
move a1,y1
cmp x0,y1
jeq goon_cmp ;相等继续比较
jcc FP_CLOSE ;可以丢弃
jmp n_ok ;开始分频发送的比较
goon_cmp:
move #$b9ab,x0
move a0,y0
cmp x0,y0
jcc FP_CLOSE ;可以丢弃
n_ok:
;--我们开始用自动分频发送,我们移位该数值,知道高16位为0为止,这时对应的移位次数就可以左移9位,然后用bfset来配置x:TMRD3_CTRL
move #0,a2 ;是为了用算术右移而清的0
move #0,y0 ;用来存放移动次数的
just_on:
move a1,y1
cmp #0,y1
jeq out_start
asr a
add #1,y0
jmp just_on
out_start:
move #0,b2
move #0,b0
move y0,b1
rep #9
asl b
move b,x:TMRD3_CTRL ;我们把得到的分频置到控制器里
move a0,x:TMRD3_CMP1 ;用做加记数
bfset #$3023,x:TMRD3_CTRL ;我们选的就是1分频,作为基频
move #$1,x:TMRD3_SCR
jmp FP_PULSE_OUT_END
FP_CLOSE:
bfclr #$1,x:TMRD3_SCR ;如果nowf为0,则不让发送方波
FP_PULSE_OUT_END:
rts