您的当前位置:首页正文

位移测量装置 (msp430f149+AD9851)

来源:画鸵萌宠网
位移测量装置

指导教师:葛华

队员及年级:王鹏杰 电子0501 罗苏安 电子0501 孙飞 电子0502

学校及院系:武汉理工大学信息工程学院电子科学与技术专业

摘要:本文基于TI公司的单片机MSP430F149,设计了一款位移测量装置,该系统主要由激励电路、线性可变差动变压器电路、放大整流滤波电路和数据采集及处理电路四大部分组成。基于性价比的考虑,所有电路均采用TI公司的芯片设计。经测试,系统各项性能指标都达到并超过了设计要求,工作稳定,用户界面友好。

关键字:MSP430F149;差动变压器;位移测量;数据处理

Abstract: Based on TI's MSP430F149 micro-controller, the title designed a displacement measuring device that the system is mainly inspired by the circuit of the linear variable differential transformer, rectifier&filter circuit and data acquisition and processing circuit. Based on cost considerations, all the circuits use TI's chips to design it. After test, the system performance targets are reached and some exceeds the design requirements.

Keywords: MSP430F149; Differential Transformer; Displacement Measurement; Data Processing

1 方案设计

1.1 理论分析

根据题目要求,本系统设计目标主要包括四大部分:激励电路、线性可变差动变压器电路、放大整流滤波电路和数据采集及处理电路。如图1 所示。

图1 位移测量装置

1

上述位移测量装置的工作原理是:激励电路产生正弦波信号经放大电路放大,差分输出运放变成两路相位相差π的正弦信号,驱动差动变压器初级线圈。差动变压器的次级线圈感应出感生电压,电压的大小与变压器中磁棒的位置以及初级激励信号大小有关,当激励信号大小不变时次级输出信号幅值大小取决于磁棒的位置。在一定长度范围内,磁棒位于变压器中央时,次级两端输出信号幅值大小相等;当磁棒移向某一边时,次级的该端的电感L就变大,位移量∆L变大。对于螺绕环,其电感量为:

当插入磁棒后,电感量为:

L 1 = µ 0 µ r n 2 s∆ l + µ 0 n 2 s (l − ∆ l )=µ0n2sl+µ0(µr−1)n2s∆l

(1-1-2) L0=µ0n2sl

(1-1-1)

所以,∆L=L1−L0=µ0(µr−1)n2s∆l=k∆l,即电感变化量∆L与磁棒位移量∆l成正比。故有:

UAL+∆L

U=L

0

0

UBL'−∆LU=L

00

L+L'=L0

UA+UB=U0

(1-1-3)

L0VA−VB

解得 ∆ L = • = k • d 。即位移量∆l与d成正比。

2VA+VB

,

所以电感变化量输出信号幅值就变大,另一端变小,反之亦然。将差动变压

器次级输出信号进行放大整流滤波得到平滑的两组直流电压,该直流电压就反映了磁棒在线圈中的移动距离。通过算法

V−V d=ABVA+VB 距离。

1.2 TI器件选型及介绍

TI(美国德州仪器公司)在模拟及数字领域有着性能优越、品种丰富的器件种类,尤其是在模拟器件和微处理器领域推出了一系列高性能,超低功耗,可靠的运算放大器和微处理器。

本系统控制较为复杂,拟采用320x240LCD显示系统信息,3x4矩阵键盘输入,DDS产生激励信号,因此需要占用大量的单片机IO资源,要求单片机运算速度很快,及时处理A/D采样得到的数据。综合考虑,本系统控制核心采用

(1-1-4)

其中VA、VB为整流滤波后的两组直流电压,d值就精确反映了磁棒的移动

2

MSP430F149单片机。MSP430Fxxx系列是德州仪器公司新开发的一类具有16位总线的带FLASH 的单片机,其性价比和集成度很高。它采用16位的总线,外设和内存统一编址,寻址范围可达64K,还可以外扩展存储器。具有统一的中断管理,具有丰富的片上外围模块资源。片内有精密硬件乘法器、两个16位定时器、一个14路的12位的模数转换器、一个看门狗、6路P口、两路USART通信端口、一路SPI通信端口、一个比较器、一个DCO内部振荡器和两个外部时钟,支持8M 的时钟,有PWM工作模式。由于为FLASH型,则可以在线对单片机进行调试和下载,且JTAG口直接和FET(FLASH EMULATION TOOL)相连,不需另外的仿真工具,方便实用,而且具有超低功耗。

图2 MSP430F149引脚图

本在激励电路中,由于要驱动线圈低阻负载,需要选择驱动能力强的单端输入到差分输出的转换电路,因此采用TI的THS4503全差分输出放大器。THS4503其带宽可达370MHz,转换速率2800 V/µs,宽电源供电范围(5 V,±5 V,12V,15V),线性度好,增强AC性能并具有较好的散热能力。

图3 THS4503引脚图

为了去除采样时激励信号的干扰,必须保证在一个激励周期内采样5个点,即采样速率0.5MSPS,为了进一步提高精度,应选具有1MSPS的A/D转换芯片。本系统选用TI公司的A/D转换芯片ADS7886。ADS7886是12位串行接口, 1MSPS速率采样,微功耗SAR型A/D转换器。具有20MHz串行接口速率,电路简单,无须任何外围器件,6脚SOT23超小封装。

3

图4 ADS7886引脚图

1.3 设计方案论证

方案一:系统激励部分正弦波产生电路采用传统的函数发生芯片产生,经放大送入差分运放、变压、整流滤波后,根据两路电压改变得到位移值。该方案产生正弦波具有低相位噪声等优点,但传统的函数发生芯片电路结构复杂、分立元件较多,不利于实际制作,故不采用此方案。

方案二:正弦波产生使用DDS方案,而整流滤波电路采用真有效值检测芯片。真有效值检测可以将交流电压很好的转换成其有效值大小的直流电平,利于后级电压采样。但由于真有效值检测芯片(如AD637)价格昂贵,电路成本高昂,故不采用此方案。

方案三:正弦波产生采用直接数字式频率合成器(DDS),后级电路与方案一相同。DDS方案电路简单,仅用一块芯片就可以实现,而且可以产生较宽频率范围的正弦波且失真度小。采用普通的二极管整流滤波电路。为使后级A/D采样电路稳定采样,增强了整流滤波电路的滤波特性,并加一级电压跟随器进行隔离缓冲,以达到较高精度。

通过以上分析,选择方案三。正弦波使用DDS芯片产生,经放大差分后输入可变差动变压器初级,次级生成两路交流电压,经过放大整流滤波后得到直流电压,经A/D转换后送入单片机,单片机通过线性拟合计算即可得到位移量。

2 系统实现

2.1 硬件设计 2.1.1 系统原理框图

图5 系统原理框图

4

2.1.2 接口设计

激励电路使用单片机控制AD9851产生100kHz的正弦波,与430单片机接口电路如图6所示。AD9851输出正弦波峰峰值为500mV左右,加一级放大,使输出峰峰值为1V左右,送入差分运放THS4503。

图6 DDS与单片机接口电路

为了使差分运放稳定工作,将THS4503的放大倍数设置为1,并根据其典型应用电路配置反馈电阻。THS4503与前级、后级接口电路如图7所示。

图7 THS4503与前级、后级接口电路

为了增强对感性负载的驱动能力,从THS4503出来的两路差分信号经过两片AD811进行放大,驱动差动变压器前级线圈。从差动变压器次级出来的交流信号同样经过AD811进行一次放大,以达到足够大的幅值送给整流二极管进行整流,再经过两级电容滤波,得到平滑的直流电压。由于经过整流器出来的两路电压信号一路为正,一路为负,而A/D转换器只能采样正电压,于是在输出负电压之后采用由通用运放LF353构成的一级反相器进行反相,另一路加一级电压跟随器进行阻抗匹配。同时为了消除数字电路对模拟电路的干扰,数字地和模拟地分开,之间用磁珠相连进行处理,达到了较好的抗干扰效果。设计的电路如

5

图8所示。

图8 差动变压器与前级、后级接口电路

电机驱动采用PWM方式控制,MSP430F149通过内部定时器产生PWM信号,通过光耦进行隔离,驱动TIP122达林顿管驱动电机运转,同时通过两路继电器控制电机的正反转,以达到精确控制磁棒位移的目的。

图9 电机驱动电路

2.1.3 硬件设计注意事项

硬件电路是整个系统的基础,是保证系统正常工作的必要条件。在该系统的硬件电路设计制作过程中,应充分注意以下几点:

1)电源。电源电路为整个系统服务,其参数指标决定着整个系统的性能指标,在电源的电路设计过程中,应注意数字电路(单片机系统)对模拟电路的干扰,电路中数字地和模拟地应当分开处理,尽可能采用独立的两组电源分别给数字部分和模拟部分进行供电。

2)激励源信号。从DDS出来的100kHz正弦信号要进行充分的滤波,尽可能地消除高频分量。送入差分运放THS4503的正弦信号要进行隔直处理,去掉直流偏置,否则THS4503会发热严重,甚至烧毁芯片。

3)A/D转换电路。ADS7886对干扰非常敏感,不能用排线将其数据端与430单片机进行连接,而要使用分散的,尽可能短的线进行连接,否则430单片机无法读到A/D转换后的数据。

6

4)电机驱动电路。直流电机在运行过程中会产生非常强的电磁干扰,要充分考虑到直流电机的影响,在直流电机两端要加吸收电容,电机驱动电路要加足够的电源滤波电容。

5)线圈电路。本系统中差动变压器实际上是一个无线电天线,弥漫在空中的各种无线电波都会对其造成干扰,为了提高精度,最好在线圈外加屏蔽措施,增强抗干扰能力。 2.2 软件设计

2.2.1软件流程及设计思路技巧

本系统的主要程序流程:主程序始终运行,根据用户需要,可分别进入三种模式——手动控制、步进控制及自动控制,返回主程序循环。

具体流程如下:

开始 初始化:MSP430端口、液晶屏、ADS7886、AD9851 显示人机交互界面 读取ADS7886转换数据 数据处理(计算d值等) 更新显示(VA、VB、d、实际位移) 是否 有有效按键 按下 是 2键 模式2 否 1键 3键 模式1 模式3 图10 主程序流程图

系统上电复位后,主程序开始初始化各个模块,并显示欢迎界面;然后读取A/D采样值,计算VA、VB、d值,并根据d值计算实际位移;更新屏幕显示,判断按键;最后循环执行。

7

A/D转换器ADS7886的驱动根据其数据手册提供的时序,进行软件模拟。时序如图11所示。

图11 ADS7886时序图

同时为了消除硬件电路干扰带来的误差,在软件设计上我们做了分段线性拟合及近似的处理,进行软件滤波,达到了很好的效果。

各模式子程序流程图,详见附录。

由于本系统的占用资源较多,程序流程复杂,且涉及到各模式间切换,所以在软件设计时必须遵循模块化设计思路,由小到大,编好各个模块程序,再组合成整个程序。

软件编程的几点技巧:

1)所有子程序用到的端口,全部用宏定义在程序顶部说明以便日后方便全局调用。

2)适当添加注释,方便阅读。

3)关键数据尽量定义为全局变量,因为实践发现,在非全局变量情况下,进行某些复杂运算时,数据可能发生突变,影响结果。

4)设置合适的入口出口参量,以增加程序的重复使用性。

5)当不需要改变整个寄存器值时,全部采取位操作,以避免对其他位的干扰。

6)尽量把工作模式完善,以应对不同情况对工作模式的需求。 2.2.2 MSP430单片机选型及应用

由于本系统占用的资源较多,需要使用较多的I/O端口,因此选用MSP430Fxxx系列中性价比较高的MSP430F149单片机,MSP430F149单片机自带60KB Flash ROM,拥有6个8位的I/O口,且拥有丰富的片内资源,满足本系统的设计需要。

MSP430F149单片机具有JTAG调试接口,可以在IAR集成编译环境在线仿真调试程序,非常方便,且不需要额外的仿真工具。MSP430F149运算速度很快,在外部8M晶振驱动下,执行一条指令的时间为0.125µS。 2.2.3 编程感想及软件设计注意事项

本系统在程序编写方面的收获,可以总结为以下几点:

8

1)本系统对MCU的要求较高,AT89系列及STC系列已基本不能满足设计要求,需要更高性能、更多资源的芯片,TI公司混合信号430单片机应运而生; 2)在设计软件时,必须进行模块化设计及程序包式封装,增加程序之间的兼容性和可重复利用性,提高效率;

3)此外还应注意充分应用仿真工具,发挥其辅助设计作用,提高调试程序的速度和效率,节约时间。

3 作品性能测试与分析

3.1 系统测试方法

测量系统如图12所示。系统测量指标主要分四个方面:①正弦信号测试;②差动输出信号测试;③直流电压测试;④位移量测试。采用DS5062MAE 60M双踪数字示波器检测正弦信号的频率及幅度、差动输出信号的相位和幅值;采用四位半数字万用表检测差整流滤波后得到的直流电平;采用数显游标卡尺精确测量实际位移量。

图12 测量系统

3.2 性能测试

⑴正弦波信号测试

表1 正弦波输出特性

要求频率(kHz)

100kHz

实际频率(kHz)

100.00kHz

电压峰峰值(mV)

510

频率误差 0%

是否失真 无失真

⑵差动变压器输出信号测试

表2 差动变压器输出特性

正向位移

位置(mm) 0.00 5.00 10.00 15.00 20.00 25.00

频率(kHz) 100 100 100 100 100 100

波形特性 峰峰值(V) 1.88 1.18 0.86 0.58 0.37 0.39

有无失真

无 无 无 无 无 无

位置 (mm) 0.00 -5.00 -10.00 -15.00 -20.00 -25.00

反向位移

波形特性

频率(kHz) 100.00 100.00 100.00 100.00 100.00 100.00

峰峰值(V) 1.88 1.84 2.14 2.44 2.68 2.70

有无失真

无 无 无 无 无 无

9

⑶直流电压测试

表3 直流电压信号VA、VB、和d值

正向位移

位置(mm) 0.00 5.00 10.00 15.00 20.00 25.00

VA 电压(V) 1.09 1.46 1.82 2.16 2.40 2.46

VB 电压(V) 1.09 0.68 0.37 0.13 0.02 0.01

d值 0.000 0.365 0.659 0.885 0.986 0.995

位置(mm) -0.00 -5.00 -10.00 -15.00 -20.00 -25.00

反向位移 VA 电压(V) 1.10 0.79 0.45 0.17 0.04 0.02

VB 电压(V) 1.09 1.48 1.86 2.19 2.40 2.46

d值 -0.001 -0.305 -0.609 -0.859 -0.968 -0.984

⑷位移量测试

表4 位移量误差测试

正向位移

设定位移(mm)

0.00 5.00 10.00 15.00 20.00 25.00

实际位移(mm)

0.01 5.25 10.47 15.34 20.20 25.32

绝对误差(mm)

0.01 0.25 0.47 0.34 0.20 0.32

设定位移(mm)

-0.00 -5.00 -10.00 -15.00 -20.00 -25.00

反向位移 实际位移(mm)

-0.02 -5.21 -10.44 -15.27 -20.29 -25.35

绝对误差(mm)

0.02 0.21 0.44 0.27 0.29 0.35

3.3 误差分析

根据题目要求,本设计实现了所有基本功能,达到了基本指标,并且在许多方面有一定的扩展,如测量精度达到0.5mm以内,测量范围-25~25mm等。

总结误差来源,主要有以下几个方面:

1)差动变压器手工绕制时有一定误差,初级和次级线圈的不严格对称对系统精度有一定影响。

2)电机传动的机械部分精度不高,影响电机定位。

3)整流电路滤波效果不是非常理想,影响A/D转换器采样得道的电压值。 3.4 进一步改进措施

经过测试,本系统都达到了并超过了题目要求的各项指标,但系统的精度也有待进一步提高。系统还应采取以下措施进行完善:

1)提高差动变压器的绕制精度。本系统的差动变压器初级电感量经实测约为90μH,有些偏小,应增大电感量。

2)电机传动部分的机械精度需要进一步改善,采用齿轮密度大的齿轮组提高控制精度。

3)整流部分采用精密整流电路,使送入A/D转换器的直流电压稳定精确,提高系统的测量精度。

10

致 谢

感谢德州仪器半导体技术(上海)有限公司赛前培训及赞助本次湖北省电子设计竞赛,贵公司提供的优秀的模拟器件和MSP430单片机芯片是本作品成功设计完成的保证,今后我们会继续关注贵公司的器件和产品,在这里我们指导老师和全体队员向贵公司表示衷心地感谢!

11

附录

1其它模块电路图 其它模块电路图

1)MSP430主控电路及液晶电路

2)电源电路

12

2直流电压信号VA、VB、、d值随位移量变化曲线

直流电压信号VA、VB、、d值随磁棒位移量变化而变化,使用Microsoft Excel软件得到其变化曲线。

A32.521.510.50-0.5-1-1.5-25-23-21-19-17-15-13-11-9-7-5-3-10Bd24681012141618202224其中 A——直流电压信号VA(V);

B——直流电压信号VB(V); d——d=(VA-VB)/(VA+VB)。

3 主要波形 1)DDS输出波形

13

2)THS4503差分输出波形

3)差动变压器次级输出波形

4)整流滤波后波形

14

4 作品实物图

5 关键源程序

(1)主程序

#define PWMDIR P2DIR//输出端口 #define PWMOUT P2OUT

#define PWM BIT7;//输出位

long crystal=8000000;//振荡频率(主时钟)

//-----------------------------------初始化-----------------------------------// void Init_PWMmaker(long frequency,char zkb) {

PWMDIR|= PWM;

TACTL|=TASSEL1+TACLR;

CCR0=crystal/frequency;//计算计数值 CCR1=CCR0/100*zkb;//计算占空比 CCTL0|= CCIE;//中断使能 CCTL1|= CCIE; _EINT();

TACTL|=MC_1;//增计数模式 }

//------------------------------------中断处理--------------------------------// #pragma vector=TIMERA0_VECTOR __interrupt void CCR0int (void) {

PWMOUT|= PWM;

15

}

#pragma vector=TIMERA1_VECTOR __interrupt void CCR1int (void) {

if (TAIV&0x02)//判断是否为CCR1的中断 {

PWMOUT&=~PWM; } }

//读标志位模式 /*{

if (CCTL1&CCIFG) {

num=~num; P1OUT=num;

CCTL1&=~CCIFG; }

if (TACTL&TAIFG) {

num=~num; P1OUT=num;

TACTL&=~TAIFG; } }*/

(2)AD9851控制程序 #include \"AD9851.h\"

//------------------------------子程序------------------------------------------ //------------------------------------------------------------------------------ // 初始化函数

//------------------------------------------------------------------------------ void Init_AD9851() {

//P3.4/.5/.6为DDS端口

DATA_DDR |= DATA;//设置数据输出口为输出方向

CTRL_DIR |= FQ_UD + W_CLK + RESET;//P3口的控制位为输出方向}

//------------------------------------------------------------------------------ // 计算控制字

// 入口:频率数组指针 出口:控制字 //------------------------------------------------------------------------------ unsigned long Control_word_Calculation(unsigned char *fno) {

16

unsigned long dds;

dds=(*(fno+7))*FF7+ (*(fno+6))*FF6+ (*(fno+5))*FF5+ (*(fno+4))*FF4+ (*(fno+3))*FF3+ (*(fno+2))*FF2+ (*(fno+1))*FF1+ (*fno)*FF0; return dds; }

//------------------------------------------------------------------------------ // 拆分函数

//------------------------------------------------------------------------------ void AD9851_word_break(void) {

DDS_Word_8[1]=AD9851_word_32>>24&0x000000FF;//最前 DDS_Word_8[2]=AD9851_word_32>>16&0x000000FF; DDS_Word_8[3]=AD9851_word_32>>8&0x000000FF;

DDS_Word_8[4]=AD9851_word_32&0x000000FF;//最后8位控制字}

//------------------------------------------------------------------------------ // 延时函数

//------------------------------------------------------------------------------ void delay_9851(void) {

int i;

for(i=0;i<200;i++); }

//------------------------------------------------------------------------------ // AD9851控制函数

//------------------------------------------------------------------------------

void Write_AD9851(unsigned char data[5])//连续发送5字节数据到{

unsigned char i;

CTRL_OUT&=~W_CLK;//W_CLK=0 CTRL_OUT&=~FQ_UD;//FQ_UD=0

for(i=0;i<5;i++) {

DATA_PORT=data[i]; //上升沿写入数据 CTRL_OUT&=~W_CLK;//W_CLK=0 CTRL_OUT|=W_CLK;//W_CLK=1 }

8位控制字 AD9851 17

CTRL_OUT&=~FQ_UD;//FQ_UD=0执行转换 CTRL_OUT|=FQ_UD;//FQ_UD=1 }

//------------------------------------------------------------------------------ // 初始化复位函数

//------------------------------------------------------------------------------ void RSET_AD9851(void) {

CTRL_OUT&=~RESET;//RESET=0 CTRL_OUT|=RESET;//RESET=1

delay_9851();delay_9851();delay_9851();delay_9851(); CTRL_OUT&=~RESET;//RESET=0

delay_9851();delay_9851();delay_9851();delay_9851(); Write_AD9851(DDS_Word_0);//清空寄存器 Write_AD9851(DDS_Word_0);//清空寄存器 }

(3)ADS7886控制程序

#define ADS7886OUT P3OUT #define ADS7886DIR P3DIR #define ADS7886SEL P3SEL #define ADS7886IN P3IN #define CLK0 BIT0 #define DAT0 BIT1 #define CSS0 BIT2 #define CLK1 BIT3 #define DAT1 BIT4 #define CSS1 BIT5

int dataA,dataB,dAa,dBa,dA[20],dB[20];//ADS7886接收的数据 long subA,subB; float VA,VB,d;

char disA[5],disB[5],disd[5],dism[4]; char direction=0,move;

#define Num_of_Results 4

static unsigned int A0results[Num_of_Results]; // These need to be global in static unsigned int A1results[Num_of_Results]; // this example. Otherwise, the

//--------------------------------双ADS7886采样--------------------------------// void ADS7886_R(char j) {

char i;

ADS7886OUT |= CLK0 + CSS0 + CLK1 + CSS1;//CLK=1,CSS=1

18

ADS7886DIR |= CLK0 + CSS0 + CLK1 + CSS1;//输出 ADS7886DIR &=~(DAT0 + DAT1);//输入 ADS7886SEL = 0;

ADS7886OUT &=~(CSS0 + CSS1);//CSS=0 dataB=0;dataA=0;

for(i=0;i<15;i++) {

dataB=dataB<<1;//左移 dataA=dataA<<1;

ADS7886OUT &=~(CLK0 + CLK1);//CLK=0 if (ADS7886IN&DAT0) dataA |= BIT0;//末位置1 else dataA &=~BIT0;//末位置0 if (ADS7886IN&DAT1) dataB |= BIT0;//末位置1 else dataB &=~BIT0;//末位置0 ADS7886OUT |= CLK0 + CLK1; }

ADS7886OUT |= CSS0 + CSS1; dA[j]=dataA;dB[j]=dataB; }

//------------------------------数据处理及显示--------------------------------// void dispose_display() {

//数据处理

VA=dAa*3.310/4096; disA[4]=(char)(VA); disA[3]=17;

disA[2]=(char)((VA-disA[4])*10);

disA[1]=(char)((VA*10-disA[4]*10-disA[2])*10);

disA[0]=(char)((VA*100-disA[4]*100-disA[2]*10-disA[1])*10);

VB=dBa*3.310/4096; disB[4]=(char)(VB); disB[3]=17;

disB[2]=(char)((VB-disB[4])*10);

disB[1]=(char)((VB*10-disB[4]*10-disB[2])*10);

disB[0]=(char)((VB*100-disB[4]*100-disB[2]*10-disB[1])*10);

if (VA==0&&VB==0) d=0; else d=(VA-VB)/(VA+VB); gotoxy(32,150); if (d>0) {

direction=0;//正方向

19

lcd_character(\"+\ }

else {

d=0-d;

direction=1;//反方向 lcd_character(\"-\ }

disd[4]=(char)(d); disd[3]=17;

disd[2]=(char)((d-disd[4])*10); disd[1]=(char)(d*100)%10; disd[0]=(char)(d*1000)%10; //第一段内 if ((d>=-0.280)&&(d<=0.280)) move=(char)(d/0.007);//0~4 //第二段内

if (((d>-0.524)&&(d<=-0.280))||((d>=0.280)&&(d<0.524))) move=(char)(d/0.0065);//4~8 //第三段内

if (((d>-0.690)&&(d<=-0.524))||((d>=0.524)&&(d<0.690))) move=(char)(d/0.0061);//8~11 //第四段内 if (((d>-0.690)&&(d<=-0.850))||((d>=0.690)&&(d<0.850))) move=(char)(d/0.0061);//11~15 //第五段内

if (((d>-0.960)&&(d<=-0.940))||((d>=0.940)&&(d<0.960))) move=(char)(d/0.006);//三位有效move值

dism[3]=move/100;

dism[2]=(move-dism[3]*100)/10; dism[1]=17;

dism[0]=move%10; //数据显示 char i;

for(i=0;i<5;i++) {

gotoxy(6+i,150);

lcd_character1(tab_num[disA[4-i]]); gotoxy(18+i,150);

lcd_character1(tab_num[disB[4-i]]); gotoxy(33+i,150);

lcd_character1(tab_num[disd[4-i]]); }

if (direction==0) {

gotoxy(31,180);

20

lcd_character(\"+\ } else {

gotoxy(31,180); lcd_character(\"-\ }

gotoxy(32,180);

lcd_character1(tab_num[dism[3]]); gotoxy(33,180);

lcd_character1(tab_num[dism[2]]); gotoxy(34,180);

lcd_character1(tab_num[dism[1]]); gotoxy(35,180);

lcd_character1(tab_num[dism[0]]); }

(4)键盘扫描程序

#define KEY_DIR P4DIR #define KEY_OUT P4OUT //列选 #define KEY_IN P4IN //行选

/*********************************************************** ***********************************************************/ int key_scan();

int key_scan(void) {

int i;

char j,temp,buf=0; int key=10;

S:KEY_DIR =0x70; //设置高三位为输出,低四位为输入 KEY_OUT =0x00;

if((KEY_IN&0x0F)==0x0F) //判断低四位(列)是否为高 goto S; //无键按下 else {

for(i=300;i>0;i--); //延时去抖后再判断 if((KEY_IN&0x0F)==0x0F) goto S;

else //确认有键按下 {

temp =0x60; //行扫描控制 for(j=0;j<3;j++)

21

{

KEY_OUT = temp;

buf = (~KEY_IN)&0x0F; //滤掉高四位 switch (buf) {

case 8 : key = 4*j+3; break; case 4 : key = 4*j+2; break; case 2 : key = 4*j+1; break; case 1 : key = 4*j+0; break; }

temp=(temp<<1)|0x10&0x70; //左移一位,第四位置 } do{

KEY_OUT =0x00;

}while((KEY_IN&0x0F)!=0x0F); if(key<9)

return key+1; else if(key==9) return 0;

else if(key==10) return 11; else if(key==11) return 12; else goto S; } } }

(5)PWM控制程序

#define PWMDIR P2DIR//输出端口 #define PWMOUT P2OUT

#define PWM BIT7;//输出位

long crystal=8000000;//振荡频率(主时钟)

//-----------------------------------初始化-----------------------------------// void Init_PWMmaker(long frequency,char zkb) {

PWMDIR|= PWM;

TACTL|=TASSEL1+TACLR;

CCR0=crystal/frequency;//计算计数值 CCR1=CCR0/100*zkb;//计算占空比 CCTL0|= CCIE;//中断使能 CCTL1|= CCIE; _EINT();

TACTL|=MC_1;//增计数模式

1,第八位置0 22

}

//------------------------------------中断处理--------------------------------// #pragma vector=TIMERA0_VECTOR __interrupt void CCR0int (void) {

PWMOUT|= PWM; }

#pragma vector=TIMERA1_VECTOR __interrupt void CCR1int (void) {

if (TAIV&0x02)//判断是否为 {

PWMOUT&=~PWM; } }

//读标志位模式 /*{

if (CCTL1&CCIFG) {

num=~num; P1OUT=num;

CCTL1&=~CCIFG; }

if (TACTL&TAIFG) {

num=~num; P1OUT=num;

TACTL&=~TAIFG; } }*/

CCR1的中断 23

因篇幅问题不能全部显示,请点此查看更多更全内容

Top