list p=16f628a
#include <p16f628a.inc> ;fosc=4mhz
__config _cp_off&_boden_off&_mclre_off&_pwrte_on&_lvp_off&_wdt_off&_intrc_osc_noclkout
cblock 0x20
temp0 ;暂存器0
temp1 ;暂存器1
temp2 ;暂存器2
temp3 ;暂存器3
number ;频率号码
dis_num ;要显示的数
h_send ; 串行数据高8位
m_send ; 中8位
l_send ; 低8位
bits ; 循环计数器
n_l ; 分频比的低8位
a_cbit ; 带有控制位的余数。
endc
;--------------------------------------
#define clk portb,4 ; 时钟线(mb1504-09)
#define ser portb,5 ; 数据线(mb1504-10)
#define le portb,6 ; 锁存线(mb1504-11)
#define r_h 0x2e ;晶振12mhz,参考频率1khz,
#define r_l 0xe0 ;r=d'(2ee0h),这里定义好了,以后好改
;*************************************************
org 0x00
goto start
;********************************************************
org 0x0014
;********************************************************
lookupa_cbit
addwf pcl,f
dt 14h,60h,50h
;--------------------------------------
lookupn_l
addwf pcl,f
dt 01h,6dh,e2h
;********************************************************
start
banksel option_reg ;bank1
movlw b' ;rb上拉,内部时钟,分频器给狗
movwf option_reg ;
;--------------------------------------
movlw b' ;a口4、5输入其余输出
movwf trisa
;--------------------------------------
movlw 00h ;b全输出
movwf trisb
;--------------------------------------
banksel cmcon ; bank0
movlw b' ;比较器关
movwf cmcon
clrf porta
clrf portb
movlw dƆ' ;取0是65.610mhz
;取1是72.560mhz
;取2是80.040mhz
movwf number
call pll
goto $
;*************************************************
pll
movf number,w
call lookupn_l
movwf n_l
movf number,w
call lookupa_cbit
movwf a_cbit
call send_r
call send_na
return
;*************************************************
;参考频率固定,一次性的带控制位发送出去。
;晶振12mhz,参考频率1khz,r=d'(2ee0h)
;选预置的64分频sw=0
;控制位cbit=1
;不直接赋值是为了以后好改r。
;*************************************************
send_r
movlw r_h
movwf h_send
movlw r_l
movwf m_send
;--------------------------------------
bcf status,c ;c清0
rlf m_send,f ;从低位开始左移
rlf h_send,f ;把首、 尾的2位让出来给sw和cbit
bsf m_send,0 ;cbit=1,
;选64预分频,sw=0,数据中此位本身已经是0了,不动
clrf l_send ;不用的l_send清0
;--------------------------------------
movlw dཌ' ;发16位
movwf bits
call start_send ;开始发
nop ;粗略预计共用时340us
return
;*************************************************
;发送分频比n和吞吐脉冲数a(就是余数)
;n的高位是固定的04h,低位查表(偷个懒,不想写计算程序了,反正也不多)
;低位在n_l里
;a_cbit里是对应的余数,已经把cbit含在里面,整好构成8位。
;
;*************************************************
send_na
movf a_cbit,w
movwf l_send
movf n_l,w
movwf m_send
movlw 0x04
movwf h_send
;--------------------------------------
;数据整理,第19位顶到头,要左移5次
bcf status,c ;c清0
movlw dƋ'
movwf bits
loop
rlf l_send,f ;从低位开始左移
rlf m_send,f ;
rlf h_send,f
decfsz bits,f ;结束
goto loop ;否, 继续
;--------------------------------------
movlw dཏ' ;发19位
movwf bits
call start_send ;开始发
nop ;粗略预计共用时400us
return
;*************************************************
;mb1504数据发送子程序;串行输入,高位在前
;高位开始左移发送
;*************************************************
start_send
bcf ser ; 数据线=0
bcf status,c ; c=0
rlf l_send,f ;从低位开始左移
rlf m_send,f ;
rlf h_send,f ;最高位移到c里,输出1bit
btfsc status,c ;查询, 数据为0?
bsf ser ;否
fill 0x0,7 ;延时7us
bsf clk ;时钟线,上升沿clk=1
fill 0x0,7 ;时钟脉冲维持7us
bcf clk ;
;--------------------------------------
decfsz bits,f ;结束(已发送16/19bit)?
goto start_send ;否, 继续
fill 0x0,5 ;
bsf le ;le=1,锁存
fill 0x0,7 ;le脉宽维持7us
bcf le ;
return
;************************************************
end