数控恒流源设计报告加程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数控恒流源
设计报告
背景
数控恒流源是单片机运用数字控制技术控制恒流源的一种设计方案。
当前,数字化数控恒流源的应用,随着电子技术的发展使用范围越来越广,在电子测量仪器、激光、传感技术、超导、现代通信等高新技术领域,恒流源都被广泛应用,且发展前景较为良好。
同时,也不仅局限于此。
电子领域,数控恒压技术已经很成熟,但是恒流方面特别是数控恒流的技术是有待发展,高性能的数控恒流器件的开发和应用存在巨大的发展空间。
所以设计一个数控恒流源方案来提高恒流源的稳定性、适用范围以及精度很有必要。
目录
第一章设计方案
第二章恒流电路
第三章MSP430F149单片机及电源
第四章 AD模块
第五章DA模块
第六章键盘模块和显示模块
第七章软件设计
第八章实验总结
第一章设计方案
本设计本设计是基于单片机控制的直流恒流源,分为以下几个组成部分:单片机控制系统、A/D和D/A转换模块、电源模块、恒流源模块、负载及键盘液晶显示模块, 系统框图如图所示。
系统框图
用430单片机作为整机的控制单元,通过改变D/A转换器的输入数字量来改变输出电压值,从而间接地改变压控恒流源的输出电流大小。
为了能够使系统具备检测实际输出电流值的大小,可以将电流转换成电压,并经过A/D转换器进行模数转换,用单片机实时对电压进行采样,与输入预期值比较,并通过430单片机进行进行数据处理微调输出,提高精度实时显示。
第二章恒流电路
数控直流电流源可以采用电流输出型D/A转换器来实现,单由于其输出电流的幅值一般在u A数量级,因此需要进行电流放大若干倍才能达到所需要的要求电流值,电路实现很困难。
若选择电压输出型DAC,再通过V-I转换电路变成与之成比例的电流信号,则电路实现相对简单,因此设计直流电源时常采用该种方案实现,在这种方案中,V/I转换电路设计是关键。
通常的V/I转换有两种方式,一种是负载共地的方式,一种是负载共电源的方式。
我们选用的是负载共地的方式,因为有很多电路负载在连接的时候需要进行共地。
R6为电流反馈采样电阻,R5为限流电阻,RL为负载电阻。
R7为A/D转换采样电阻,R 6采样到的电流信号加到电路的输入端,构成电流并联负反馈电路。
由虚断知,运算放大器输入端没有电流流过,
则(Vi –V2)/R1= (V1 –V4)/R2……a
同理(V3–V2)/R3= V2/R4 ……b
由虚短知V1 =V2……c
如果R1=R2=R4=R3,则由abc式得V3-V4=Vi
上式说明R6两端的电压和输入电压Vi相等,则通过R7和RL的电流I=Vi/R6。
如果负载RL<<100KΩ,且运算放大器的放大增益足够大时,通过负载RL的电流仅有输入电压Vi决定,并且I=Vi/R6。
所以R1、R2、R3、R4选用100kΩ。
为了方便采样,我们选择R6为1Ω电阻。
Vi为0~1V,我们做的恒流源输出电流在0~100mA,R6=1/0.1=10Ω。
为了扩大电流的输出能力,在上电路的负反馈没有通过电阻直接反馈,而是串联了三极管的发射结,进行电流放大。
因为在恒流源电路中,MOSFET管的输入电容太大,而一般运放的输出电阻都在几十欧姆以上,会造成闭环的延迟,而高增益的闭环负反馈中的迟延很容易振荡,三极管的放大倍数选大些,也可以用复合管,实际上电阻的误差比三极管基极电流的影响可能要大,还可以通过调节电阻的值来调节.所以我们选用的是三级管而不是MOSFET管。
第三章 MSP430F149单片机及电源
3.1MSP430F149单片机
MSP430F149单片机是一个16 位的、具有精简指令集的、超低功耗的混合型单片机。
由于它具有极低的功耗、达到60KB的FLASH容量、丰富的片内外设和相对较小的体积及方便灵活的开发环境,已成为众多单片机系列中一颗耀眼的“芯星”。
开发板资源描述:
【1】.板载MSP430F149芯片
【2】.集成USB型BSL编程器(对自身或其他板子进行bsl编程)
【3】.提供32.768KHZ和8MHZ两种晶振连接方式
【4】.采用USB供电和程序下载,优质电容滤波
【5】.采用标准JTAG接口(14针),支持硬件仿真。
【6】.所有IO口(包括AD电源等)均引出(未焊接排针,可自己向上或向下焊接)。
【7】.4路彩色LED全部上拉,可以借此观察程序运行状态。
【8】.2个优质独立按键。
【9】.板载手动复位电路。
【10】.板载蜂鸣器电路,可做音乐实验等。
【11】.提供NRF24L01+无线模块接口。
【12】.板子集成USB转串口功能。
【13】.向外提供3.3v和5v电源排针。
MSP430的端口有P1、P2、P3、P4、P5、P6、S和COM(型号不同,包含的端口也不仅相同,如MSP430X11X系列只有P1,P2端口,而MSP430X4XX系列则包含全部上述端口),它们都可以直接用于输入/输出。
MSP430系统中没有专门的输入/输出指令,输入/输出操作通过传送指令来实现。
端口P1`P6的每一位都可以独立用于输入/输出,即具有位寻址功能。
常见的键盘接口可以直接用端口进行模拟,用查询或者中断方式控制。
由于MSP430的端口只有数据口,没有状态口或控制口,在实际应用中,如在查询式输入/输出传送时,可以用端口的某一位或者几位来传送状态信息,通过查询对应位的状态来确定外设是否处于“准
备好”状态。
端口的功能。
(1)P1,P2端口:I/O,中断功能,其他片内外设功能如定时器、比较器;(2)ﻩﻩP3,P4P5P6端口:I/O,其他片内外设功能如SPI、UART模式,A/D转换等;(3)S,COMﻩﻩ端口:I/O,驱动液晶。
MSP430各端口具有丰富的控制寄存器供用户实现相应的操作。
其中P1,P2具有7个寄存器,P3~P6具有4个寄存器。
通过设置寄存器我们可以实现:(1)每个I/O位独立编程;(2)任意组合输入,输出和中断;(3)P1,P2所有8个位全部可以用作外部中断处理;(4)可以使用所以指令对寄存器操作;(5)可以按字节输入、输出,也可按位进行操作。
端口P1,P2的功能可以通过它们的7个控制寄存器来实现。
这里,Px代表P1或P2。
(1)PxDIR:输入/输出方向寄存器。
8位相互独立,可以分别定义8个引脚的输入/输出方向。
8位再PUC后都被复位。
使用输入/输出功能时,应该先定义端口的方向。
作为输入时只能读,作为输出时,可读可写。
0:输入模式;1:输出模式。
如:P1DIR|=BIT4;//P1.4输出,P2DIR=0XF0; //高4位输出,低4位输入。
(2)PXIN:输入寄存器,为只读寄存器。
用户不能对它进行写入,只能通过读取其寄存器的内容来知道I/O口的输入信号。
所以其引脚的方向要选为输入。
如再键盘键盘扫描程序中
经常要读取行线或者列线的端口寄存器值来判断案件情况。
例如:unsigned char
key;P1DIR&=~BIT4;//P1.4输入……
key=P1IN&0X10;//输出端口P1.4的值……
(3)PXOUT:输出寄存器。
该寄存器为I/O端口的输出缓冲寄存器,再读取时输出缓存的内容与引脚方向定义无关。
改变方向寄存器的内容,输出缓存的内容不受影响。
如:PIOUT|=0X01; //P1.0输出1,PIOUT&=~0X01;//P1.0输出0。
(4)PXIFG:中断标志寄存器。
他的8个标志位标志相应引脚是否有中断请求有待处理。
0:无中断请求,1:有中断请求。
其中断标志分别为PXIFG.0~PXIFG.7。
应该注意的是:PXIFG.0~PXIFG.7共用一个中断向量,为多源中断。
当任一事件引起的中断进行处理时,PXIFG.0~PXIFG.7不会自动复位,必须由软件来判断是对哪一个事件,并将相应的标志复位。
另外,外部中断事件的时间必须保持不低于1.5倍的MCLK时间,以保证中断请求被接受,且使相应中断标志位置位。
(5)PXIES:中断触发沿选择寄存器。
如果允许PX口的某个引脚中断,还需定义该引脚的中断触发方式。
0:上升沿触发使相应标志置位,1:下降沿触发相应标志置位。
如:MOV.B#07H,&P1IES;p1低3位下降沿触发中断。
(6)PXIE:中断使能寄存器。
PX口的每一个引脚都有一位用以控制该引脚是否允许中断。
0:禁止中断,1:允许中断。
MOV.B #0E0H, &P2IE ;P2高3位允许中断。
(7)PXSEL:功能选择寄存器。
P1,P2两端口还具有其他片内外设功能,将这些功能与芯片外的联系通过复用P1,P2引脚的方式来实现。
PXSEL用来选择引脚的I/O端口功能与外围模块功能。
0:选择引脚为I/O端口,1:选择引脚为外围模块功能。
如:P1SEL|=0X10; //P1.4为外围模块功能。
端口P3、P4、P5、P6没有中断能力,其余功能同PI,P2。
除掉端口P1,P2与中断相关的3个寄存器,端口P3,P4,P5,P6的4个寄存器(用法同P1,P2)分别为PXDIR,PXIN,PXOUT,PXSEL可供用户使用。
端口COM和S,他们实现与液晶片的直接接口。
COM为液晶片的公共端,S为液晶片的段码端。
液晶片输出端也可经软件配置为数字输出端口。
3.2电源模块:5v12v佰嘉达D-120A双组电源
佰嘉达D-120A 双组电源是开关电源(英文:Switching Mode PowerSupp ly),又称交换式电源、开关变换器,是一种高频化电能转换装置。
其功能是将一个位准的电压,透过不同形式的架构转换为用户端所需求的电压或电流。
开关电源体积小、重量轻:由于没有工频变压器,所以体积和重量只有线性电源的20~30%。
功耗小、效率高:功率晶体管工作在开关状态,所以晶体管上的功耗小,转化效率
高,一般为60~70%,而线性电电源只有30~40%。
所以选择开关电源转化和提供12V和5V电压。
第四章 DA模块
因为MSP430F149单片机内部并没有内置DAC12模块,所以必须外接DAC芯片进行DA转换。
考虑到恒流源的精度和步进的大小,我们决定使用12位的DAC芯片来进行DA转换。
经过挑选,我们使用12位的TLV5618。
其连接图如下
DA模块电路图
特性双通道12位电压输出型DAC
可编程设置时间:3uS—10uS
兼容TMS320和SPI接口
可直接代替TLC5618
应用数字电路控制
数字偏移及增益控制
工业生产控制
机器和自动控制装
第五章AD模块
这里采用的是MSP430F149单片机内
部的ADC12模块,需在单片机外接如图所示
的一些元件辅助芯片。
ADC12提供4种转换模式:
单通道单次转换
序列通道单次转换
单通道多次转换
序列通道多次转换
这里我们只用单通道单次转换
对选定的通道进行单次转换要进行如下设
置:
x=CSStartAdd,指向转换开始地址
ADC12MEMx存放转换结果
ADC12IFG.x为对应的中断标志
ADC12MCTLx寄存器中定义了通道和参考电压
转换完成时必须使ENC再次复位并置位(上升沿),以准备下一次转换。
在ENC复位并再次置位之前的输入信号将被忽略。
AD模块电路图
不论用户使用何种转换模式,都要处理以下问题:
设置具体模式ﻫ输入模拟信号ﻫ关注转换结束信号
存放转换数据以及采用查询或者中断方式读取数据
二、ADC12寄存器说明
1.ADC12CTL0 控制寄存器0,各位定义:
ADC12SC——采样/转换控制位。
在不同条件下,ADC12SC的含义如下所示:ENC——转换允许位。
0:ADC12为初始状态,不能启动A/D转换;
1:首次转换由SAMPCON上升沿启动
ADC12TVIE——转换时间溢出中断允许位(当前转换还没完成时,又发生一次采样请求,则会发生转换时间溢出)
0:没发生转换时间溢出1ﻫ:发生转换时间溢出
ADC12OVIE——溢出中断允许位(当ADC12MEMx中原有数据还没有读出,而又有新的转换结果数据要写入时,则发生溢出)
0:没发生溢出1ﻫ:发生溢出
ADC12ON——ADC12内核控制位
0:关闭ADC12内核
1:打开ADC12内核
REFON——参考电压控制位
0:内部参考电压发生器关闭ﻫ1:内部参考电压发生器打开
2.5V——内部参考电压的电压值选择位
0:选择1.5V内部参考电压1ﻫ:选择2.5V内部参考电压
MSC——多次采样转换位(CONSEQ<>0表示当前转换模式不是单通道单次转换)
SHT1、SHT0——采样保持定时器1,采样保持定时器0
分别定义保存在转换结果寄存器ADC12MEM8~ADC12MEM15和ADC12MEM0~ADC12MEM7中的转换采样时序与采样时钟ADC12CLK的关系。
采样周期是AD
C12CLK周期乘4的整数倍。
2.ADC12CTL1 转换控制寄存器1(大多数3~15位,只有在ENC=0时才可被修改),各位定义:
CSSTARTADD——转换存储器地址位。
该4位所表示的二进制数0~15分别对应ADC12MEM0~15。
可以定义单次转换地址或序列转换的首地址。
SHS——采样触发输入源选择位。
SHP——采样信号(SAMPCON)选择控制位。
ISSH——采样输入信号方向控制位
ADC12DIV——ADC12时钟源分频因子选择位。
分频因子为该3位二进制数加1
ADC12SSEL——ADC12内核时钟源选择
CONSEQ——转换模式选择位
ADC12BUSY——ADC12忙标志(只用于单通道单次转换模式,在其它转换模式下,该位无效)
3.ADC12MEM0~ADC12MEM15 转换存储寄存器
该组寄存器均为16位寄存器,用来存放A/D转换结果。
中用其中低12位,高4位在读出时为0
4.ADC12MCTLx 转换存储控制寄存器(所有位只有在ENC为低电平时可修改,在POR 时各位被复位)
对于每个转换存储器有一个对应的转换存储器控制寄存器,所以在进行CSSTARTADD转换存储器地址位设置的同时,也确定了ADC12MCTLx。
5.ADC12IFG 中断标志寄存器为16位,其中中断标志位ADC12IFG.x对应于转换存储寄存器ADC12MEMx:
ADC12IFG.x置位:转换结束,并且转换结果已经装入转换存储寄存器。
ADC12IFG.x复位:ADC12MEMx被访问。
6.ADC12IE 中断使能寄存器为16位,对应于ADC12IFG寄存器:
ADC12IE.x=1:允许相应的中断标志位ADC12IFG.x在置位时发生的中断请求服务。
ADC12IE.x=0:禁止相应的中断标志位ADC12IFG.x在置位时发生的中断请求服务。
7.ADC12IV 中断向量寄存器
ADC12是一个多源中断:有18个中断标志(ADC12IFG.0~ADC12IFG.15与ADC12TOV,ADC12OV),但只有一个中断向量。
所以需要设置这18个标志的优先级顺序,按照优先级顺序安排中断标志的响应,高优先级的请求可以中断正在服务的低优先级。
各中断标志会产生一个0~36的偶数。
ADC12OV和ADC12TOV会在访问ADC12IV后自动复位。
但在响应了ADC12IFG.x 标志对应的中断服务之后,相应的标志不自动复位,用以保证能处理发生溢出的情况。
第六章键盘模块和显示器模块
6.1键盘模块
4X4键盘电路图
键盘在单片机系统中用得非常广泛。
当按键多而且单片机的I/O口有限时,往往要考虑的是矩阵式键盘。
其中有两种方式可以实现矩阵式键盘:一种是利用纯硬件完成解码的称为“编码键盘”;另外一种是利用软件实现解码的称为“非编码键盘”。
在单片机系统中,只要单片机有空余的时间来解码时,我们往往利用的是软件解码的形式,即“非编码键盘”来实现矩阵键盘。
这样可以节约成本。
软件原理为扫描键盘矩阵时,每次只有一行电平拉低。
在逐次扫描拉低的这些行的同时,去读那些列的电平。
;被拉低的行上,按下的键对应的列的电平为0,其它为1.用左移位的指令,在进位位CY里就可以检测出是0还是1.为1表示无按下,;为0表示该键按下。
在扫描按键时,如无按下,则取码指针R1加1后,继续扫描。
如有键按下,转按键处理子程序,按键按下标志位;F0清0(表示按下)。
此时,取码指针的值,就是按键的键名。
随后继续进入按键检测子程序重新扫描。
每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
键盘连接成4×4的矩阵形式,占用单片机P1口的8根线,行信号是P5.0-5.3,列信号是P5.4-5.7。
按键对应功能图
6.21602液晶显示模块
工业字符型液晶,能够同时显示16x02即32个字符。
(16列2行)ﻫ注:为了表示的方便,后文皆以1表示高电平,0表示低电平。
1ﻫ602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自
定义CGRAM,显示效果也不好)。
1ﻫ602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
ﻫ目前市面上字符液晶绝大多数是基于
HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
⑵管脚功能
1602采用标准的16脚接口,其中:
第1脚:VSS为电源地
第2脚:VCC接5V电源正极
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。
第15~16脚:空脚或背灯电源。
15脚背光正极,16脚背光负极。
⑶特性
3.3V或5V工作电压,对比度可调
内含复位电路
提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能
有80字节显示数据存储器DDRAM
内建有192个5X7点阵的字型的字符发生器CGROM
8个可由用户自定义的5X7的字符发生器CGRAM
指令集
1602通过D0~D7的8位数据端传输数据和指令。
显示模式设置:(初始化)00ﻫ110000[0x38] 设置16×2显示,5×7点阵,8位数据接口;ﻫ显示开关及光标设置:(初始化)
0000 1DCBD显示(1有效)、C光标显示(1有效)、B光标闪烁(1有效)
0000 01NSN=1(读或写一个字符后地址指针加1&光标加1),
N=0(读或写一个字符后地址指针减1 &光标减1),ﻫS=1 且N=1 (当写一个字符后,整屏显示左移)ﻫs=0 当写一个字符后,整屏显示不移动ﻫ数据指针设置:
数据首地址为80H,所以数据地址为80H+地址码(0-27H,40-67H)ﻫ其他设置:0ﻫ1H (显示清屏,数据指针=0,所有显示=0);02H(显示回车,数据指针=0)。
第七章软件设计
第八章实验总结
经测试,此数控恒流源在0~100mA时可适用负载的电阻范围为0~69.Ω。
在50m A时相对误差为0,在10mA时显示电流比电流表小1.5mA,在100mA时显示电流比电流表大1.5mA。
并且其误差值近视抛物线。
经分析,我们认为是一方面因为DA采样信号经过LM358放大10倍时误有一定的误差,并不是绝对的十倍,故造成其输出值不是理想状态。
另一方面是因为单片机的ADC模块的参考电压不是很准确,也造成一定影响。
附录1:实物图
附录2:程序清单
#include <msp430x14x.h>
#include "Keypad.h"
#include "cry1602.h"
#defineucharunsigned char
#define uintunsigned int
#define Num_of_Results 32
uchar shuzi[]={"0123456789."};
staticuintresults[Num_of_Results]; //保存ADC转换结果的数组
void Trans_val(uintHex_Val);
voidDA_conver(uint dig);
void shuzishuru(uint shuzi);
void Write_A_B(uintdata_a,uintdata_b,ucharchannal,uchar model);
//提示语句:
uchar Strings[]={"Please enter the currentvalue:"};
uchar ceshi1[]={"No data"};
uchar ceshi2[]={"Less than 100mA"};
uchar ceshi3[]={"A:"};
uchar ceshi4[]={"B:"};
uchar ceshi5[]={"mA"};
//引用外部变量的声明
extern unsigned charkey_val;
externunsigned char key_Flag;
unsigned longDianliu2,Dianliu3;
uint Dianliu1,zheng,daxiao,com,VV;
uchar dianliu1[10],dianliu2[10],display[10];//display要求输出的电流,dianliu2实际输出的电流,dianliu1键入的电流
uint z,y,h,q,j,k,a;
uint n,nn,m,mm;//电流值的位数(整数部分,小数部分)
uintd,dd;//小数点标志1为有小数
//0为没小数
void main(void)
{
z=1;//按键后清除,重新输入标志
y=0;//y字符数字转整型数字(使用后归零)
h=0;//0,1确认键标志符0:未按过;1按过
q=0;//DA转换结果输出位数
j=0;//AD输出位
k=0;//AD转换结束位
a=0;//AD显示取平均
n=0;
nn=0;
m=0;
mm=0;
d=0;
dd=0;
Dianliu1=0;
Dianliu2=0;
Dianliu3=0;
zheng=0;
daxiao=0;
com=0;
VV=0;
WDTCTL=WDTPW +WDTHOLD;//关闭看门狗
Init_Keypad();
LcdReset();
DispNChar(0,0,31,Strings);
//AD初始化
P6SEL |= 0x01; // 使能ADC通道
ADC12CTL0=ADC12ON+SHT0_8+MSC+REFON+REF2_5V;
ADC12CTL1 = SHP+CONSEQ_2;;
ADC12MCTL0 = SREF_1;
ADC12IE= 0x01;//使能ADC中断
_EINT();
while(1)
{
Key_Event();
//电流实时检测
if(h==1){
ADC12CTL0|=ENC;// 使能转换
ADC12CTL0 |= ADC12SC; //开始转换
while(k==0);
k=0;
if(q==1)
{
if(Dianliu2<VV)
{
if(com<2400)com=com+1;
}
else if(Dianliu2>VV)
{
if(com>0)com=com-1;
}
if(com<2400)Write_A_B(com,0x0000,1,0); //A通道,慢速模式
}
//调整da的输出,注意是否接入负载,有电流
/*int qwe;
qwe=Dianliu2%100/10;
Disp1Char(0,1,shuzi[qwe]);*/
}
if(key_Flag ==1)
{
key_Flag= 0;
if((key_val!=0)&&(z==1))
{
LcdWriteCommand(0x01, 1);
DispNChar(14,0,2,ceshi5);
DispNChar(8-(m+n+d+1)/2,0,n +m+d,dianliu1);
z=0;//显示清屏(z清屏标志)
}
elseif((key_val!=0)&&(z==2))
{
LcdWriteCommand(0x01, 1);
DispNChar(0,0,2,ceshi3);
DispNChar(2,0,nn+2*mm,display);
DispNChar(8,0,2,ceshi4);
DispNChar(14,1,2,ceshi5);
DispNChar(8-(m+n+d+1)/2,1,n+m+d,dianliu1);
z=0;
}
switch(key_val) ﻩ
{
ﻩcase1:
Init_Keypad();
LcdReset();
DispNChar(0,0,31,Strings);
Dianliu1=0;
Dianliu2=0;
Dianliu3=0;
zheng=0;
daxiao=0;
z=1;
y=0;
n=0;
m=0;
h=0;
d=0;
a=0;
nn=0;
mm=0;
dd=0;
com=0;
VV=0;
q=0;
j=0;//AD输出位
k=0;//AD转换结束位
Write_A_B(com,0x0000,1,0); //A通道,慢速模式
break;ﻩﻩﻩﻩﻩ
case 2:
if((n<3&&d==0)||(m<1&&d ==1))
{
shuzishuru(9);
break;
}
else break;
case3:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(8);
break;
}
else break;
case 4:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(7);
break;
}
else break;
case5://小数点
if(d==0)
{d=1;
if(n!=0) dianliu1[n]='.';
else
{
dianliu1[n]='0';
n++;
dianliu1[n]='.';
}
if(h==0)
{
DispNChar(8-(m+n+d+1)/2,0,n+m+d,dianliu1);
DispNChar(14,0,2,ceshi5);
}
elseDispNChar(8-(m+n+d+1)/2,1,n+m+d,dianliu1);
break;
}ﻩ
else break;
ﻩﻩﻩcase 6:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(6);
break;
}
elsebreak;
case7:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(5);
break;
}
else break;
case 8:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(4);
break;
}
elsebreak;
case 9://清除
if((n!=0)&&(d==0))//清除整数
{
y=dianliu1[--n]-'0';
Dianliu1= (Dianliu1-y)/10;
y=0;
if(h==0){
LcdWriteCommand(0x01,1);
DispNChar(14,0,2,ceshi5);
Di
spNChar(8-(m+n+d+1)/2,0,n+m+d,dianliu1);
}
else{
LcdWriteCommand(0x01,1);
DispNChar(0,0,2,ceshi3);
DispNChar(2,0,nn+
2*mm,display);
DispNChar(8,0,2,c eshi4);
DispNChar(14,1,2,ceshi5);
DispNChar(8-
(m+n+d+1)/2,1,n+m+d,dianliu1);
}
}
else if((d!=0)&&(m!=0))//清除小数
{
y=dianliu1[m+n]-'0';
Dianliu1=(Dianliu1-y)/10;
m--;
y=0;
if(h==0){
LcdWriteComman
d(0x01, 1);
DispNCh
ar(14,0,2,ceshi5);
DispNChar(8-(m+n+d+1)/2,0,n+m+d,dianliu1);
}
else{
LcdWriteCommand(0x01, 1);
DispNChar(0,
0,2,ceshi3);
DispNChar(2,0,nn+2*mm,display);
DispNChar(8,0,2,ceshi4);
DispNC
har(14,1,2,ceshi5);
DispNChar(8-(m+
n+d+1)/2,1,n+m+d,dianliu1);
}
}
else if((d!=0)&&(m==0))//清除小数点
{
d=0;
if(h==0){
LcdWriteCommand(0x01, 1);
DispNChar(14,0,2,ceshi5);
DispNChar(8-
(m+n+d+1)/2,0,n+m+d,dianliu1);
}
else{
LcdWriteComman d(0x01, 1);
DispNChar(0,0,2,ces hi3);
DispNCha
r(2,0,nn+2*mm,display);
DispNChar(8,0,2,ceshi4);
DispNChar(14,1,2,ceshi5);
DispNChar(8-(m+n+d+1)/2,1,n+m+d,dianliu1);
}
}
else
{DispNChar(4,1,7,
ceshi1);
if(h==0)z=1;
else z=2;
}
break;
case10:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(3);
break;
}
elsebreak;
case 11:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(2);
break;
}
else break;
case 12:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(1);
break;
}
elsebreak;
case 13://确定
if((n!=0))
{
if(m==0)daxiao=Dianliu1*10;
elsedaxiao=Dianliu1;
if(daxiao>1000){
DispNChar(0,1,16,ceshi2);
m=0;
n=0;
d=0;
Dianliu1=0;
dianliu1[0]='\0';
if(h==1)z=2;
elsez=1;
break;
}
h=1;//确认标志
mm=m;nn=n;dd=d;
zheng=daxiao;
for(y=0;y<(n+m+d);y++) display[y]=dianliu1[y];
y=0;
m=0;
n=0;
d=0;
Dianliu1=0;
dianliu1[0]='\0';
LcdWriteCommand(0x01, 1);
DispNChar(0,0,2,ceshi3);
DispNChar(2,0,nn+2*mm,dis play);
DispNChar(8,0,2,ceshi4);
DispNChar(13,1,2,ceshi5);
// ADC12CTL0 |= ENC;
// 使能转换
// ADC12CTL0|= ADC12SC;
// 开始转换
}
break;
case14://暂停//jia
if(h==1)
{
VV=0;
com=(uint)(VV*2);//com =(uint)(VV/(2*REF)*4096);
Write_A_B(com,0x0000,1,0); //A通道,慢速模式
q=0;//转换输出确认位置
0
break;
}
else break;
case 15://输出//jian
if(h==1)
{
VV=zheng;
com=(uint)(VV*2);//com=(uint)(VV/(2*REF)*4096);
if(com<2400)Wr
ite_A_B(com,0x0000,1,0);//A通道,慢速模式
q=1;//转换输出确认位
break;
}
else break;
case16:
if((n<3&&d==0)||(m<1&&d==1))
{
shuzishuru(0);
break;
}
else break;
}
}
}
}
void shuzishuru(uintshuzi)//数字输入
{
dianliu1[n+m+d]='0'+shuzi;
Dianliu1=10*Dianliu1+shuzi;
if(d==0)n++;
elsem++;
if(h==0)
{
DispNChar(8-(m
+n+d+1)/2,0,n+m+d,dianliu1);
DispNChar(14,0,2,ceshi5);
}
else DispNChar(8-(m+n+d+1)/2,1,n+m+d,dianliu1);
}
/*******************************************
AD模块
函数名称:Trans_val
功能:将16进制ADC转换数据变换成三位10进制真实的模拟电压数据,并在液晶上显示
参数:Hex_Val--16进制数据
n--变换时的分母等于2的n次方
返回值:无
********************************************/ voidTrans_val(uintHex_Val)
{
uchar i;
Dianliu2 = Hex_Val;
Dianliu2 =(Dianliu2*2500)/4096;
Dianliu2=Dianliu2%10000;
//caltmp=2*caltmp;
j++;
Dianliu3=Dianliu3+Dianliu2;
a++;
if(j==300)
{Dianliu3=Dianliu3/a;
dianliu2[0] =Dianliu3%10000/1000;
dianliu2[1] =Dianliu3%1000/100;
dianliu2[2] =Dianliu3%100/10;
dianliu2[3]= 10;
dianliu2[4]=Dianliu3%10;
for(i =0;i <5;i++)
Disp1Char((10 + i),0,shuzi[dianliu2[i]]);
j=0;
}
k=1;
if(a==30)
{a=0;
Dianliu3=0;
}
ADC12CTL0&= ~ENC; //关使能转换}
/*******************************************
函数名称:ADC12ISR
功能:ADC中断服务函数,在这里用多次平均的
计算P6.0口的模拟电压数值
参数:无
返回值:无
********************************************/
#pragmavector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{
staticuintindex = 0;
results[index++] = ADC12MEM0; // Moveresults if(index == Num_of_Results)
{
uchari;
unsigned longsum = 0;
index = 0;
for(i =0; i< Num_of_Results;i++)
{
sum += results[i];
}
sum>>= 5; //除以32
Trans_val(sum);
}
}
/*********************
DA模块
**********************/
voidDA_conver(uint dig)
{
uchari=0;
P1DIR=BIT0+BIT1+BIT2; //数据线(BIT0=Din),时钟(BIT1=SCLK),片选(BIT2=CS)
P1OUT|=BIT1;//时钟SCLK=1;
P1OUT&=~BIT2; //片选有效
for(i=0;i<16;i++) //写入16 bit的控制位与数据
{
if(dig&0x8000)
P1OUT|=BIT0;
else
P1OUT&=~BIT0;
P1OUT&=~BIT1; //时钟SCLK=0;
_NOP();
_NOP();
dig=dig<<1;
P1OUT|=BIT1;//时钟SCLK=1;
_NOP();
_NOP();
}
P1OUT|=BIT1; //时钟SCLK=1;
P1OUT|=BIT2;//片选无效
}
void Write_A_B(uintdata_a,uint data_b,uchar channal,uchar model)//模式、通道选择并进行DA转换
//data_aA通道转换的电压值
//mode 转速控制
{
uint temp;
if(model)
temp=0x4000;
else
temp=0x0000;
switch(channal)
{
case1: //选A通道DA_conver(temp|0x8000|(0x0fff&data_a));
break;
case 2: //选B通道DA_conver(temp|0x0000|(0x0fff&data_b));
break;
case3: //选A&B通道DA_conver(temp|0x1000|(0x0fff&data_b));
DA_conver(temp|0x8000|(0x0fff&data_a));
break;
default:
break;
}
}。