| 
								MSP430超声波测距     最近有不少网友们在QQ群讨论起关于超声波距离测量的话题,本人听了此话题以后也感到有所触动。在此,本人推荐一个超声波距离测量DIY活动给广大的MSP430爱好者,希望有兴趣的朋友们一起来参与此次DIY活动。本次活动以公开的形式推荐给大家,所有的电路原理图、电路原理、超声波距离测量原理、计算公式、源程序代码都将一一公开给MSP430爱好者,因为这是TI官方一个典型范例,相信大家参与后会有很大的收获。因为此资料是TI官方一个典型范例,同时由利尔达公司将原理注释翻译成中文。所以这是一份较为实用和符合大众的制作资料,希望有兴趣的能一起参加。
 摘要
 本应用报告描述了一种采用MSP430F413 
								超低功耗微控制器的基于超声波的距离测量系统。系统向测量目标发射超声波脉冲然后接收相应的反射波。MSP430 
								集成的模拟比较器A 
								用于检测到达系统的回声。超声波脉冲从系统到目标然后反射回系统所需的时间可以由MSP430精确的测量。假设声波室温下在空气中的速度为1100 
								英尺/秒,MSP430 计算系统与目标间的距离并采用内部集成的LCD 
								驱动器将其显示在一两位的静态液晶显示器上。距离以英寸为单位显示,精度为1 
								英寸本系统能够测量的最小距离是8 
								英寸,因为受到发射器传感器稳定时间;能够测量的最大距离为99英寸,回声的强度取决于反射物的材质形状、和尺寸。地毯之类的吸音材料或者反射面积小于两平方英尺的物体反射能力很弱,这类目标最大测量范围相对较小。如果系统接收到的回声的强度很小以至于比较器A 
								无法检测到就超出了系统的测量范围。这时系统将显示错误信息“E”。
 DIY样品图如下:
 
  
 以下将按几个部分来讲述此次超声波距离测量步骤:
 1-工作原理
 2-电路描述
 3-软件
 Ultrasonic.s43
 设备初始化子
 程序主循环程序
 计算子程序
 BT_ISR 子程序
 显示子程序
 延时子程序
 
 工作原理
 本应用基于声波的反射。声波在其传播的介质中被定义为纵波。当声波受到尺寸大于其波长的目标物阻挡时就会发生反射;反射波称为回声。如果声波在介质中传播的速度是已知的,而且测量到声波从声源到达目标然后返回声源的时间,从声源到目标的距离就可以精确地计算出来。这就是本应用的测量原理。这里声波传播的介质就是空气,采用不可见的超声波。
 假设室温下声波在空气中的传播速度是1100 
								英尺/秒,测量到的声波从声源到达目标然后返回声源的时间是t,秒距离d可以由下列公式计算:
 d=1100 12 t 
								(英寸)
 因为声波经过的距离是声源与目标之间距离的两倍,声源与目标之间的实际距离应该为d/2。
 
 电路描述
 本应用中中用来发射和接收超声波的装置是40KHz 的陶瓷超声波传感器。MSP430 
								采用晶体振荡器产生的一个40KHz 方波信号的12 
								周期脉冲序列驱动发射传感器,接收传感器则接收回声。MSP430 的定时器A被定义为40KHz 
								晶振频率计数器,因此时间测量精度为25 
								微秒,这对本应用来说足够用了。测量的时间基准是非常稳定的因为它由石英晶体振荡器产生。接收传感器收到的回声由运算放大器放大后送到比较器A 
								的输入端。比较器A 检测到其输入端的回声信号后触发定时器A 计数值的捕捉来捕获比较寄存器CCR1 
								的值。捕捉在回声到达系统的瞬间进行。捕获的计数值就是超声波脉冲序列从系统出发到达目标然后返回系统的时间。从系统到目标的距离(用英寸表示)就可由MSP430 
								用测得的时间算出并显示在两位静态液晶显示器上。显示更新后MSP430 马上转入LPM3 
								睡眠模式来降低功耗。基本定时器1 被编程用来每205 毫秒中断MSP430 
								一次。基本定时器1的中断信号唤醒MSP430 并重复测量周期更新显示。
 图1 显示的是本应用的电路原理图。其中MSP430F413 U1 
								是系统的核心部分。参考文献[1]是这个芯片的技术资料。LCD1 
								是一由MSP430F413内部集成的LCD 驱动器驱动的两位低压静态液晶显示器。R03 
								连接到Vss R13 和R23, 悬空将LCD 外围电路设置为静态LCD 
								驱动模式。这里方便的选用了一个40KHz 
								的低频晶振,与本应用中采用的超声波传感器的谐振频率相匹配。R12 
								作为复位线的上拉电阻,内部集成的掉电保护电路可以预防掉电情况。C9 
								位于靠近芯片电源线的位置,提供MSP430 的电源耦合。14 脚的接插件(J1) 提供JTAG 
								接口与MSP430 相连,可使用MSP430FLASH 仿真工具进行在线调试和编程LED1 
								用来指示测量周期。端口引脚P1.5 被定义为输出超声波发射器所需要的40KHz 
								方波ACLK信号。
 传感器的输出驱动电路直接由9V 电池供电并提供18Vpp 驱动超声波发射器。18Vpp 
								是通过一个二进制非门CD4049(U4)桥电路实现的。参考文献[6]是它的技术资料。其中一个非门用来为驱动器的一侧提供180 
								度的相移信号。另一侧由相内信号驱动。这种结构使输出端的电压提高了一倍,为发射传感器提供了18Vpp 
								电压。两个门并联连接以便每一侧能够为传感器提供足够的驱动电流。电容C6 C7 
								阻断了到传感器的直流通路。因为CD4049 工作于9V 而MSP430 工作于Vcc 3.6V。 
								MSP430 和输出驱动器之间的逻辑电平是不匹配的,双极性晶体管Q1 
								就作为这两种逻辑电平之间的转换器。
 运算放大器U3 是TI 公司的高速运算放大器TLV2771 
								。参考文献[5]是它的技术资料。这个放大器具有高增益带宽并在40KHz 
								时提供充分的高增益。运算放大器连接成反相放大器构造。R7、R5 设置增益为55、C5 
								提供高频滚降。R3、R4 
								偏置非反相输入端,为运算放大器的单输入工作提供一个虚拟中间值。放大后的超声波信号在这个虚拟中间值。上下波动传感器RX1 
								的高Q 值提供选择性并丢弃除了40KHz 之外的频率。运算放大器的输出端连接到比较器A 
								的输入端CA0 (即端口引脚P1.6)。 比较器A 的参考电平内部选择为0.5Vcc 
								。当接收到回声时电压高于参考电平从而触发比较器A 的输出CAOUT 。调整R3 
								可以得到需要的灵敏度并优化测量范围。
 MSP430 和超声波信号放大器电路由9V 电池经TI 公司的LDO 芯片TPS77001 
								调制后的3.6V 电压供电。参考文献[4]是它的技术资料。电阻R1和R2 
								调整稳压器输出电压为3.6V。 C1和C2 
								是推荐使用的稳压器的正常工作的供电电容。发射器的驱动电路是由9V 电池直接供电的。开关S1 
								是本应用的电源开关。
 图2 显示的是12 周期的40KHz 脉冲序列的波形轨迹图。我们注意到19.2V 
								的峰峰电压波动。方波顶部的正弦响铃波是由于传感器内部的谐振。
 图3 
								显示的是一个完整测量周期的波形轨迹。轨迹1显示的是发射传感器输出端的12周期的40KHz脉冲序列。轨迹2 
								显示的是接收传感器输出经运算放大器放大后在引脚1上的输出。轨迹上的第一个脉冲序列信号,代表直接从发射器上收到的信号被MSP430忽略。接下去的脉冲序列代表目标反射的回声,被MSP430 
								用于测量。轨迹3 显示的是MSP430 
								测得的时间间隔的宽度。这个宽度代表该脉冲序列从系统到达目标再返回所花的时间,显然它取决于所测量的距离。
 
  图1
 
 
  图2
 
 
  图3
 软件Ultrasonic.s43
 设备初始化子程序
 这个子程序初始化及设置外围电路。首先关闭看门狗电路,采用一个软件延时让低频晶振稳定,将FLL+倍频器设置为64 
								来产生2.56MHz 的MCLK频率。P1.0 
								设置为输出控制LED。未使用的端口引脚设置为输出,端口引脚P1.5 设置为输出带缓冲的40KHz 
								ACLK。频率基本定时器1 启动并设置为提供一个150Hz LCD 频率并每205 
								毫秒中断CPU 开始一次测量周期比较器A 内部参考电平设置为0.5Vcc ,CAPD 
								位设置为关闭比较器输入引脚的输入缓冲。LCD 
								模块打开并在本应用中设置为静态模式驱动两位静态LCD 。LCD 存储器清零,LCD 
								的初始显示为00。基本定时器1 中断和全局中断打开,这样基本定时器1 就可以周期性中断CPU。
 
 主循环程序
 主循环用存储在DIGITS 缓冲区内的值更新液晶显示器然后MSP430置于LPM3 
								睡眠模式。MSP430 维持在睡眠模式直至基本定时器1 中断发生及BT_ISR 
								返回活动模式。这时就开始一个测量周期定时器A 设置为16 位增计数模式,选择ALCK 
								作为其时钟源。CCR1 设置为比较模式,初始值为12 以便在P1.5 引脚上输出12 
								个周期的40KHz 的脉冲序列接下去是一个36ACLK 
								周期的延时,保证输出传感器稳定这是通过设置CCR1为初始值36 的比较模式实现的,在CCR1 
								处于比较等待状态时,MSP430保持LPM0 状态。
 然后系统切换到通过接收传感器接收回声。比较器A 
								被设置为等待回声,在回声到达的瞬间提供一个捕获中断。定时器A 计数值从捕获比较寄存器CCR1 
								中得到。这个值就是超声波序列从发射传感器到达目标然后返回这段距离所需的时间。计数值加上48 
								加以调整,以补偿12 个周期脉冲序列和36 
								个周期发射传感器稳定延时的损失。CCR1调整后的值就是脉冲序列发出时刻到回声到达系统这段时间的准确值。然后,就调用计算子程序计算实际距离单位为英寸并返回结果。如果结果超出范围,回声信号就接收不到,比较器A 
								也不会产生捕获中断。MSP430 保持LPM 状态知道下一个基本定时器1 
								中断将其唤醒,通过检测其CCTL1 控制寄存器中的CAIFG 位来确“E” 
								。程序最终返回到主程序,更新LCD 显示并返回LPM3 睡眠模式。下一个基本定时器1 
								中断将MSP430 唤醒至活动状态重复程序执行过程。
 
 计算子程序
 计算子程序负责本应用中的数学计算。CCR1 中调整后的16 位数值存储为变量Result, 
								这个值就代表超声波序列从系统到目标然后返回系统这段距离所需的时间。因为定时器A 计数间隔为25 
								微秒,对应的时间值为Result25 微秒假设室温下声音的速度为1100 
								英寸/秒,可以看出,从定时器A计数值得到的Result 每6 个值对应于1 英寸的距离。
 为了采用MSP430 现有的整数计算达到要求的精度,16 位的Result 首先乘以100 
								然后除以6。16位*16位的乘法是由子程序Mu100 
								完成的,32位的结果存储在变量htX100_msw 和htX100_lsw 中,然后除以6 
								并将结果保存在变量DIGITS 中DIGITS 中的值是二进制格式的,由hex2bcd 
								子程序将这个二进制值转换成BCD码然后丢弃BCD 码,的最后两个数字来补偿前面所作的与100 
								的乘法。两位的结果值返回到变量DIGITS中。
 
 BT_ISR 子程序
 基本定时器1 中断子程序BT_ISR 对保存在堆栈中的状态寄存器SR 
								中的位进行操作以使MSP430 能够返回活动状态继续执行主循环中LPM3之后的程序代码。
 
 显示子程序
 这个子程序用变量DIGITS 的值更新两位静态LCD 
								显示。静态显示器的段值存储在查寻表LCD_Tab 中。通过将DIGITS中的数字与LCD_Tab 
								查寻表中的位置相关联,LCD 存储器就可以装入所需要的段值。
 
 延时子程序
 这个子程序产生一个16 
								位的软件延时。由于软件减计数的变量处于堆栈的顶部(TOS),寄存器不会受到影响。延时时间到后,子程序返回前堆栈指针(SP)恢复到原始值。
 
 结论
 内部集成的模拟比较器A、带硬件捕获/比较寄存器的16 位定时器A、基本定时器1、 LCD 
								驱动电路简化了超声波测距应用的设计,提供了一种单片系统解决方案。本应用在15 
								英寸距离测量中的平均功耗为1.3 毫安。这包括LDO U2, 运算放大器U3 和CMOS 
								二进制反相器U4 的静态电流,运算放大器自身就由1 毫安的静态电流,电路其他部分的功耗为300 
								微安。LED 工作时需5 毫安,电流MSP430 在LCD 连续工作时需2.1 
								微安的平均电流。这是利用MSP430 的低功耗特性实现的,MSP430 大部分时间处于LPM3 
								睡眠状态,这时用到的CPU 资源仅为5.6%。
 因为声波的速度与温度有关,测量值在非室温下准确度会下降。在本应用中引入一个简单的基于热电阻的温度测量和距离补偿,可以使系统在很大的温度范围内精确测量。如果需要测得的距离和温度数据可以存储在FLASH 
								存储器中。加上额外增益和使用多态LCD 来读出尽可能多的位数也可以增大测量范围。
 
 MSP430源程序(汇编)
 
								;******************************************************************************;    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
 ;******************************************************************************
 
								;******************************************************************************
								BT_ISR                                       ; 
								Basic Timer ISR, CPU returns
 ; 
								to active mode on RETI
 ;******************************************************************************
 bic     #LPM3,0(SP)             ; 
								Clear LPM3 bits on TOS
 reti                            ; 
								on return from interrupt
 
 ;******************************************************************************
 TAX_ISR;     Common ISR for CCR1-4 and overflow
 ;******************************************************************************
 add.w   &TAIV,PC                ; 
								Add TA interrupt offset to PC
 reti                            ; 
								CCR0 - no source
 jmp     CCR1_ISR                ; 
								CCR1
 reti                            ; 
								CCR2
 reti                            ; 
								CCR3
 reti                            ; 
								CCR4
 TA_over      reti                            ; 
								Timer_A overflow
 
 CCR1_ISR     bic.w   #CCIFG,&CCTL1
 bic.w   #LPM0,0(SP)             ; 
								Exit LPM0 on reti
 reti                            ;
 
 ;******************************************************************************
 Display      ;Subroutine to Display values 
								DIGIT1 & DIGIT2
 ;CPU Registers used R15, R14, R13 
								and R12,  not saved
 ;******************************************************************************
 mov.w   #LCDM1,R15              ; 
								R15 points to first LCD location
 mov.b   DIGITS,R14              ; 
								LSD value moved to R14
 OutLCD       mov.b   R14,R13                 ; 
								Copy value in R14 to R13
 rra.b   R13                     ; 
								Right Shift
 rra.b   R13                     ; 
								four times to
 rra.b   R13                     ; 
								swap
 rra.b   R13                     ; 
								nibbles
 and.b   #0Fh,R14                ; 
								low nibble now in R14
 and.b   #0Fh,R13                ; 
								high nibble now in R13
 mov.b   LCD_Tab(R14),R12        ; 
								Low nibble to LCD digit 1
 mov.b   R12,0(R15)              ; 
								Low nibble segments a & b to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								Low nibble segments c & d to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								Low nibble segments e & f to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								Low nibble segments g & h to LCD
 rra.w   R12
 inc.b   R15
 mov.b   LCD_Tab(R13),R12        ; 
								High nibble to LCD digit 2
 mov.b   R12,0(R15)              ; 
								High nibble segments a & b to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								High nibble segments c & d to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								High nibble segments e & f to LCD
 rra.w   R12
 inc.b   R15
 mov.b   R12,0(R15)              ; 
								High nibble segments g & h to LCD
 rra.w   R12
 ret
 ;******************************************************************************
 ;            LCD Type Definition
 ;******************************************************************************
 ;Segments definition
 a            equ     001h
 b            equ     010h
 c            equ     002h
 d            equ     020h
 e            equ     004h
 f            equ     040h
 g            equ     008h
 h            equ     080h
 Blank        equ     000h
 
 LCD_Tab      db      a+b+c+d+e+f             ; 
								Displays "0"
 db      b+c                     ; 
								Displays "1"
 db      a+b+d+e+g               ; 
								Displays "2"
 db      a+b+c+d+g               ; 
								Displays "3"
 db      b+c+f+g                 ; 
								Displays "4"
 db      a+c+d+f+g               ; 
								Displays "5"
 db      a+c+d+e+f+g             ; 
								Displays "6"
 db      a+b+c                   ; 
								Displays "7"
 db      a+b+c+d+e+f+g           ; 
								Displays "8"
 db      a+b+c+d+f+g             ; 
								Displays "9"
 db      a+b+c+e+f+g             ; 
								Displays "A"
 db      Blank                   ; 
								Displays  Blank
 db      a+d+e+f                 ; 
								Displays "C"
 db      b+c+d+e+g               ; 
								Displays "D" d
 db      a+d+e+f+g               ; 
								Displays "E"
 db      a+e+f+g                 ; 
								Displays "F"
 ;******************************************************************************
 Delay;       Software delay
 ;******************************************************************************
 push    #0FFFFh                 ; 
								Delay to TOS
 DL1          dec.w   0(SP)                   ; 
								Decrement TOS
 jnz     DL1                     ; 
								Delay over?
 incd    SP                      ; 
								Clean TOS
 ret                             ; 
								Return from subroutine
 
 ;******************************************************************************
 Math_calc;   calculation subroutine
 ;******************************************************************************
 mov.w   #0h, DIGITS             ; 
								Initialise DIGIT to 0
 cmp.w   #0h, Result             ; 
								Check if Result count=0
 jeq     calc_over               ; 
								Exit if 0
 call    #Mul100                 ; 
								Multiply Result count by 100
 call    #Divide                 ; 
								Divide the result with #06d
 call    #Hex2bcd                ; 
								Convert 16bit binary to BCD number
 ; 
								Result xx.xx
 calc_over    ret                             ; 
								Return from subroutine
 ;******************************************************************************
 Mul100       ;subroutine for multiplying Result 
								with 100d
 ;inputs Result 16bit and constant 
								64h (100d) 16bit
 ;output 32bit htX100_msw & 
								htX100_lsw
 ;******************************************************************************
 mov.w   #100,IROP1              ; 
								Load IROP1 with 100 (multiplier)
 mpyu         clr.w   htX100_lsw              ; 
								Clear buffer for least
 ; 
								significant word
 clr.w   htX100_msw              ; 
								Clear buffer for most
 ; 
								significant word
 macu         clr.w   IROP2M                  ; 
								Clear multiplier high word
 L$002        bit.w   #1,IROP1                ; 
								Test actual bit
 jz      L$01                    ; 
								If 0: do nothing
 add.w   Result,htX100_lsw       ; 
								If 1: Add multiplier to Result
 addc.w  IROP2M,htX100_msw       ;
 L$01         rla.w   Result                  ; 
								Multiplier X 2
 rlc.w   IROP2M                  ;
 rrc.w   IROP1                   ; 
								Next bit to test
 jnz     L$002                   ; 
								If bit in carry : finished
 ret
 ;******************************************************************************
 Divide       ;Subroutine for 32/16 bits division
 ;inputs 32bit htX100_msw & 
								htX100_lsw and #06 16bit, output DIGIT 16bit
 ;******************************************************************************
 clr.w   DIGITS                  ; 
								Clear buffer to hold new Result
 mov.w   #17,IRBT                ; 
								Initialize loop counter
 div1         cmp.w   #06,htX100_msw          ; 
								Compare divisor with dividend high word
 jlo     div2                    ; 
								If less : jump to div2
 sub.w   #06,htX100_msw          ; 
								Subtract 6 from high word
 div2         rlc.w   DIGITS                  ; 
								Rotate result left through carry 1 bit
 jc      div4                    ; 
								If carry set: finished
 dec.w   IRBT                    ; 
								Decrement bit counter
 jz      div3                    ; 
								If counter = 0 : finished
 rla.w   htX100_lsw              ; 
								Dividend X 2
 rlc.w   htX100_msw              ;
 jnc     div1                    ; 
								If carry not set jump to step div1
 sub.w   #06,htX100_msw          ; 
								Subtract 6 from high word
 setc                            ; 
								Set carry
 jmp div2                        ; 
								Jump to repeat
 div3         clrc                            ; 
								Clear carry
 div4         ret                             ; 
								Return from subroutine
 ;******************************************************************************
 Hex2bcd      ;Subroutine for converting 16bit 
								hexadecimal value to BCD value
 ;input in DIGITS 16bit hexadecimal, 
								output in DIGITS 16bit BCD
 ;******************************************************************************
 mov #16,r9                     ; R9 
								no of bits
 clr r8                         ; 
								Clear R8
 clr r7                         ; 
								Clear R7
 L$1          rla DIGITS                     ; 
								Rotate left arithmetic DIGITS
 dadd r7,r7                     ; 
								Add source and carry decimally
 dadd r8,r8                     ; to 
								destination
 dec r9                         ; 
								Decrement bit counter
 jnz L$1                        ; Is 
								16 bits over ?
 mov r7,DIGITS                  ; 
								Result in DIGITS
 ret                            ; 
								Return from subroutine
 ;******************************************************************************
 COMMON  INTVEC                  ; 
								MSP430x41x Interrupt vectors
 ;******************************************************************************
 ORG     BASICTIMER_VECTOR
 BT_VEC       DW      BT_ISR                  ; 
								Basic Timer Vector
 
 ORG     TIMERA1_VECTOR          ; 
								Timer_AX Vector
 TIMA_VEC     DW      TAX_ISR                 ;
 
 ORG     RESET_VECTOR
 RESET_VEC    DW      RESET                   ; 
								POR, ext. Reset, Watchdog
 
 ;******************************************************************************
 END
 我连材料清单都提供给你,问你心动吗?
 -----------------------------------------------------------------------------
 元件编号                                   参数值
 R1                               200K  1 % - 
								0805 SMD
 R2, R3, R4, R6, R7, R12          100K  1 % - 
								0805 SMD
 R5                               1.8K  0.1 % - 
								0805 SMD
 R8, R9, R10                    10K  0.1 % - 
								0805 SMD
 R11                               560  5 % - 
								0805 SMD
 C1, C3, C4, C8, C9                    0.1uF 16V 
								PPS 1210 SMD
 C6, C7                               2 X 0.1uF 
								16V PPS 1210 SMD
 C5                               22pF 50V CERM 
								 0805 SMD
 C2                               4.7F 10V CERM 
								0805 SMD
 Q1                               NPN 三极管 
								MMBT3904
 X1                                40KHz Quartz 
								Crystal
 TX1                                TRANS 40KHz 
								超声波 S类型
 RX1                                RCVR 40KHz 
								超声波 S类型
 LED1                                  RED LED
 S1                                  滑动开关
 9V                                    
								 电池合(PCB装配式)
 9V                                     9V碱性的电池
 U1                                  MSP430F413 
								单片机
 U2                                  TI LDO稳压器 
								TPS77001
 U3                                  TI 运放 
								TLV2771
 U4                                  十六进制反相缓冲器 
								SO-16
 J1                                   14 Pin插座
 LCD1                                  LCD 0.5” 2 
								Digit
 PCB                                    自制PCB
 
								
								本站提供该文中的部分超声测距元件,请电话联系 
								
								超声波传感器   T-40-16/R-40-16    5元/对    防水型:13元/只.   
								批发另仪
 在超声波测距DIY活动开展以来,全国各地网友反应非常热列。吸引了不少电子爱好者前来参与;为了能够让爱好者更方便地参与本次活动,为此为大家准备了此活动的主要元件材料。如果有需要的网友可以通过邮购方式购买。
 另外,此超声波测距项目也可以采用其形号的MSP430单片机来实现。所以用户未必一定要选择MSP430F413,还可以选择其它MSP430型号。
 
 
								
								    |