;******************************************************************************
; MSP430F413 超声波距离测量示范程序
;
;******************************************************************************
; 寄存器定义
;******************************************************************************
#define DIGITS R11
#define Result R10
#define IRBT R9
#define IROP1 R4
#define IROP2L R5
#define IROP2M R6
#define IRACL R7
#define IRACM R8
;******************************************************************************
; 变量定义
;******************************************************************************
RSEG UDATA0
htX100_msw: DS 2 ; 字变量存贮在RAM 200h和201h
htX100_lsw: DS 2 ; 202h和203h
;******************************************************************************
RSEG CSTACK ; 指向开始堆栈段区
DS 0
RSEG CODE ; 指向开始代码段区
RESET mov.w #SFE(CSTACK),SP ; 定义堆栈
call #Init_Device ; MSP430 初始化
mov.w #0,DIGITS ; 初始化DIGITS 为'0'
Mainloop
bic.b #CAON,&CACTL1 ; 比较器A关闭
call #Display ; 显示数据在LCD上
bis.w #LPM3,SR ; 在LPM3模式等待
;************************开始超声波发出和捕获测量******************************
clr.w &CCTL1 ; 不使用CCTL1
clr.w &TACTL ; 不使用timer_A
bis.b #BIT0,&P1OUT ; LED开
SetupTimerA mov.w #TASSEL0+TACLR+MC1,&TACTL
; TACLK = ACLK,16位向上模式
bis.b #BIT5,&P1SEL ; ACLK o/p on P1.5
mov.w #12,&CCR1 ; 12 周期 40KHz爆发
mov.w #CCIE,&CCTL1 ; 比较模式中断
bis.w #LPM0,SR ; 等待CCR1中断
bic.b #BIT5,&P1SEL ; ACLK o/p on P1.5 OFF
TimerCLR bis.w #TACLR,&TACTL
mov.w #36,&CCR1 ; Delay for transducer to settle
mov.w #CCIE,&CCTL1 ; 比较模式中断
bis.w #LPM0,SR ; 等待CCR1中断
bis.b #CAON,&CACTL1 ; 比较器A 开
bic.b #CAIFG,&CACTL1 ; 使能比较器A中断标志
mov.w #CM0+CCIS0+SCS+CAP+CCIE,&CCTL1
; 正边沿, CCIB,Cap,中断
push &TAR ; TOS = TAR 在测量的开始
bis.w #LPM0,SR ; 等待CCR1中断(Echo)
clr.w &CCTL1 ; 不使用CCTL1
bic.b #BIT0,&P1OUT ; LED关闭
bit.b #CAIFG,&CACTL1 ; 检查回声波不接收
jz Next ; '超出范围'条件
mov.w &CCR1,Result ; Result = TAR (CCR1) at EOC
sub.w @SP+,Result ; Result = time taken
add.w #48,Result ; 补偿爆发12个时钟
; 传递时间 + 36个时钟延时
;****************** 测量完成 **************************************************
call #Math_calc ; 调用数学子程序
swpb DIGITS ; Shift left by two digits for /100
jmp Mainloop ; 下一次测量周期
Next mov.w #0beh,DIGITS ; 不回声接收显示'E' 表示错误
jmp Mainloop
;******************************************************************************
Init_Device ; 初始化MSP430x41x
;******************************************************************************
mov.w #WDTPW+WDTHOLD,&WDTCTL ; 停止WDT
bis.b #030h,&FLL_CTL0 ; 开启负载电容器对于XTAL振荡器开始振荡
;
call #Delay ; 延时对于振荡器到稳定为止
mov.b #03fh,&SCFQCTL ; MCLK = 40KhzX64 = 2.56Mhz
call #Delay ; 延时对于FLL到稳定为止
SetupP1 mov.b #000h,&P1OUT ; 清除P1 输出寄存器
bis.b #0bfh,&P1DIR ; 不用的Pin设置为输出
bis.b #040h,&P1SEL ; 比较器A输入功能
SetupP2 mov.b #000h,&P2OUT ; 清除P2输出寄存器
bis.b #0ffh,&P2DIR ; 不用的Pin设置为输出
SetupP6 mov.b #000h,&P6OUT ; 清除P6输出寄存器
bis.b #0ffh,&P6DIR ; 不用的Pin设置为输出
SetupBT mov.b #BTFRFQ0+BTFRFQ1+BTIP2+BTDIV,&BTCTL
; Enable BT with 150Hz LCD freq.
; and 205 milli-second interrupt
SetupCA mov.b #CAPD6,&CAPD ; o/p buffer disable for comp i/p
mov.b #P2CA0,&CACTL2 ; P1.6为比较输入
mov.b #CARSEL+CAREF1+CAON,&CACTL1
; 比较器A开, 0.5Vcc整. 参考
SetupLCD bis.b #LCDON+LCDSON+LCDSG0_7,LCDCTL
; LCD模块开和静态模式
ClearLCD mov #15,R15 ; 15 LCD mem位置清除
mov.b #LCDMEM,R14
Clear1 mov.b #0,0(R14) ; 写零在LCD RAM中
inc.b R14
dec R15 ; 是否清除所有LCD mem?
jnz Clear1 ; 清除更多LCD mem
bis.b #BTIE,&IE2 ; 使能基本定时器中断
eint ; 使能中断
ret
;******************************************************************************