华佗小知识
您的当前位置:首页基于C8051F350的称重系统软件设计

基于C8051F350的称重系统软件设计

来源:华佗小知识
常州工学院毕业设计论文 摘 要

随着对称重仪表的准度、精度、速度的要求越来越高,快速发展的单片机被运用到其中并逐步形成了一套集称重、处理、显示、和监控的电子称重系统。本文介绍了电子称重系统的工作原理、硬件电路设计,重点介绍了软件设计。本系统在设计中紧密结合市场需求,参考了国内著名的称重仪器生产商的产品,并且在功能设计上进行了一些新的改进。本系统采用目前使用最广泛、技术较为成熟的SOC单片机C8051F350作为控制核心,实现了自动采样、处理、显示功能,并能通过异步串行口与上位机通信。其中测量功能由以MAVIN足立NA2型传感器为核心的传感器电路、以OPA27为核心的放大电路和单片机内部的24位A/D转换实现;显示电路采用LCD显示。整个系统具有精确、快捷、方便、实用的显著特点

关键词: 称重系统;C8051F350;传感器;A/D转换;LCD

I

常州工学院毕业设计论文 ABSTRACT

With the more and more higher request of the accuracy, precision and speed of weighing instrument, the singlechip with rapidly development is applied and a suit of electronic weighing system including weighing, processing, displaying and monitoring has been formed gradually. This text introduces the work principle, the hardware electronic circuit design, especially the software design of the electronic weighing system. During the process of design, the demand of market was especially noticed, many products of domestic famous weighing instrument producer were consulted and some new improvements were made on the function design. The system uses SOC SCM C8051F350 which is most extensively applied currently and relatively mature on techinique as the core of control, realizing the function of sampling, processing and displaying automatically, and can communicate with epigyny computer through the asynchronous serial port. Thereinto the measure is completed by sensor circuit based on MAVIN NA2 sensor, amplification circuit based on OPA227 and A/D converter in C8051F350, the LCD is applied in displaying circuit, which makes the whole system has the marked characteristics of precise, fast, convenience and applied.

Keyword: weighing system; C8051F350;Sensor;A/D conversion;LCD

II

常州工学院毕业设计论文 目 录

摘 要 ............................................................................................................................. I ABSTRACT .................................................................................................................. II 第一章 绪 论 .............................................................................................................. 1 1.1 课题来源 ............................................................................................................. 1 1.2 课题研究的目的和意义 ..................................................................................... 1 1.3 国内外现状 ......................................................................................................... 2 1.4 论文的主要内容 ................................................................................................. 2 第二章 设计要求 ........................................................................................................ 3 2.1总体要求 .............................................................................................................. 3 2.2性能指标 .............................................................................................................. 3 2.3本章小结 .............................................................................................................. 3 第三章 硬件设计 ........................................................................................................ 4 3.1 仪器功能简介 ..................................................................................................... 4 3.2 硬件设计 ............................................................................................................. 4 3.2.1系统原理框图 ............................................................................................... 4 3.2.2电路分析 ....................................................................................................... 4 3.3 本章小结 ........................................................................................................... 10 第四章 系统软件设计 .............................................................................................. 12 4.1主程序的设计 .................................................................................................... 12 4.2子程序的设计 .................................................................................................... 13 4.2.1时钟初始化子程序 ..................................................................................... 13 4.2.2 I/O端口初始化子程序 .............................................................................. 18 4.2.3 A/D转换初始化子程序 ............................................................................. 22 4.2.4 A/D转换子程序 ......................................................................................... 29 4.2.5显示子程序 ................................................................................................. 33 4.2.6异步串行口初始化子程序 ......................................................................... 40 4.2.7按键子程序 ................................................................................................. 44 4.3本章小结 ............................................................................................................ 45 第五章 软件仿真 ...................................................................................................... 46 5.1仿真软件的介绍 ................................................................................................ 46 5.2仿真画面的介绍 ................................................................................................ 46 5.3本章小结 ............................................................................................................ 50

III

常州工学院毕业设计论文 结 论 ........................................................................................................................ 51 参考文献 ...................................................................................................................... 52 致 谢 ........................................................................................................................ 54 附 录 ........................................................................................................................ 55

IV

常州工学院毕业设计论文 第一章 绪 论

1.1 课题来源

随着科学技术和经济的发展,出售商品品种的增加,称量物品的设备也需要更新换代,人们对称重装置的要求也越来越高。传统的机械式称重装置正在被电子称重装置所代替,从而进入到传感器、电子学和微处理机领域,使得称重装置变成为电子仪器。它的特点是:精确、智能、简明、可靠,克服了传统的杆秤、盘秤不精确、速度慢、不能计价、易作弊等缺点,在商业领域应用越来越多。

称重技术的突破是微处理机的应用。称重技术的这种发展是由于不仅要求获得静态称重数据,而且进一步要求称重工作的自动化,实现快速称量,以及测量各种动态参数,提高测量精度和各种数据的及时处理。这些精度、速度、性能和功能方面的要求是传统的机械测量系统无法满足的。也就是说,这种技术发展中的突破是必然的结果。

通常称量物体采用的是直读法,该测量方法应用到称重装置上为:通过测量弹性元件的变形来测定被测物体的重量,结构简单,操作方便,但精度较低。因此我们对弹性元件变形量进行信号放大处理,通过微处理机对其进行量度分割,从而提高其精度。

随着电子元器件集成化的迅速发展,微处理机、单片机的发展和计算机软件的开发使得不仅实验室的传统称量装置已被电子称重装置所取代,而且这种趋势已经扩展到工业和其他领域。

1.2 课题研究的目的和意义

目前,电子称重仪的应用范围越来越广泛,同时对电子称重仪的技术要求也越来越高,电子称重仪由一个单一的称重装置逐渐发展成一个集称重、自动控制和信息处理等为一体的综合性的称重系统。本课题研究的目的是设计一种集称重、显示以及能够与上位机监控的电子称重系统,利用精确A/D型SOC单片机C8051F350为核心,配以数据采集、显示、按键、串口等外围电路,达到测量精确快速、操作方便的目的,同时可以通过异步串口与上位机通讯,达到监控和问题反馈的目的,真正使称重装置变为一个有机可靠的系统。本设计的意义在于规范了计量市场,有效地提高了称重的快速有效性,并将称重装置纳入市场管理系

1

常州工学院毕业设计论文 统,有效地对计量过程实施监控,保证了交易的真实性和公平性。

1.3 国内外现状

50年代中期电子技术的渗入推动了衡器制造业的发展。60年代初期出现机电结合式电子衡器以来,经过40多年的不断改进与完善,我国电子衡器从最初的机电结合型发展到现在的全电子型和数字智能型。我国电子衡器的技术装备和检测试验手段基本达到国际90年代中期的水平。电子称重技术从静态称重向动态称重发展;计量方法从模拟测量向数字测量发展;测量特点从单参数测量向多参数测量发展,特别是对快速称重和动态称重的研究与应用。但就总体而言,我国电子衡器产品的数量和质量与工业发达国家相比还有较大差距,其主要差距是技术与工艺不够先进、工艺装备与测试仪表老化、开发能力不足、产品的品种规格较少、功能不全、稳定性和可靠性较差等。

通过分析近年来电子衡器产品的发展情况及国内外市场的需求,电子衡器总的发展趋势是小型化、模块化、集成化、智能化;其技术性能趋向是速率高、准确度高、稳定性高、可靠性高;其功能趋向是称重计量的控制信息和非控制信息并重的“智能化”功能;其应用性能趋向于综合性和组合性。

1.4 论文的主要内容

本课题研究的是电子称重系统,包括硬件部分和软件部分,本论文主要研究的是软件部分。本课题使用精确A/D型SOC单片机C8051F350进行数据的采集,处理,在硬件电路设计的基础上运用C语言进行编程。在论文的第一章介绍了课题的来源及相关背景;第二章明确了本设计的设计要求;第三章简要叙述硬件电路的设计及相关原理;第四章则是论文的重点,首先从整体构建程序总体框架,再按局部子程序一一详细介绍,包括称重子程序,显示子程序,按键子程序,串口通信子程序等;第五章阐述了软件仿真过程;结论部分对设计进行了总结和展望;附录附带电路图和详细程序。

2

常州工学院毕业设计论文 第二章 设计要求

2.1总体要求

称重系统以C8051F350为核心,应变片传感器接收压力输入信号经放大、滤波、A/D转换、A/D处理,最后由LCD输出显示。系统具备清零、去皮、防止死机、干扰、串口输出功能。要求做到精准、方便、稳定、智能、性价比高。

2.2性能指标

去皮和清零功能 LCD显示

测量范围:0-50kg 最小分度值:0.01Kg 电源: 220V±10%

2.3本章小结

本章主要是明确了电子称重系统的各项功能,以及确定各项性能指标,为硬件设计确立设计方案和标准,也为仿真效果提供了依据。

3

常州工学院毕业设计论文 第三章 硬件设计

3.1 仪器功能简介

本称重系统操作方便,人机间互动主要依靠按键和LCD显示屏。操作过程如下:上电后系统复位,放上托盘,也就是我们所说的“皮”,按下去皮按键,由于误差原因显示会接近0,此时再按下清零键,显示为零,通过两次校准保证了称重的精确。然后放上所称重物(本设计要求重量范围在0-50Kg),此时重量会显示在LCD屏上,如果有必要还可以外接PC机进行串口通信。称完后拿下重物再按清零键即可进行下一次测量,如在称量过程中发生故障,我们还配置了外部复位按键,以复位重新启动系统。

3.2 硬件设计

3.2.1系统原理框图

硬件电路按照模块化设计方法设计,主要包括单片机电路、传感器电路、A/D放大电路、显示电路、电源稳压电路、串口通信电路等。系统原理框图如图3-1所示。

稳压电源试样重物传感器模拟放大A/D转换单片机驱动LCD上位机按键

图3–1 称重系统原理框图

3.2.2电路分析

一、单片机电路

本设计采用SOC单片机C8051F350,芯片的各主要引脚分配如下:

4

常州工学院毕业设计论文 引脚 P0.0 P0.2 P0.3 P0.4 P0.5 P0.6 P0.7 二、传感器电路

说明 上电指示灯 外部时钟输入 外部时钟输出 串行通信TXD 串行通信RXD 显示驱动/CS 显示驱动/RD 引脚 P1.0 P1.1 P1.2 P1.3 AIN0.0 AIN0.1 说明 显示驱动/WR 显示驱动DATA 去皮按键 清零按键 模拟输入+ 模拟输入- 传感器采用电阻应变片,利用电桥平衡原理进行压差的采样,因为电桥测量不仅可以提高检测灵敏度,还能获得较为理想的温度补偿效果,减小和克服非线性误差。

直流电桥电路如下图所示:

AR1CR3BR2+uA-R4 D

图3-2 直流电桥电路 四个电阻两两串联,接点A和B接直流电源E。根据串联电路电阻分压关系,得C、D两点的电压分别为: VC=

R1R1R3E,VD=

R2R4R2E

电桥的输出电压为:UoutVCVDR1R4R2R3

R2R4R1R3U电桥的平衡条件是:R2R3R1R4。当电桥平衡时,输出电压为零。

根据本仪器的设计精度要求,我们选择MAVIN足立NA2称重传感器。 惠斯登电桥具有很多优点,如可以抑制温度变化的影响,可以抑制侧向力干扰,可以比较方便的解决称重传感器的补偿问题等,所以惠斯登电桥在称重传感

5

常州工学院毕业设计论文 器中得到了广泛的应用。又因为全桥式等臂电桥的灵敏度最高,各臂参数一致,各种干扰的影响容易相互抵消,所以称重传感器均采用全桥式等臂电桥。

+5V1R34R5R6R4+si2gUoy-sig

UOYE(R6R6R6R6R4R4图3-3 差动全桥电路 R5R5R5R5R3R3)3

若R3UOYR4R5R6R3R3,R3R4R5R6R3R3,则:

)

E(R3R3R3R3R3R32R3R3R32R3R3R3R3R3R3R3E()E

三、A/D放大电路

图3-4 仪表放大电路 传感器测量的电压信号经常含有干扰信号,所以当差分电压输出时,在其前面加一个LC滤波电路,抑制了电源对传感器的噪声干扰,得到比较稳定的差分

6

常州工学院毕业设计论文 信号。再通过一个2通道模拟多路分配器接入运放的同相输入端放大。由于系统连续工作电压信号会随着温度的变化而发生漂移,为了防止温漂导致的电压失真,在差分信号的两端加接通道多路器74HC4053,当电压随温度往上变化时,74HC4053就把其信号变反,这样电压信号就会成锯齿形稳定在真实电压值附近,从而保证了信号的准确。如图3-4所示,R8、R9、R10电阻使用了精度高、温度系数稳定的精密电阻,从而减小因放大产生的干扰。

电阻应变片式传感器输出电压为mv数量级,因此必须加放大电路。根据差

2R分电路的原理Uout(19)UinR8。

传感器称重量程100Kg,灵敏2mv/v,供桥电压为5v,满量程输出就为10mv。现称重物体为最重50Kg,则最多输出5mv电压。ADC的参考电压为2.5V,为留有余量使50Kg对应2V,所以要使输出电压从0-5mv放大到0-2V,放大倍数为

2V5mV400。

本系统的放大电路用了专用的仪表放大器,其优点是: 1、单片机内部的运放不是很稳定,容易造成偏差。

2、内部的运放最大增益为128,而现在所要求的放大倍数要达到400,不能满足放大的要求。故采用外部的运算放大器。

传感器满量程输出=传感器额定输出激励电压=2mV/V5V=10mV=10000μV。 微伏/分度=传感器满量程输出分度值传感器总容量=

100000.011001.0(V/d)

查灵敏度表,对应于5000分度数,其灵敏度允许范围为0.6-5.2,符合灵敏度要求。 四、显示电路

本设计中我们采用LCD显示,显示的驱动芯片采用HT1621B。

7

常州工学院毕业设计论文

图3-5 LCD显示电路

HT1621B是一种128点阵式存储器映射多功能LCD驱动电路,它适合点阵式LCD显示,包括LCD模块和显示子系统,具有关闭电源功能。硬件接线中重点关心以下引脚:

名称 /CS I/O I 功能说明 片选信号输入端(带上拉电阻)。为逻辑高电平时,数据和命令不能读出和写入,并且串行接口电路复位。为逻辑低电平时,控制器与HT1621B间可以传数据和命令。 /RD I READ时钟输入端(带上拉电阻)。RAM中的数据在/RD信号的下降沿被输出到DATA线上,主控制器可以在下一个上升沿锁存这个数据。 WR I WRITE 时钟输入(带上拉电阻)。在/WR信号的上升沿,DATA线上的数据被锁存到HT1621B。 DATA COM0~COM3 SEG0~SEG31

I/O O O 串行数据输入/输出端(带上拉电阻)。 LCD COM输出端。 LCD SEG输出端。 8

常州工学院毕业设计论文 五、电源电路设计

图3-6电源电路 本设计采用的芯片需要的供电电压有2.5V,3.3V和5V三种,主要采用小功率电源调整芯片MIC5205产生2.5V和5V电压,3.3V低压降调节器LP2981产生3.3V电压。

5V电压用MIC5205芯片产生,输入电压有波动时,为了使电路能稳定工作,在输入和输出部分分别接入电容C5、C8。C5为输入稳定电容,当稳压器输入阻抗降低时,防止发生振荡。C8为输出稳压电容,对于降低输出纹波、输出噪音及负载电流变化的影响有好的效果,C8的最大值为2.2μF太大的值会增加调节器的过度反应。C7作为滤波电容,C6的作用是减少相位失真,减小输出噪声。2.5V电压采用电阻分压的方式从MIC5205的输出得到,其中R1、R2电阻用1ppm的高精度电阻,这样能得到稳定的电压。3.3V电压用LP2981芯片产生,其工作原理与MIC5205相似。

9

常州工学院毕业设计论文 六、串口通信电路

图3-7串口通信电路

该称重系统还可以与上位机通信,这样系统还可以扩展功能,由上位机直接控制完成监控任务。与上位机的通信接口采用芯片MAX3221。MAX3221是3V至5.5V单通道RS-232线驱动器/接收器。该器件可满足TIA/EIA-232-F要求并在一个异步通信控制器和串行端口连接器之间提供接口电荷汞和四个小型外接电容器可在单路3V至5.5V电源电压下工作这些器件在数据信号率达到250 kbit/s且最大的30-V/s驱动输出回转率时工作。

当串行端口失效时,可对电压管理进行灵活的控制选择。在FORCEON为低且FORCEOFF为高时自动掉电功能起作用。在这种工作方式中,若器件未感应到接收器输入端上的一个有效的RS-232信号,则驱动器输出端被禁止。若FORCEOFF置为低且EN为高,则驱动器和接收器均被切断,电源电流降至1μA。断开串行端口或关闭外围驱动器将会导致自动掉电。当FORCEON和FORCEOFF为高时,自动掉电被禁止当自动掉电被使能且在接收器输入端加一个有效信号时器件被激活。无效INVALID输出告知用户查看RS-232信号是否加在接收器输入端。如果接收器输入端电压高于2.7V或低于–2.7V或在+0.3V之间并持续少于30μs,INVALID为高数据有效;如果接收器输入端电压在+0.3V之间并持续超过30μs,则INVALID为低数据无效。

3.3 本章小结

本章首先介绍了本称重系统的实际使用方法,接着通过原理框图明确了设计方案和工作原理。根据模块化的设计方法,重点对单片机电路、传感器电路、A/D

10

常州工学院毕业设计论文 放大电路、显示电路、电源稳压电路、串口通信电路等进行了介绍,明确了本系统硬件中使用的各种芯片,尤其是核心控制部件C8051F350的各端口的分配,为软件设计做好了准备。

11

常州工学院毕业设计论文 第四章 系统软件设计

4.1主程序的设计

本设计的主程序是由各个子程序模块构成的。系统上电后,首先对系统进行初始化,由于C8051F350是SOC单片机,它较MCS51系列单片机的一大特点是将很多外设或功能部件都嵌入其中,如本设计用到的24位ADC、增强型UART、时钟振荡器等,因而对这些外设、功能部件以及端口引脚的初始化比MCS51系列单片机更为复杂,也至关重要,在初始化中主要是对各部件进行模式配置以及根据前述硬件设计对I/O端口进行分配。完成初始化后,放上托盘,进行去皮以去掉托盘的重量,但由于去皮是粗略的减掉托盘重,由于零点漂移此时显示并不为零,为了使称重更精确还要进行清零。然后放上重物,系统开始采集数据,采集完一定的数据值后取平均值,对数据进行处理即将A/D转换得来的数字量转化为显示模量为显示作准备,接着调LCD显示子程序显示。如果有必要进行串口通讯则进入串口通讯子程序,否则检测是否清零进入下一次称重。

主程序流程图如下:

12

常州工学院毕业设计论文 开始初始化去皮清零N数据采集完?Y数据处理显示要串口通讯?Y串口通讯NY清零键按下?结束

图4–1 主程序流程图

4.2子程序的设计

系统控制程序设计是按照结构化的程序设计方法设计,将整个程序细分为:时钟初始化子程序、I/O端口初始化子程序、A/D转换初始化子程序、A/D转换子程序、显示子程序、异步串口初始化子程序、按键子程序等, 以方便调试与检查。

4.2.1时钟初始化子程序

时钟初始化子程序SYSCLK_Init用于初始化系统时钟,用外部24.5MHz振荡器作为时钟源,并使用时钟乘法器产生一个外部振荡器x2即49MHz的系统时钟,并且使能时钟丢失检测器。

13

常州工学院毕业设计论文 C8051F350有一个可编程内部振荡器、一个外部振荡器驱动电路和一个时钟乘法器。可以通过对OSCICN寄存器编程来使能/禁止内部振荡器。系统时钟(SYSCLK)可以由内部振荡器、外部振荡器电路或时钟乘法器提供。时钟乘法器有三种可能的输出:内部振荡器×2、外部振荡器×2或内部振荡器×4。

OSCICN:内部振荡器控制寄存器

IOSCEN IFRDY - - - - IFCN1-0 IOSCEN:内部振荡器使能位(0:内部振荡器禁止。1:内部振荡器使能。) IFRDY:内部振荡器频率准备好标志(0:内部振荡器未运行在编程频率。1:内部振荡器按编程频率运行。)

IFCN1-0:内部振荡器频率控制位(00:SYSCLK为内部频振荡器8分频。01:SYSCLK为内部振荡器4分频。 10:SYSCLK为内部振荡器2分频。 11:SYSCLK为内部振荡器输出)

外部振荡器电路可以驱动外部晶体、陶瓷谐振器、电容或RC网络。必须在OSCXCN寄存器中选择外部振荡器类型,还必须正确选择频率控制位XFCN。当使用外部振荡器电路时,必须对所用端口引脚进行配置。当外部振荡器电路被配置为晶体方式时,端口引脚P0.2和P0.3分别被用作XTAL1和XTAL2。端口I/O交叉开关应被配置为跳过被振荡器占用的引脚。当在晶体方式使用外部振荡器电路时,应将所用的端口引脚配置为模拟输入。

应从OSCXCN寄存器中的晶体列选择外部振荡器频率控制值,在晶体振荡器被使能时,振荡器幅度检测电路需要一个建立时间来达到合适的偏置。在使能晶体振荡器和检查XTLVLD位之间引入1ms的延时可以防止提前将系统时钟切换到外部振荡器。步骤如下:

14

常州工学院毕业设计论文 开始 强制XTAL1和XTAL2为低设置XTAL1和XTAL2为模拟输入使能外部振荡器等待至少1msXTLVLD=1?Y系统时钟切换到外部振荡器N结束

图4–2 晶体振荡器初始化流程图

OSCXCN:外部振荡器控制寄存器

XTLVLD XOSCMD2-0 - XFCN2-0 XTLVLD:晶体振荡器有效标志(0:晶体振荡器未用或未稳定。 1:晶体振荡器正在运行并且工作稳定。)

XOSCMD2-0:外部振荡器方式位(00x:外部振荡器电路关闭。 010:外部CMOS时钟方式。 011:外部CMOS时钟方式二分频。 100:RC振荡器方式。 101:电容振荡器方式。 110:晶体振荡器方式。 111:晶体振荡器方式二分频。) XFCN2-0:外部振荡器频率控制位 XFCN 晶体(XOSCMD=11x) 000 001 f ≤ 32kHz 32kHz < f ≤ 84kHz RC(XOSCMD=10x) f ≤ 25kHz 25kHz < f ≤ 50kHz 50kHz < f ≤ 100kHz 100kHz < f ≤ 200kHz 200kHz < f ≤ 400kHz 400kHz < f ≤ 800kHz C(XOSCMD=10x) K因子= 0.87 K因子= 2.6 K因子= 7.7 K因子= 22 K因子= 65 K因子= 180 010 84kHz < f ≤ 225kHz 011 225kHz < f ≤ 590kHz 100 590kHz < f ≤ 1.5MHz 101 1.5MHz < f ≤ 4MHz 15

常州工学院毕业设计论文 110 111 4MHz < f ≤ 10MHz 10MHz < f ≤ 30MHz 800kHz < f ≤ 1.6MHz 1.6MHz < f ≤ 3.2MHz K因子= 6 K因子= 1590 时钟乘法器产生一个4倍于输入时钟频率的输出时钟。时钟乘法器的输入可以从外部振荡器、内部振荡器/2或外部振荡器/2中选择。因此有三种可能的输出,内部振荡器×2、外部振荡器×2或外部振荡器×4。

时钟乘法器用CLKMUL寄存器配置。配置和使能时钟乘法器的过程如下:

开始复位时钟乘法器选择时钟乘法器输入使能时钟乘法器延时大于5μs初始化时钟乘法器MULRDY=1?Y结束N

图4–3 时钟乘法器初始化流程图

当使用外部振荡器作为时钟乘法器的输入时,外部源必须在时钟乘法器被初始化之前被使能并稳定

CLKMUL:时钟乘法器控制寄存器

MULEN MULINIT MULRDY - - - MULSEL 1-0 MULEN:时钟乘法器使能位(0:时钟乘法器被禁止。1:时钟乘法器被使能。) MULINIT:时钟乘法器初始化位(在时钟乘法器被使能时,该位应为‘0’。时钟乘法器被使能后,向该位写‘1’对时钟乘法器初始化。当时钟乘法器稳定后,MULRDY的读出值为‘1’。)

MULRDY:时钟乘法器准备好标志(0:时钟乘法器未准备好。 1:时钟乘法器准备好。)

16

常州工学院毕业设计论文 MULSEL:系统时钟源选择位

MULSEL 00 01 10 11 输入时钟 内部振荡器/2 外部振荡器 外部振荡器/2 保留 时钟乘法器输出 内部振荡器×2 外部振荡器×4 外部振荡器×2 保留 外部晶体谐振器通常需要较长的起动时间,应待其稳定后方可用作系统时钟。当外部振荡器稳定后,晶体有效标志(寄存器OSCXCN中的XTLVLD)被硬件置‘1’。在晶体方式,为了防止读到假XTLVLD标志,软件在使能外部振荡器和检查XTLVLD之间至少应延时1ms。

寄存器CLKSEL中的CLKSL[1:0]位选择用作系统时钟的振荡器。系统时钟可以在内部振荡器、外部振荡器及时钟乘法器之间自由切换,只要所选择的时钟源被使能并稳定运行。

CLKSEL:时钟选择寄存器

- - - - - - CLKSL 1-0 CLKSL[1:0]:系统时钟选择位。(00:内部振荡器。01:外部振荡器。10:时钟乘法器。11:保留。)

时钟丢失检测器(MCD)是由系统时钟触发的单稳态电路。如果系统时钟保持在高电平或低电平的时间大于100微秒,单稳态电路将超时并产生复位。在发生时钟丢失检测器复位后,MCDRSF标志(RSTSRC.2)的读出值为‘1’,表示本次复位源为MCD;否则该位读出值为‘0’。向MCDRSF位写‘1’将使能时钟丢失检测器;写‘0’将禁止时钟丢失检测器。/RST引脚的状态不受该复位的影响。

子程序如下:void SYSCLK_Init (void) {

int multiplier_delay;

OSCICN = 0x00; //禁止内部振荡源

OSCXCN = 0x67; //选择外部晶体振荡器方式, 10MHzfor(multiplier_delay=0;multiplier_delay<24400; multiplier_delay++)

{} //延时最少1ms

while (!(OSCXCN & 0x80)); //查询XTLVLD等待晶体振荡器准备好 CLKMUL = 0x00; //复位时钟乘法器

17

常州工学院毕业设计论文 CLKMUL &= ~0x01; //MULSEL = 10b,选择时钟乘法器输入为外部振荡器/2 }

CLKMUL |= 0x80; //使能时钟乘法器

for(multiplier_delay=0; multiplier_delay < 125; multiplier_delay++) {} //延时最少5us

CLKMUL |= 0xC0; //初始化时钟乘法器

while (!(CLKMUL & 0x20)); //查询MULRDY等待时钟乘法器准备好 RSTSRC = 0x04; //使能时钟丢失检测器

CLKSEL = 0x02; //选择时钟乘法器输出作为系统时钟

4.2.2 I/O端口初始化子程序

I/O端口初始化子程序PORT_Init用于设置交叉开关和通用端口I/O。 数字和模拟资源可以通过17个I/O引脚使用。端口引脚被组织为两个8位口和一个1位口。每个端口引脚都可以被定义为通用I/O(GPIO)或模拟输入。P0.0-P1.7可以被分配给内部数字资源。设计者完全控制数字功能的引脚分配,只受I/O引脚数的。 这种资源分配的灵活性是通过使用优先权交叉开关译码器实现的。不论交叉开关的设置如何,端口I/O引脚的状态总是可以被读到相应的端口锁存器。交叉开关根据优先权译码表为所选择的内部数字资源分配I/O引脚。寄存器XBR0和XBR1用于选择内部数字功能。

所有端口I/O都耐5V电压。端口I/O单元可以被配置为漏极开路或推挽方式(在端口输出方式寄存器PnMDOUT中设置,n = 0,1,2)。

优先权交叉开关译码器为每个I/O功能分配优先权,从优先权最高的UART0开始。当一个数字资源被选择时,尚未分配的端口引脚中的最低位被分配给该资源(但UART0总是被分配到引脚P0.4和P0.5)。如果一个端口引脚已经被分配,则交叉开关在为下一个被选择的资源分配引脚时将跳过该引脚。此外,交叉开关还将跳过在PnSKIP寄存器中被置‘1’的那些位所对应的引脚。PnSKIP寄存器允许软件跳过那些被用作模拟输入、特殊功能或GPIO的引脚。

如果一个端口引脚被一个外设使用而不经过交叉开关,则该引脚在PnSKIP寄存器中的对应位应被置‘1’。这种情况适用于P0.3和/或P0.2(用于外部振荡器)、P0.6(用于外部CNVSTR信号)、P1.6(用于IDA0)、P1.7(用于IDA1)和任何被选择的ADC或比较器输入。交叉开关跳过那些已经被分配的引脚,移向

18

常州工学院毕业设计论文 下一个未被分配的引脚。

寄存器XBR0和XBR1用于为数字I/O资源分配物理I/O引脚。当UART被选择时,交叉开关也为其分配两个引脚(TX和RX)。UART0的引脚分配是固定的(这是出于引导装入的目的):UART TX0总是被分配到P0.4;UART RX0总是被分配到P0.5。在优先功能被分配之后,标准端口I/O是连续的。

I/O端口初始化包括以下步骤:

开始选择端口输入方式选择端口输出方式选择应被交叉开关跳过的引脚分配引脚给外设使能交叉开关结束

图4–4 端口初始化程序流程图

所有端口引脚都必须被配置为模拟或数字输入。被用作ADC输入的任何引脚都应被配置为模拟输入。当一个引脚被配置为模拟输入时,它的弱上拉、数字驱动器和数字接收器都被禁止,这可以节省功耗并减小模拟输入的噪声。

此外,应将交叉开关配置为跳过所有被用作模拟输入的引脚(通过将 PnSKIP 寄存器中的对应位置‘1’来实现)。端口输入方式在 PnMDIN 寄存器中设置,其中‘1’表示数字输入,‘0’表示模拟输入。复位后所有引脚的缺省设置都是数字输入。I/O 引脚的输出驱动器特性由端口输出方式寄存器 PnMDOUT中的对应位决定,每个端口输出驱动器都可被配置为漏极开路或推挽方式。不管交叉开关是否将端口引脚分配给某个数字外设,都需要对端口驱动器的输出方式进行设置。

当XBR1寄存器中的WEAKPUD位为‘0’时,输出方式为漏极开路的那些引脚的弱上拉被使能。WEAKPUD不影响被配置为推挽方式的端口I/O。当漏极开路输

19

常州工学院毕业设计论文 出被驱动为逻辑‘0’时,弱上拉被自动关断(禁止)以避免不必要的功率消耗。

寄存器XBR0和XBR1必须被装入正确的值以选择所需要的数字I/O功能。置‘1’XBR1中的XBARE位将使能交叉开关。不管XBRn寄存器的设置如何,在交叉开关被使能之前,外部引脚保持标准端口I/O方式(输入)。

为使端口引脚工作在标准端口I/O输出方式,交叉开关必须被使能。当交叉开关被禁止时,端口输出驱动器被禁止。

XBR0:端口I/O交叉开关寄存器0

- - CP0AE CP0E SYSCKE SMB0E SPI0E URT0E CP0AE:比较器0异步输出使能位(0:CP0A不连到端口引脚.1:CP0A连到端口引脚P1.4。) CP0E:比较器0输出使能位(0:CP0不连到端口引脚。1:CP0连到端口引脚P1.5。) SYSCKE:/SYSCLK输出使能位(0:/SYSCLK不连到端口引脚; 1:/SYSCLK连到端口引脚。)

SMB0E:SMBus I/O使能位(0:SMBus I/O不连到端口引脚。 1:SMBus I/O连到端口引脚。)

SPI0E:SPI I/O使能位(0:SPI I/O不连到端口引脚。1:SPI I/O连到端口引脚。) URT0E:UART I/O使能位(0:UART I/O不连到端口引脚。1:UART TX0, RX0 连到端口引脚 P0.4 和 P0.5。)

XBR1:端口I/O交叉开关寄存器1

WEAKPUD XBARE T1E T0E ECIE - PCA0ME1-0 WEAKPUD:端口I/O弱上拉禁止位。(0:弱上拉使能。1:弱上拉禁止。) XBARE:交叉开关使能位(0:交叉开关禁止。1:交叉开关使能。) T1E:T1使能位(0:T1不连到端口引脚。1:T1连到端口引脚。) T0E:T0使能位(0:T0 不连到端口引脚。1:T0连到端口引脚。)

ECIE:PCA0外部计数输入使能位(0:ECI不连到端口引脚。1:ECI连到端口引脚。)

PCA0ME:PCA 模块 I/O 使能位(00:所有的PCA I/O都不连到端口引脚。01:CEX0连到端口引脚。10:CEX0、CEX1连到端口引脚。11:CEX0、CEX1、CEX2连到端口引脚)

未被交叉开关分配的端口引脚和未被模拟外设使用的端口引脚都可以作为通用I/O。通过对应的端口数据寄存器访问端口P0-P2,这些寄存器既可以按位寻址也可以按字节寻址。向端口写入时,数据被锁存到端口数据寄存器中,以保

20

常州工学院毕业设计论文 持引脚上的输出数据值不变。读端口数据寄存器(或端口位)将总是返回引脚本身的逻辑状态,而与XBRn的设置值无关,即使在引脚被交叉开关分配给其它信号时,端口寄存器总是读其对应的端口I/O引脚。但在对端口SFR执行下面的读-修改-写指令(ANL、ORL、XRL、JBC、CPL、INC、DEC、DJNZ)和对端口SFR中的某一位执行MOV、CLR、SETB期间例外。这些指令读端口寄存器(而不是引脚)的值,修改后再写回端口SFR。

P0:端口0寄存器

P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 P0.[7:0] 写 - 输出出现在 I/O 引脚。(0:逻辑低电平输出。1:逻辑高电平输出。若相应的P0MDOUT.n位 = 0,则为高阻态。)

读 - 读那些在P0MDIN中被选择为模拟输入的引脚时总是返回‘0’。被配置为数字输入时直接读端口引脚。(0:P0.n为逻辑低电平。1:P0.n为逻辑高电平。)

P0MDIN:端口0输入方式寄存器

P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 P0.7–P0.0:输入方式配置位(当端口引脚被配置为模拟输入时,其弱上拉、数字驱动器和数字接收器都被禁止。0:对应的P0.n引脚被配置为模拟输入。1:对应的P0.n引脚不配置为模拟输入。)

P0MDOUT:端口0输出方式寄存器

P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 P0.7–P0.0:输出方式配置位(分别对应)。如果P0MDIN寄存器中的对应位为逻辑‘0’,则输出方式配置为被忽略。(0:对应的P0.n输出为漏极开路。1:对应的P0.n输出为推挽方式。)

P0SKIP:端口 0 跳过寄存器

P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 P0SKIP.[7:0]:端口0交叉开关跳过使能位。这些位选择被交叉开关译码器跳过的端口引脚。作为模拟输入(ADC或比较器)或特殊功能(VREF输入、外部振荡器电路、CNVSTR输入)的引脚应被交叉开关跳过。(0:对应的P0.n不被交叉开关跳过。1:对应的P0.n被交叉开关跳过。)

P1(端口1寄存器)、P1MDIN(端口1输入方式寄存器)、P1MDOUT(端口1输出方式寄存器)、P0SKIP(端口1跳过寄存器)、P2(端口2寄存器)、P2MDOUT

21

常州工学院毕业设计论文 (端口2输出方式寄存器)也类似。

子程序如下:void PORT_Init (void) {

P0SKIP |= 0xCC; // 跳过P0.2、P0.3晶振引脚,P0.6、P0.7、P1.0、P1.1 P1SKIP |= 0x0F; // 显示引脚,P1.2、P1.3去皮和清零引脚 XBR0 = 0x01; // 使用串口UART0

XBR1 = 0x40; // 使用弱上拉电阻,使能交叉开关 P0MDOUT |= 0xDF; // 设置输出方式 }

4.2.3 A/D转换初始化子程序

A/D转换初始化子程序ADC0_Init用于设置采样速率、输出字速率、采样引脚等。

C8051F350内部有一个全差分24位Sigma-Delta模/数转换器,该ADC具有在片校准功能。两个的抽取滤波器可被编程到1KHz的采样率。可以使用内部的电压基准,也可以用差分外部基准进行比率测量。ADC0中包含一个可编程增益放大器,有8种增益设置,最大增益可达128倍。模拟多路选择器将ADC的差分输入与8个外部引脚及内部温度传感器相连。可以使用内部输入缓冲器为直接连接的变送器提供高输入阻抗。一个8位的偏移DAC允许修正较大的输入偏移电压。

通过将寄存器ADC0MD中的AD0EN位置‘1’来使能ADC0。ADC0在被禁止时处于低功耗关断方式(所有的时钟都被关断),以使功耗最低。除ADC0SM位外,ADC0在关断方式下保持其所有设置,ADC0SM位被复位到000b(空闲方式)。

ADC的电压基准由寄存器ADC0CF中的ADC0VREF选择。当ADC0VREF位被置‘1’时,ADC使用外部电压基准源;当ADC0VREF位被清‘0’时,ADC使用内部基准。

ADC的模拟输入被连接到器件的外部引脚或内部电压。模拟输入可以被配置为单端方式(相对与AGND来测量一个的输入)或差分方式(测量两个输入之间的差值)。

可编程增益放大器(PGA)对ADC输入进行放大, PGA增益设置由寄存器ADC0CN中的AD0GN位控制。

AIN+和AIN-之前有两个的输入缓冲器。每个输入都有一组(两个)缓

22

常州工学院毕业设计论文 冲器,可用于使ADC的输入电流最小(对于敏感的测量)。当绝对引脚输入电压位于测量范围的低半部分时使用“low” 输入缓冲器,当绝对引脚输入电压位于测量范围的高半部分时使用“high”输入缓冲器。输入缓冲器也可以被旁路,以便AIN+和AIN-与PGA输入直接相连。ADC输入缓冲器由ADC0BUF寄存器控制。

ADC0CLK寄存器保持调制器时钟(MDCLK)的分频数。调制器时钟决定ADC采样电容的开关频率。当MDCLK频率等于2.4576 MHz时,ADC的性能最佳。调制器以MDCLK/128的速率对输入信号采样。

ADC滤波器的抽取比由寄存器ADC0DECH和ADC0DECL中的DECI[10:0]位选择。抽取比等于1+DECI[10:0]。抽取比决定用多少个调制器采样值来生成一个输出字。ADC输出字的速率等于调制器采样速率除以抽取比。较高的抽取比会产生具有较低噪声的结果,但需要较长的转换周期。最小的抽取比为20。当使用快速滤波器输出时,抽取比必须被设置为8的整数倍。

可以使用内部或系统校准方式对ADC0的增益和偏移进行在系统校准。为保证校准精度,应先进行偏移校准,然后再进行增益校准。没有必要既进行内部校准又进行系统校准,因为系统校准会对任何内部误差源进行补偿。

偏移校准是进行一次单点测量,使一个输入电压产生零值的ADC输出。当执行一次偏移校准时,任何偏离零值的测量偏差都被保存到偏移寄存器中。进行ADC转换时,所有的转换结果都要减去该偏移值。

增益校准是进行两点测量,它决定ADC传输函数的斜率。当执行增益校准时,实际上只进行一次测量,其结果被认为是ADC传输函数的期望满度值。偏移校准值被作为增益校准测量的另外一点,借此可计算出增益系数。在进行完偏移校准之后,转换值被乘以增益系数。

通过写ADC系统方式位(AD0SM)来选择校准选项并启动校准过程。在校准期间,AD0CBSY位被置‘1’。在校准完成后,AD0SM位回到空闲方式,AD0CBSY位被清‘0’,AD0CALC位被置‘1’,并产生ADC中断。清‘0’AD0INT标志时,AD0CALC位被清‘0’。校准结束后,校准结果被写入相应的校准寄存器。

进行内部校准时不需要在ADC输入引脚施加一个特殊电压。内部校准有三种选项:仅偏移校准、仅增益校准或全校准(偏移和增益)。全内部校准时,先进行内部偏移校准,然后进行内部增益校准。如果偏移和增益校准进行,则必须在增益校准之前进行偏移校准。在内部偏移校准期间,ADC输入被从内部连接到AGND。对于内部增益校准,ADC输入被从内部连接到一个满度电压,该满度电

23

常州工学院毕业设计论文 压等于所选择的参考电压除以PGA增益。

进行系统校准时使用在ADC输入引脚施加的电压。系统校准有两种选项:偏移校准和增益校准。为保证校准精度,应先进行偏移校准,然后再进行增益校准。在系统偏移校准期间,ADC输入应被连接到“零”值。在系统增益校准期间,ADC输入应被连接到正满度值(对于当前的PGA增益设置)。

偏移和增益的校准结果均为24位。校准结果保存在可用软件读和写的特殊功能寄存器中。偏移校准结果为以2的补码形式(24位)保存在寄存器ADC0COH、ADC0COM和ADC0COL中。偏移寄存器中各位的权值如下:

ADC0COH 23(MSB)-16 223ADC0COM 15-8 215ADC0COL 7-0(LSB) 216 28 2270 增益校准结果为定点24位数,保存在寄存器ADC0CGH、ADC0CGM和ADC0CGL中。增益寄存器中各位的权值如下:

ADC0CGH 23(MSB)-16 2207ADC0CGM 15-8 28ADC0CGL 7-0(LSB) 215 216223 偏移校准值用于调整ADC传输函数的零点。偏移校准值为满度正值(0x7FFFFF)或满度负值(0x800000)时将导致ADC错误条件。

增益校准值用于调整ADC传输函数的斜率。增益校准寄存器中的数值范围为0 ~2223。增益校准值为极限值时(0或2223)将导致ADC错误条件。

ADC提供两种转换方式:单次转换和连续转换。在单次转换方式,每个滤波器(SINC3滤波器和快速滤波器)都输出转换结果。在连续转换方式,ADC执行back-to-back转换,直到ADC方式改变。

通过向ADC系统方式位(AD0SM)写“单次转换”选项对应的值来启动单次转换。在单次转换方式,ADC采集足够的信息为AD0ISEL位所选择的滤波器产生一个结果。在转换期间,AD0BUSY位被置‘1’。快速滤波器中的结果在一个ADC转换周期(由调制器周期和抽取比决定)之后可用,而SINC3滤波器中的结果在三个ADC转换周期之后可用。寄存器ADC0CF中的AD0ISEL位决定何时产生转换结束中断,并使ADC返回到空闲方式。如果AD0ISEL位被置‘1’,则AD0INT位在快速滤波器中的结果可用时被置‘1’。如果AD0ISEL位被清‘0’,则AD0INT

24

常州工学院毕业设计论文 位在SIN3滤波器中的结果可用时被置‘1’。当所选择的滤波器结束时,AD0SM位返回到空闲方式,AD0BUSY位被清‘0’。当使用SINC3滤波器时,快速滤波器也会输出有效结果。当使用快速滤波器工作在单次转换方式时,SINC3滤波器的结果是不准确的。

通过向ADC系统方式位(AD0SM)写“连续转换”选项对应的值来启动连续转换。在连续转换方式,ADC在每次转换结束后立即开始一次新的转换。在转换期间,AD0BUSY位被置‘1’。快速滤波器中的结果在一个ADC转换周期之后可用,之后每个转换周期都有可用的结果(由调制器周期和抽取比决定)。第一个SINC3滤波器的结果在三个ADC转换周期之后可用,后续的转换结果在每个转换周期结束时可用。寄存器ADC0CF中的AD0ISEL位决定何时产生转换结束中断。如果AD0ISEL位被清‘0’,则AD0INT位在SINC3滤波器中的结果可用时被置‘1’。如果AD0ISEL位被置‘1’,则AD0INT位在快速滤波器中的结果可用时被置‘1’。不管AD0ISEL位的设置如何,当新结果可用时,这两个滤波器都更新它们的结果寄存器。如果要停止转换并退出连续转换方式,AD0SM位应被写入空闲方式对应的数值。

ADC的两个滤波器都有其自己的输出数据寄存器。SINC滤波器的结果保存在ADC0H、ADC0M和ADC0L中,快速滤波器的结果保存在ADC0FH、ADC0FM和ADC0FL中。可以用寄存器ADC0CN中的AD0POL位将ADC输出配置为单极性或双极性方式。ADC输出字的编码见下表:

单极性输出字编码(AD0POL = 0) 输入电压(AIN+ - AIN-) VREF – 1LSB VREF/2 +1 LSB 0 24位输出字 0xFFFFFF 0x800000 0x000001 0x000000 注:输入电压是指经PGA放大后ADC输入端的电压。 双极性输出字编码(AD0POL = 1) 输入电压(AIN+ - AIN-) VREF – 1LSB VREF/2 24位输出字 0x7FFFFF 0x400000 25

常州工学院毕业设计论文 +1 LSB 0 -1 LSB -VREF/2 –VREF 0x000001 0x000000 0xFFFFFF 0xC00000 0x8000000 注:输入电压是指经PGA放大后ADC输入端的电压。 SINC3滤波器使用三个转换周期的信息产生一个ADC输出,快速滤波器仅使用当前转换周期的信息产生DAC输出。快速滤波器对模拟输入变化的响应较快,而SINC3滤波器产生具有较低噪声的结果。

在转换或校准期间的任何错误都由ADC0STA寄存器中的标志位来指示。如果在转换期间发生了SINC3滤波器限幅,AD0S3C标志会被置‘1’。类似地,如果在转换期间发生了快速滤波器限幅,则AD0FFC标志会被置‘1’。滤波器限幅发生在内部滤波器寄存器溢出之时(在转换期间)。如果发生了ADC超越条件,则AD0OVR标志被置‘1’。当ADC转换结束,而AD0INT标志仍然被置‘1’时,发生超越条件。如果数据寄存器尚未被读取,将被更新为新数据值,前面的转换结果丢失。通用的AD0ERR标志指示发生了AD0S3C、AD0FFC或AD0OVR错误条件,或者校准结果超出了偏移或增益寄存器的极限值。不管是否发生了错误条件,每次转换结束后数据输出寄存器都被更新。

C8051F35x包含一个8位的偏移DAC,可用于偏移修正,修正范围大约为±1/2×ADC输入范围(对任一PGA增益设置)。ADC0DAC寄存器控制偏移DAC电压。该寄存器中的值为有符号二进制数。MSB(位7)决定DAC幅值的符号,剩下的7位(位6-0)决定幅值。偏移DAC的每个LSB约等价于ADC输入范围的0.4%。对AD0DAC寄存器的写操作更新偏移DAC的输出。

Burnout电流源可用于检测ADC输入是否开路或短路。通过将寄存器ADC0CN中的AD0BCE位置‘1’来使能Burnout电流源。正通道Burnout电流源在AIN+上提供大约2 μA的电流,负通道Burnout电流源在AIN-上吸收大约2 μA的电流。如果在Burnout电流源被使能的情况下AIN+和AIN-之间是开路状态,则ADC会读到一个正的满度值,如果在Burnout电流源被使能的情况下AIN+和AIN-之间是短路状态,则ADC会读到一个接近零值的结果。在正常的ADC测量期间,Burnout电流源应被禁止。

26

常州工学院毕业设计论文 ADC0CN: ADC0控制寄存器

- - - AD0POL AD0BCE AD0GN2-0 AD0POL:ADC0极性控制位(0:ADC0工作在单极性方式,结果值为自然二进制数。1:ADC0工作在双极性方式,结果值为2的补码。)

AD0BCE:Burnout电流源使能位(0:Burnout电流源未被使能。1:Burnout电流源被使能。)

AD0GN:ADC0可编程增益设置位(000:PGA增益 = 1。001:PGA增益 = 2。010:PGA增益 = 4。011:PGA增益 = 8。100:PGA增益 = 16。101:PGA增益 = 32。110:PGA增益 = 。111:PGA增益 = 128。)

ADC0CF: ADC0配置寄存器

- - - AD0ISEL - AD0VREF - - AD0ISEL:ADC0中断源选择位。(该位选择哪一个滤波器转换结束使AD0INT中断标志置‘1’。0:SINC3滤波器。1:快速滤波器。)

AD0VREF:ADC0 VREF源选择位。(0:ADC0使用内部VREF2.5V。将该位清‘0’使能内部电压基准。1:ADC0使用外部VREF。)

ADC0MD: ADC0方式寄存器

AD0EN - 保留 保留 - AD0SM2-0 AD0EN:ADC0使能位(0:ADC0禁止。ADC0处于低耗停机状态。1:ADC0使能。ADC0处于活动状态,可以进行校准或转换。)

AD0SM:ADC0系统方式选择位。(这些位定义ADC的工作方式。它们被用于启动所有的ADC转换和校准周期。000:空闲。001:全内部校准。010:单次转换。011:连续转换。100:内部偏移校准。101:内部增益校准。110:系统偏移校准。111:系统增益校准。)

ADC0CLK: ADC0调制器时钟分频寄存器

ADC0CLK7-0 ADC0CLK:ADC0调制器时钟分频系数。该寄存器用于将系统时钟(SYSCLK)分频,建立调制器时钟(MDCLK)。调制器对ADC输入信号以MDCLK/128的频率采样。要达到最佳性能,应选择能使调制器时钟等于2.4576 MHz(调制器采样速率 = 19.2 KHz)的分频系数。系统时钟按下面的方程被分频:MDCLK = SYSCLK/(ADC0CLK+1)

27

常州工学院毕业设计论文 ADC0STA: ADC0状态寄存器

AD0BUSY AD0CBSY AD0INT AD0S3C AD0FFC AD0CALC AD0ERR AD0OVR AD0BUSY:ADC0转换标志(0:ADC0不在执行转换。1:ADC0正在执行转换。) AD0CBSY:ADC0校准标志(0:ADC0不在执行校准。1:ADC0正在执行校准。) AD0INT:ADC0转换结束中断标志(该标志必须用软件清‘0’。0:自该标志最后一次被清‘0’后未完成转换。1:ADC0转换结束。)

AD0S3C:ADC0 SINC3滤波器限幅标志(该错误标志指示在转换期间发生了SINC3滤波器限幅。0:ADC0 SINC3滤波器未发生限幅。1:ADC0 SINC3滤波器发生了限幅。)

AD0FFC:ADC0快速滤波器限幅标志(该错误标志指示在转换期间发生了快速滤波器限幅。0:ADC0快速滤波器未发生限幅。1:ADC0快速滤波器发生了限幅。) AD0CALC:ADC0校准结束标志(0:ADC0校准未完成。1:ADC0校准已完成。) AD0ERR:ADC0错误标志。该位在下列情况下由硬件置位:1) 转换周期中发生了AD0OVR、AD0S3C或AD0FFC错误。2) 校准结果超出了偏移或增益寄存器的极限值。

AD0OVR:ADC0超越标志。(该位指示发生了超越条件。0:未发生ADC0超越条件。1:发生了ADC0超越条件。)

ADC0包含一个模拟多路选择器,可以选择去AIN+和AIN-输入的信号。AIN+和AIN-输入都有十种可选的输入源:AIN0.0 ~ AIN0.7、AGND和片内温度传感器。ADC0MUX寄存器控制两个通道的输入选择。可以通过配置模拟多路选择器来实现单端或差分测量。将一个ADC输入连接到AGND即可实现单端测量。

ADC0MUX: ADC0模拟多路器控制寄存器

AD0PSEL7-4 AD0NSEL3-0 AD0PSEL:ADC0 正输入多路器通道选择。(0000:AIN0.0。0001:AIN0.1。0010:AIN0.2。0011:AIN0.3。0100:AIN0.4。0101:AIN0.5。0110:AIN0.6。0111:AIN0.7。1111:温度传感器。 所有其它设置:AGND。)

AD0NSEL:ADC0负输入多路器通道选择(0000:AIN0.0。0001:AIN0.1。0010:AIN0.2。0011:AIN0.3。0100:AIN0.4。0101:AIN0.5。0110:AIN0.6。0111:AIN0.7。1111:温度传感器。所有其它设置:AGND。) 子程序如下:void ADC0_Init (void) {

28

常州工学院毕业设计论文 ADC0CN = 0x00; // 单极性输出模式,增益为1

ADC0CF = 0x04; // 使用外部参考源,SINC3滤波器输出

ADC0CLK = (SYSCLK/MDCLK)-1; // 为调制器选择时钟,MDCLK=2.4576MHz ADC0BUF = 0x00; // 关闭输入缓冲

ADC0MUX = 0x01; // 设置ADC引脚,AIN0.1 => AIN- ,AIN0.0 => AIN+ ADC0MD = 0x80; // 启动ADC0 }

4.2.4 A/D转换子程序

该子程序用于完成采样、校准、转换的工作,为显示做好准备。

C8051F35包含一个扩展的中断系统,支持12个中断源,每个中断源有两个优先级。每个中断源可以在一个SFR中有一个或多个中断标志。当一个外设或外部源满足有效的中断条件时,相应的中断标志被置为逻辑‘1’。

如果一个中断源被允许,则在中断标志被置位时将产生中断。一旦当前指令执行完,CPU开始执行中断服务程序(ISR)。如果中断未被允许,中断标志将被硬件忽略,程序继续正常执行。中断标志置‘1’与否不受中断允许/禁止状态的影响。

每个中断源都可以用一个 SFR(IE或EIE1)中的相关中断允许位来允许或禁止,但是必须首先将EA位(IE.7)置‘1’,以保证每个单独的中断允许位有效。不管每个中断允许位的设置如何,清‘0’EA位将禁止所有中断。某些中断标志在CPU进入ISR时被自动清除,但大多数中断标志不是由硬件清除的,必须在ISR返回前用软件清除。

每个中断源都可以被地编程为两个优先级中的一个:低优先级或高优先级。每个中断在 SFR(IP或EIP1)中都有一个配置其优先级的中断优先级设置位,缺省值为低优先级。 如果两个中断同时发生,具有高优先级的中断先得到服务。如果这两个中断的优先级相同, 则由固定的优先级顺序决定哪一个中断先得到服务。

IE:中断允许寄存器

EA ESPI0 ET2 ES0 ET1 EX1 ET0 EX0 EA:允许所有中断。该位允许/禁止所有中断。它超越所有的单个中断屏蔽设置。(0:禁止所有中断源。1:开放中断。每个中断由它对应的中断屏蔽设置决定。)

29

常州工学院毕业设计论文 ESPI0:串行外设接口(SPI0)中断允许位。该位用于设置SPI0的中断屏蔽。(0:禁止SPI0中断。1:允许SPI0的中断请求。)

ET2:定时器2中断允许位。该位用于设置定时器 2 的中断屏蔽。(0:禁止定时器 2 中断。 1:允许 TF2L 或 TF2H 标志的中断请求。)

ES0:UART0中断允许位。该位设置UART0的中断屏蔽。(0:禁止 UART0 中断。 1:允许UART0中断。)

ET1:定时器1中断允许位。该位用于设置定时器1的中断屏蔽。(0:禁止定时器1中断。1:允许TF1标志位的中断请求。)

EX1:外部中断1允许位。该位用于设置外部中断1的中断屏蔽。(0:禁止外部中断1。1:允许/INT1引脚的中断请求。)

ET0:定时器0中断允许位。该位用于设置定时器0的中断屏蔽。(0:禁止定时器0中断。1:允许TF0标志位的中断请求。)

EX0:外部中断0允许位。该位用于设置外部中断0的中断屏蔽。(0:禁止外部中断 0。1:允许/INT0引脚的中断请求。)

IP:中断优先级寄存器

- PSPI0 PT2 PS0 PT1 PX1 PT0 PX0 PSPI0:串行外设接口(SPI0)中断优先级控制。该位设置SPI0中断的优先级。(0:SPI0为低优先级。1:SPI0为高优先级。)

PT2:定时器2中断优先级控制。该位设置定时器2中断的优先级。(0:定时器2为低优先级。1:定时器2为高优先级。)

PS0:UART0中断优先级控制。该位设置UART0中断的优先级。(0:UART0为低优先级。1:UART1为高优先级。)

PT1:定时器1中断优先级控制。该位设置定时器1中断的优先级。(0:定时器1为低优先级。 1:定时器1为高优先级。)

PX1:外部中断1优先级控制。该位设置外部中断1的优先级。(0:外部中断 1 为低优先级。1:外部中断1为高优先级。)

PT0:定时器0中断优先级控制。该位设置定时器0中断的优先级。(0:定时器0为低优先级。1:定时器 0 为高优先级。)

PX0:外部中断0优先级控制。该位设置外部中断0的优先级。(0:外部中断0为低优先级。1:外部中断0为高优先级。)

30

常州工学院毕业设计论文 EIE1:扩展中断允许1

ET3 保留 ECP0 EPCA0 EADC0C 保留2-1 ESMB0 ET3:定时器 3 中断允许位.该位设置定时器3的中断屏蔽。(0:禁止定时3中断。1:允许TF3L或TF3H标志的中断请求。)

ECP0:比较器0(CP0)中断允许位。该位设置CP0的中断屏蔽。(0:禁止CP0中断。1:允许CP0RIF或CP0FIF标志的中断请求。)

EPCA0:可编程计数器阵列(PCA0)中断允许位。该位设置PCA0的中断屏蔽。(0:禁止所有PCA0中断。1:允许PCA0的中断请求。)

EADC0C:ADC0转换结束中断允许位。该位设置ADC0转换结束中断屏蔽。(0:禁止ADC0转换结束中断。1:允许AD0INT标志的中断请求。)

ESMB0:SMBus中断允许位。该位设置SMBus(SMB0)的中断屏蔽。(0:禁止SMB0中断。1:允许SMB0的中断请求。)

EIP1:扩展中断优先级1

PT3 保留 PCP0 PPCA0 PADC0 保留2-1 PSMB0 PT3:定时器3中断优先级控制。该位设置定时器3中断的优先级。(0:定时器3中断为低优先级。1:定时器3中断为高优先级。)

PCP0:比较器0(CP0)中断优先级控制。该位设置CP0中断的优先级。(0:CP0中断为低优先级。1:CP0中断为高优先级。)

PPCA0:可编程计数器阵列(PCA0)中断优先级控制。该位设置PCA0中断的优先级。(0:PCA0中断为低优先级。1:PCA0中断为高优先级。)

PADC0:ADC0转换结束中断优先级控制。该位设置ADC0转换结束中断的优先级。(0:ADC0转换结束中断为低优先级。1:ADC0转换结束中断为高优先级。) PSMB0:SMBus(SMB0)中断优先级控制。该位设置SMB0中断的优先级。(0:SMB0中断为低优先级。1:SMB0中断为高优先级。)

31

常州工学院毕业设计论文 开始关中断,开校准N校准完?Y清中断标志,开始采样转换结果累加N到采样个数?Y求平均值结束待处理

图4–5 A/D转换流程图

子程序如下:

EA = 1; // 打开全局中断

EIE1 &= ~0x08; // 关闭ADC0中断 ADC0MD |= 0x81; // 开始ADC0全内部校准 while (!AD0CALC); // 等待校正结束 ADC0MD &= ~0x07; // 将ADC0置于空闲状态 AD0INT = 0; // 清除ADC0中断标志 g_iCounts = 0; // 初始化当前零点 while(1) {

Sum = 0;

ADC0MD = 0x83; // 开始连续转换

for(SampleCount=0; SampleCount32

常州工学院毕业设计论文 {

while(AD0BUSY); // 等待转换结束 AD0INT = 0; // 清除中断标志

ADC_OutputVal = ADC0L + ((long)ADC0M << 8) + ((long)ADC0H << 16); Sum += ADC_OutputVal; // 读取24位AD转换结果并求和 } //结束采样

Sum = Sum/NUMSAMPLES; //求平均值

ADC0MD = 0x80; // ADC0为空闲模式 }

4.2.5显示子程序

显示子程序用于完成A/D处理、LCD初始化、显示等操作。 显示子程序的流程图如下:

开始A/D处理LCD初始化向LCD写命令向LCD写地址地址+1取缓冲区首址向LCD写数据字符输完?Y结束N

图4–6 显示流程图

A/D处理的任务一是将A/D转换而来的数据转换为对应的重量值,二是将重量

33

常州工学院毕业设计论文 值转变为可供显示的字符,以便查表输出显示。

硬件部分已经提到50Kg重量经传感器输出并放大400倍后对应A/D输入的2V,而24位A/D的参考电压为2.5V,由定余量。由

62.5Kg224X50kg2.5V2V得X=62.5Kg,留有了一

0.01KgY解得Y=0A7CH,即0.01Kg对应的十六进制数为0A7CH,

同理可知0.02Kg 时对应数值为14F8H,50Kg时数值为CCCCCCH。由此可知从0.01Kg到0.02Kg的数字量变化较大,这样不仅满足了转换精度的要求,而且由于AD采样误差或外部干扰引起的数字量的变化不会影响到输出结果的稳定,提高了显示的准确度。

由上述公式转换得到的重量值是带有2位整数和2位小数的,为便于将重量值转变为可供显示的字符需将此值放大100倍,从最高位开始依次减去该位的十进制模量(如1000、100、......),减一次检测是否为负,为负则停止即可通过减的次数确定该位的字符,减几次该位就为字符几,依次类推确定下一位直至最低位。

A/D处理子程序如下:

Code unsigned char FontTable[10]=

{LCD_0,LCD_1,LCD_2,LCD_3,LCD_4,LCD_5,LCD_6,LCD_7,LCD_8,LCD_9}//字符0-9

code long Tens[]={ 1,10,100,1000,1000};

unsigned char LongtoASCII(char *p_out,long source)//将重量值转变为可显示的字符码 {

unsigned char j, numdig; long temp; numdig = 4;

//显示位数为4位

source= source*6250/16777216;//将A/D转换值转变为重量值并放大100倍

while (numdig) {

temp = Tens[--numdig]; //通过比较找到显示中每位的数字0~9 for (j = 0; j < 10; j++) {

34

常州工学院毕业设计论文

}

}

source -= temp;

if (source & 0x80000000) //取符号位查询 { }

break;

if (j==10) {

break;

}

source += temp;

*(p_out) = FontTable[j]; //字符送缓冲区 p_out++; //缓冲区地址加1

if (j==10) //超过9出错

return (1);

else

return (0);

}

HT1621B是一种具有微控制器接口,由存储器映射的32×4点阵式LCD控制驱动器。电路上电时清零复位,通过命令端进行工作状态设置,通过片选、读、写端对RAM数据进行读、写、修改操作,按照一一对应的原则,驱动LCD显示器。该电路可用于点阵式LCD显示驱动,各SEG端是互相的,且容易对RAM数据进行修改,所以显示点阵内容灵活,可随用户任意定制。

静态显示存储器(RAM)结构为32×4位,贮存所显示的数据。RAM的内容直接映射成LCD驱动器的内容。RAM中的数据可被READ、WRITE和READ—MODIFY—WRITE命令存取。RAM中的内容映射至LCD的过程如下图所示:

35

常州工学院毕业设计论文

HT1621B可以通过S/W来设置,设置HT1621B和传送LCD显示数据的指令共有两种模式,分别为命令模式和数据模式。对HT1621B的设置称作命令模式,其ID是100,由系统设置命令、系统频率选择命令、LCD结构命令、蜂鸣频率选择命令和操作命令组成。数据模式包括READ、WRITE 和READ—MODIFY—WRITE 操作。模式命令出现在数据和命令传送之前。如出现连续指令,命令模式ID100可以被忽略。当系统工作在不连续命令或不连续地址数据模式,CS管脚应设置为1,而之前的工作模式将被复位。一旦CS管脚为0,将出现一个新的工作模式ID。 常用的指令如下表: 名称 ID 命令代码 D/C 功能 上电预置复位 READ WRITE 110 101 A5A4A3A2A1A0D0D1D2D3 D A5A4A3A2A1A0D0D1D2D3 D A5A4A3A2A1A0D0D1D2D3 D 读RAM中数据 写数据到RAM 中 读写RAM READ-MODIFY101 -WRITE SYS DIS 100 000-0000-X C 同时关闭系统振荡器和LCD 偏置发生器 Yes SYS EN 100 000-0001-X C 开启系统振荡器 LCD OFF 100 0000-0010-X C 关闭LCD偏置发生器 Yes LCD ON 100 0000-0011-X C 开启LCD偏置发生器 36

常州工学院毕业设计论文 RC 256K 100 0001-10XX-X C 系统时钟为片内RC振荡器 Yes BIAS 1/3 100 0010-abX1-X C LCD1/3偏置状态 ab=00:2COM 端 ab=01:3COM 端 ab=10:4COM 端 TNORMAL 1.X:忽略。

100 1110-0011-X C 标准模式 Yes 2.A5~A0:RAM 地址。 3.D3~D0:RAM 数据 4.D/C:数据/命令模式。

5.110,101和100均是模式命令。如出现连续命令,命令模式ID100可以被忽略(除第一个命令ID100)。

由于对LCD显示操作时要先写命令,再写地址,最后写数据,因而在显示程序中需要经常用到三类子程序:写命令子程序、写地址子程序、写数据子程序。它们的程序流程类似,只是传送的位数不同而已。流程图如下:

开始比较命令、地址or数据的最高位N最高位为1?Y命令、地址or数据左移一位DATA=1DATA=0写允许,延时写禁止,延时N写完?Y结束

图4–7 LCD送命令、地址或数据流程图

37

常州工学院毕业设计论文 void send_command(unsigned char command)//用引脚模拟时序向LCD写入命令 { }

void send_address (unsigned int inbyte)//用引脚模拟时序向LCD写入地址 {

unsigned char i;

LCD_CS = 1; //关片选复位 Delay();

LCD_CS = 0; //开片选准备写命令 Delay();

for(i=0;i<3;i++); //命令模式ID为3位 { }

if(command&0x04) //比较命令字最高位

LCD_DATA = 1;

else

LCD_DATA = 0;

command<<=1; //命令字左移一位 Delay(); LCD_WR = 0; Delay(); LCD_WR = 1; Delay();

//写允许

//写禁止

unsigned char i;

for(i=0;i<6;i++) //地址为6位 {

if(inbyte&0x20) //比较地址字最高位

LCD_DATA = 1;

else

LCD_DATA = 0;

//地址字左移一位

38

inbyte<<=1;

常州工学院毕业设计论文 }

}

Delay(); LCD_WR = 0; Delay(); LCD_WR = 1; Delay();

//写禁止 //写允许

void send_bit_ (unsigned char bitNumber,unsigned int inbyte) //用引脚模拟时序向LCD写入数据 { }

LCD初始化子程序如下: void init_disp(void) {

send_command(0x04); //写命令模式ID100 send_bit_(9,0x1c6); //设置成标准模式 send_bit_(9,0x030);

unsigned char i;

for(i=0;iif(inbyte&0x100) //比较数据字最高位

LCD_DATA = 1;

else

LCD_DATA = 0;

//数据字左移一位

inbyte<<=1;

Delay_300ns(); LCD_WR = 0;

//写允许

Delay_50us(); //延时50us LCD_WR = 1;

//写禁止

Delay_50us();

//系统时钟为片内RC振荡器

39

常州工学院毕业设计论文 send_bit_(9,0x02); //开系统振荡

send_bit_(9,0x52); //LCD1/3偏置状态,4COM端 send_bit_(9,0x06); //开启LCD偏置发生器 LCD_CS = 1; }

LCD显示子程序如下:

void lcd_printfAll(unsigned char *lcd_buf)//将数据显示到LCD屏上去 { }

void display(long sum) //显示主函数 { }

unsigned char lcd_buf[10];

LongtoASCII(lcd_buf,sum); //调A/D处理子函数 lcd_printfAll(lcd_buf); //显示 unsigned char i,temp;

send_command(0x05); //命令模式ID101,写命令 send_address(0); //传缓冲区首址00H,写地址 for(i=0;i<4;i++) //传显示字符数据 { }

send_bit(8,lcd_buf[4]); //传固定字符数据 send_bit(8,lcd_buf[5]);

temp = *(lcd_buf+i); //缓冲区地址+1; send_bit(8,temp);

//结束配置

4.2.6异步串行口初始化子程序

UART0是一个异步、全双工串口,具有增强的波特率发生器电路,有多个时钟源可用于产生标准波特率。接收数据缓冲机制允许UART0在软件尚未读取前一个数据字节的情况下开始接收第二个输入数据字节。

40

常州工学院毕业设计论文 UART0有两个相关的特殊功能寄存器:串行控制寄存器(SCON0)和串行数据缓冲器(SBUF0)。用同一个SBUF0地址可以访问发送寄存器和接收寄存器。写SBUF0时自动访问发送寄存器;读SBUF0时自动访问接收寄存器,不可能从发送数据寄存器中读数据。

如果UART0中断被允许,则每次发送完成(SCON0中的TI0位被置‘1’)或接收到数据字节(SCON0中的RI0位被置‘1’)时将产生一个中断。当CPU转向中断服务程序时硬件不清除UART0中断标志。中断标志必须用软件清除,这就是允许软件查询UART0中断的原因(发送完成或接收完成)。

UART0波特率由定时器1工作在8位自动重装载方式产生。发送(TX)时钟由TL1产生;接收(RX)时钟由TL1的拷贝寄存器产生,该寄存器不能被用户访问。TX和RX定时器的溢出信号经过二分频后用于产生TX和RX波特率。当定时器1被允许时,RX定时器运行并使用与定时器1相同的重载值(TH1)。在检测到RX引脚上的起始条件时RX定时器被强制重载,这允许在检测到起始位时立即开始接收过程,而与TX定时器的状态无关。

定时器1应被配置为方式2,即8位自动重装载方式。定时器1的重载值应设置为使其溢出频率为所期望的波特率频率的两倍。定时器1的时钟可以在6个时钟源中选择:SYSCLK、SYSCLK/4、SYSCLK/12、SYSCLK/48、外部振荡器时钟/8和外部输入T1。对于任何给定的定时器1时钟源,UART0的波特率由方程A和方程B决定:

A)UART波特率=

12×T1溢出率 T1CLK256TH1B)T1溢出率=

其中T1CLK是定时器1的时钟频率,TH1是定时器1的高字节(重载值)。 UART0的工作方式(8位或9位)通过S0MODE位(SCON0.7)来选择。 在8位UART方式,每个数据字节共使用10位:一个起始位、8个数据位(LSB在先)和一个停止位。数据从TX0引脚发送,在RX0引脚接收。在接收时,8个数据位存入SBUF0,停止位进入RB80(SCON0.2)。

当软件向SBUF0寄存器写入一个字节时开始数据发送。在发送结束时(停止位开始)发送中断标志TI0(SCON0.1)被置‘1’。在接收允许位REN0(SCON0.4)被置‘1’后,数据接收可以在任何时刻开始。收到停止位后,如果满足下述条件则数据字节将被装入到接收寄存器SBUF0:RI0必须为逻辑‘0’;如果MCE0为

41

常州工学院毕业设计论文 逻辑‘1’,则停止位必须为‘1’。在发生接收数据溢出的情况下,先接收到的8位数据被锁存到SBUF0,而后面的溢出数据被丢弃。

如果这些条件满足,则8位数据被存入SBUF0,停止位被存入RB80,RI0标志被置位。如果这些条件不满足,则不装入SBUF0和RB80,RI0标志也不会被置‘1’。如果中断被允许,在TI0或RI0置位时将产生一个中断。

SCON0:UART0控制寄存器

S0MODE - MCE0 REN0 TB80 RB80 TI0 RI0 S0MODE:串行口工作方式选择位(该位选择UART0的工作方式。0:方式0:波特率可编程的8位UART。1:方式1:波特率可编程的9位UART。)

MCE0:多处理器通信允许(该位的功能取决于串行口工作方式。 S0MODE = 0:检查有效停止位。0:停止位的逻辑电平被忽略。1:只有当停止位为逻辑‘1’时RI0激活。S0MODE = 1:多处理器通信允许。0:第9位的逻辑电平被忽略。1:只有当第9位为逻辑‘1’时RI0才被置位并产生中断。)

REN0:接收允许(该位允许/禁止UART接收器。0:UART0接收禁止。1:UART0接收允许。)

TB80:第9发送位(该位的逻辑电平被赋值给9位UART方式的第9发送位。在8位UART方式中未用。根据需要用软件置‘1’或清‘0’。)

RB80:第9接收位(在方式0,则RB80被赋值为停止位的值。在方式1该位被赋值为9位UART方式中第九数据位的值。)

TI0:发送中断标志(当UART0发送完一个字节数据后该位被硬件置‘1’(在8位UART方式时,是在发送第8位后;在9位UART方式时,是在停止位开始)。当UART0中断被允许时,置‘1’该位将导致CPU转到UART0中断服务程序。该位必须用软件清‘0’。)

RI0:接收中断标志(当UART0接收到一个字节数据时该位被硬件置‘1’(在停止位采样后)。当UART0中断被允许时,置‘1’该位将会使CPU转到UART0中断服务程序。该位必须用软件清‘0’。)

CKCON:时钟控制寄存器

T3MH T3ML T2MH T2ML T1M T0M SCA1 SCA0 T3MH:定时器3高字节时钟选择。T3ML:定时器3低字节时钟选择。T2MH:定时器2高字节时钟选择。T2ML:定时器2低字节时钟选择

T1M:定时器1时钟选择。该位选择定时器1的时钟源。当C/T1被设置为逻辑‘1’

42

常州工学院毕业设计论文 时,T1M被忽略。(0:定时器1使用由分频位(SCA1-SAC0)定义的时钟。1:定时器1使用系统时钟) T1M:定时器0时钟选择。

SCA1-SCA0:定时器0/1预分频位。如果定时器0/1被配置为使用分频时钟,则这些位控制时钟分频数。 SCA1 0 0 1 1 SCA0 0 1 0 1 分频时钟 系统时钟/12 系统时钟/4 系统时钟/48 外部时钟/8 子程序如下:void UART0_Init (void) {

SCON0 = 0x10; // 设置串口工作模式:8bit数据,无停止位,接收允许 if (SYSCLK/BAUDRATE/2/256 < 1) //设置串口波特率 {

TH1 = -(SYSCLK/BAUDRATE/2);

CKCON |= 0x08; //定时器1使用系统时钟

}

else if (SYSCLK/BAUDRATE/2/256 < 4) {

TH1 = -(SYSCLK/BAUDRATE/2/4);

CKCON &= ~0x0B; //定时器1使用系统时钟/4 CKCON |= 0x01; }

else if (SYSCLK/BAUDRATE/2/256 < 12) {

TH1 = -(SYSCLK/BAUDRATE/2/12);

CKCON &= ~0x0B; //定时器1使用系统时钟/12 }

else {

43

常州工学院毕业设计论文 TH1 = -(SYSCLK/BAUDRATE/2/48);

CKCON &= ~0x0B; //定时器1使用系统时钟/48 CKCON |= 0x02; }

TL1 = TH1; // 初始化定时器1 TMOD &= ~0xf0; // 设定工作模式:8位重装 TMOD |= 0x20;

TR1 = 1; // 启动定时器1 TI0 = 1; // 发送准备 }

4.2.7按键子程序

按键子程序流程图如下:

开始N有键按下?YN按键有效?Y记录偏移量原值减去偏移量结束

图4–8 按键程序流程图

按键的主要功能是去皮和清零,采用查询方式查询按键是否按下。去皮主要是将托盘的重量去掉,范围较大;清零主要是防止去皮后有零点偏移,即相当于零点偏移校准,所以范围很小。但两者的原理都是一样的,很简单就是减去偏移的值即可。对去皮来说是减去转换滤波器中的托盘值,对清零来说是减去偏移校

44

常州工学院毕业设计论文 准寄存器中的零点偏移值。

子程序如下:void ProcessClear(long *sum) { }

while(Clearbutton == 1) //按键按下 {

if(Clearbutton == 0) //按键松开,确定按下有效 {

g_iCounts = *sum; //记录当前零点 *sum -= g_iCounts;

//处理显示重量

} }

4.3本章小结

本章软件设计是论文的重点,根据模块化的设计方法将主程序分成各个功能模块进行设计,介绍了各功能模块编程所要用到的相关寄存器和编程知识,通过流程图概括了时钟初始化子程序、I/O端口初始化子程序、A/D转换初始化子程序、A/D转换子程序、显示子程序、异步串口初始化子程序、按键子程序等的编程思想,并通过分析各子模块的C语言程序细化了整个软件设计过程。

45

常州工学院毕业设计论文 第五章 软件仿真

5.1仿真软件的介绍

KeilC51uVision2集成开发环境是Keil Software,Inc/Keil Elektronik GmbH 开发的基于80C51内核的微处理软件开发平台,内嵌多种符合当前工业标准的开发工具,可以完成从工程建立和管理、编译、链接、目标代码的生成、软件仿真及硬件仿真等完整的开发流程。尤其是C编译工具在产生代码的准确性和效率方面达到了较高的水平,而且可以附加灵活控制选项,在开发大型项目时非常理想。

在Keil C51集成开发环境下是使用工程的方式来管理文件的,而不是单一文件的模式。所有的文件包括源程序(包括C程序和汇编程序)、头文件以及说明性的技术文档,它们都可以放在工程文件里统一管理。使用该软件时,首先创建一个自己的应用程序,然后进行程序文件的编译、连接。

5.2仿真画面的介绍

46

图5-1 主程序仿真图

常州工学院毕业设计论文 将源文件程序添加到项目后,接下来开始编译连接。先选择Project菜单中的Options for Target‘Target 1’进行工程详细设置,设置为软件模式,然后选择Project菜单中的Build target命令对源程序进行编译。

图5-2 程序编译错误

如图5-2所示,程序在编译时发现语法错误,系统会给出错误所在的行和该错误提示信息。如有错误则可以根据下面窗口的提示进行修改,更正程序中出现的语法错误,重新编译直至完全正确为止,如图5-3所示:

47

常州工学院毕业设计论文

图5-3 程序编译连接正确

编译连接正确后获得目标代码,但这仅仅代表源程序没有语法错误,至于源程序中存在的其他错误必须通过调试才能发现并解决。

使用菜单Debug中的Start/Stop Debug Session进入调试状态。使用Step或Step Over可以单步执行程序,使用Insert/Remove BreakPoint可以设置/移除除断点等。通过对各子程序模块的设置断点和单步执行可以发现在编译时不能发现的功能执行上的错误。以下是时钟初始化子程序SYSCLK_Init的调试过程:

48

常州工学院毕业设计论文

图5-4 单步执行程序至断点

在调试程序时可以通过菜单View下的相应命令打开输出窗口(Output Windows)、观察窗口(Watch&Call Statck Windows)、存储器窗口(Memory Window)、反汇编窗口(Dissambly Window)、串行窗口(Serial Window)等。 存储器窗口中可以显示系统中各种内存中的值,通过在Address后的编缉框内输入“字母:数字”即可显示相应内存值,其中字母可以是C、D、I、X,分别代表代码存储空间、直接寻址的片内存储空间、间接寻址的片内存储空间、扩展的外部RAM 空间,数字代表想要查看的地址。在软件设计中使用的寄存器都有相应的地址被定义在C语言的.h头文件中,例如要查看时钟乘法器控制寄存器CLKMUL中的值,就可以输入该特殊寄存器的地址D:0xBE便可查看到,如图5-5所示:

49

常州工学院毕业设计论文

图5-5 用存储器窗口查看寄存器的值

以下是反汇编观察窗口,该窗口可以显示反汇编后的代码、源程序和相应反汇编代码的混合代码,可以在该窗口进行在线汇编、利用该窗口跟踪已找行的代码、在该窗口按汇编代码的方式单步执行。

图5-6 反汇编窗口

5.3本章小结

本章对用keil软件仿真的过程作了详细的介绍,仿真过程从建立工程和C源文件到汇编和连接生成目标代码,到调试完成。重点介绍了调试中所使用的方法,如设置断点、单步执行、利用各种窗口等,并利用这些方法完成了本称重系统的软件仿真工作,基本实现了设计功能要求。

50

常州工学院毕业设计论文 结 论

本课题研究的电子称重系统是在传统的称重仪的基础上开发设计的,涉及到传感器原理、A/D转换技术、模拟电子技术、单片机技术、信息显示技术以及稳压电源技术等众多学科。本电子称重系统不仅保留了传统称重仪器的一般功能特点,而且从单片机选型、传感器选型、滤波放大电路设计、电源设计、功能扩展等诸多方面全面考虑,进行了合理的改进和完善,提高了性能,增加了功能,降低了成本,简化了操作。传感器电路采用电桥电路并增加了滤波有效地防止了干扰;A/D放大电路利用通道多路器有效地防止了温漂;选择内置24位精确A/D型SOC单片机C8051F350作为控制核心,有效地提高了测量精度,并利用异步串行接口增加了与上位机通信的功能;采用液晶显示技术,使得数字显示清晰且功耗小。总的来说,硬件结构较一般称重仪器更加合理,采用C语言模块化编程使得控制程序更加精炼、灵活、易懂,仪器性能稳定,功能齐全,称重方便、快捷、准确。

本称重系统除了拥有高速、稳定、精确的称重功能以外,特别增加了与上位机的通信功能,如果对本设计加以完善,管理人员可以通过一台电脑来监控市场上的所有称重系统,对每一次交易的时间、金额等数据进行保存,以便在遇到买卖纠纷时有数据可依,这对保障买卖公平公正,维护消费者合法权益,完善市场交易过程,规范市场交易秩序,促进经济发展有着重要的启发与贡献。

51

常州工学院毕业设计论文 参考文献

[1] 维普资讯http://www.cqvip.com

[2] 童诗白,华成英.模拟电子技术基础(第三版).高等教育出版社,1988 [3] 李维褆,郭强.液晶显示应用技术.电子工业出版社.2003

[4] 郁有文,常建,程继红.传感器原理及工程应用.西安电子科技大学出版社,

2003

[5] 包可进.C8051F系列单片机应用.中国电力出版社,2005

[6] 李刚,林凌.与8051兼容的高性能、高速单片机—C8051Fxxx.北京航空航天

大学出版社,2002

[7] 张迎新,雷文,姚静波.C8051F系列SOC单片机原理及应用.国防工业出版

社,2005

[8] 包可进.C8051F系列单片机应用.中国电力出版社,2005 [9] 谭浩强.C程序设计.清华大学出版社,1999

[10] 公茂法,马宝甫,孙晨.单片机人机接口实例集.北京航空航天大学出版

社,1998

[11] 李联.中外集成电路简明速查手册.电子工业出版社,1998

[12] 马忠梅,张凯,马岩.单片机的C语言应用程序设计.北京航空航天大学出版

社.1998

[13] 周立功.增强型80C51单片机速成与实战[M].北京航空航天大学出版

社,2005

[14] 松井邦彦,梁瑞林 译.传感器实用电路设计与制作[M].科技出版社,2006 [15] 阎石.数字电路技术基础(第四版)[M].高等教育出版社,1998 [16] 何利民. 单片机应用技术选编. 北京航空航天大学出版社,2004 [17] 胡汉才.单片机原理及接口技术[M].清华大学出版社 [18] 王兆安,黄俊.电力电子技术.机械工业出版社.2000 [19] 邱关源.电路原理(第四版).高等教育出版社.1999 [20] 何希才.稳压电源电路的设计与应用.中国电力出版社.2006

[21] 马忠梅.单片机的C语言应用程序设计.北京航空航天大学出版社,1997 [22] Herbert Schildt著.戴健鹏译.新编C语言大全.清华大学出版社,1994

52

常州工学院毕业设计论文 [23] Data Converter Reference Manual(Volume).Analog Devices Inc,1992 [24] RaShid M H.Power Electronics.Prentice-Hall,Inc.1988

[25] Vasilivs, Perovl T B. Design of advanced ro-bust decentralized

control of parallel de/de converter[J]. Electrical Engineering, 2003

[26](美)Charles Kitchin ,Lew Counts. Adesigner’s Guide To

Instrumentation Amplifiers. Analog Devises ,Inc.2005 [27](德)Kochsiek Manfred.称重手册.中国计量出版社,1992 [28](日)远坂俊昭.从滤波器到镜像放大器的应用.科学出版社,2006 [29](日)长谷川彰.开关稳压电源的设计与应用.科学出版社.2006 [30](美)Floyd.Conventional Current Version.北京-科学出版社,2004 [31] John G,Kassakian.Principles of Power Electronics.Addis on Wesley

publishing company,1991

53

常州工学院毕业设计论文 致 谢

在论文完成之际,本人要深深感谢所有给予我帮助和关怀的人。首先我要感谢这次毕业设计的导师范力旻老师和邹锦华老师,正是在她们的认真指导和关怀下本文才得以完成,论文中的每一点成绩无不凝结着他们的心血和汗水。在这里向老师们致以衷心的感谢和崇高的敬意。其次还要感谢负责硬件设计部分的汪向军同学,由于我们相互的默契配合才使得这次设计能够成功。最后感谢参与论文评阅的所有老师,谢谢你们对论文提出宝贵的意见和建议。

54

附录1 系统硬件电路图

常州工学院毕业设计论文 附 录

55

常州工学院毕业设计论文 附录2 系统软件程序

/*--------------------------------------------------------------------------- ; FILE NAME: C8051F350.H ; TARGET MCUs: C8051F350

; DESCRIPTION: Register/bit definitions for the C8051F350 product family. ;---------------------------------------------------------------------------*/ /* BYTE Registers */

sfr P0 = 0x80; /* PORT 0 LATCH */ sfr SP = 0x81; /* STACK POINTER */ sfr DPL = 0x82; /* DATA POINTER LOW */ sfr DPH = 0x83; /* DATA POINTER HIGH */ sfr PCON = 0x87; /* POWER CONTROL */

sfr TCON = 0x88; /* TIMER/COUNTER CONTROL */ sfr TMOD = 0x; /* TIMER/COUNTER MODE */ sfr TL0 = 0x8A; /* TIMER/COUNTER 0 LOW */ sfr TL1 = 0x8B; /* TIMER/COUNTER 1 LOW */ sfr TH0 = 0x8C; /* TIMER/COUNTER 0 HIGH */ sfr TH1 = 0x8D; /* TIMER/COUNTER 1 HIGH */ sfr CKCON = 0x8E; /* CLOCK CONTROL */

sfr PSCTL = 0x8F; /* PROGRAM STORE R/W CONTROL */ sfr P1 = 0x90; /* PORT 1 LATCH */

sfr TMR3CN = 0x91; /* TIMER/COUNTER 3CONTROL */ sfr TMR3RLL = 0x92; /* TIMER/COUNTER 3 RELOAD LOW */ sfr TMR3RLH = 0x93; /* TIMER/COUNTER 3 RELOAD HIGH */ sfr TMR3L = 0x94; /* TIMER/COUNTER 3 LOW */ sfr TMR3H = 0x95; /* TIMER/COUNTER 3 HIGH */ sfr SCON0 = 0x98; /* UART0 CONTROL */ sfr SBUF0 = 0x99; /* UART0 DATA BUFFER */ sfr ADC0DECL = 0x9A; /* ADC0 DECIMATION LOW */ sfr ADC0DECH = 0x9B; /* ADC0 DECIMATION HIGH */

56

常州工学院毕业设计论文 sfr P2 = 0xA0; /* PORT 2 LATCH */

sfr P0MDOUT = 0xA4; /* PORT 0 OUTPUT MODE CONFIGURATION */ sfr P1MDOUT = 0xA5; /* PORT 1 OUTPUT MODE CONFIGURATION */ sfr P2MDOUT = 0xA6; /* PORT 2 OUTPUT MODE CONFIGURATION */ sfr IE = 0xA8; /* INTERRUPT ENABLE */ sfr CLKSEL = 0xA9; /* CLOCK SELECT */

sfr EMI0CN sfr ADC0CGL sfr ADC0CGM sfr ADC0CGH sfr OSCXCN sfr OSCICN sfr OSCICL sfr FLSCL sfr FLKEY sfr IP sfr ADC0COL sfr ADC0COM sfr ADC0COH sfr ADC0BUF sfr CLKMUL sfr ADC0DAC sfr ADC0L sfr ADC0M sfr ADC0H sfr ADC0MUX sfr PSW sfr REF0CN sfr P0SKIP sfr P1SKIP sfr ACC

= 0xAA; /* EXTERNAL MEMORY INTERFACE CONTROL = 0xAB; /* ADC0 GAIN CALIBRATION LOW */ = 0xAC; /* ADC0 GAIN CALIBRATION MIDDLE */ = 0xAD; /* ADC0 GAIN CALIBRATION HIGH */ = 0xB1; /* EXTERNAL OSCILLATOR CONTROL */ = 0xB2; /* INTERNAL OSCILLATOR CONTROL */ = 0xB3; /* INTERNAL OSCILLATOR CALIBRATION */ = 0xB6; /* FLASH SCALE */

= 0xB7; /* FLASH LOCK AND KEY */ = 0xB8; /* INTERRUPT PRIORITY */

= 0xBA; /* ADC0 OFFSET CALIBRATION LOW */ = 0xBB; /* ADC0 OFFSET CALIBRATION MIDDLE */ = 0xBC; /* ADC0 OFFSET CALIBRATION HIGH */ = 0xBD; /* ADC0 BUFFER CONTROL */ = 0xBE; /* CLOCK MULTIPLIER */ = 0xBF; /* ADC0 OFFSET DAC */ = 0xC3; /* ADC0 OUTPUT LOW */ = 0xC4; /* ADC0 OUTPUT MIDDLE */ = 0xC5; /* ADC0 OUTPUT HIGH */ = 0xC6; /* ADC0 MULTIPLEXER */ = 0xD0; /* PROGRAM STATUS WORD */ = 0xD1; /* VOLTAGE REFERENCE CONTROL */ = 0xD4; /* PORT 0 SKIP */ = 0xD5; /* PORT 1 SKIP */ = 0xE0; /* ACCUMULATOR */

57

常州工学院毕业设计论文 sfr XBR0 = 0xE1; /* PORT I/O CROSSBAR CONTROL 0 */ sfr XBR1 = 0xE2; /* PORT I/O CROSSBAR CONTROL 1 */ sfr IT01CF = 0xE4; /* INT0/INT1 CONFIGURATION */ sfr EIE1 = 0xE6; /* EXTENDED INTERRUPT ENABLE 1 */ sfr ADC0STA = 0xE8; /* ADC0 STATUS */

sfr RSTSRC = 0xEF; /* RESET SOURCE CONFIGURATION/STATUS */ sfr P0MDIN = 0xF1; /* PORT 0 INPUT MODE CONFIGURATION */ sfr P1MDIN = 0xF2; /* PORT 1 INPUT MODE CONFIGURATION */ sfr ADC0MD = 0xF3; /* ADC0 MODE */ sfr ADC0CN = 0xF4; /* ADC0 CONTROL */

sfr EIP1 = 0xF6; /* EXTENDED INTERRUPT PRIORITY 1 */ sfr ADC0CLK = 0xF7; /* ADC0 CLOCK */

sfr ADC0CF = 0xFB; /* ADC0 CONFIGURATION */

sfr ADC0FL = 0xFC; /* ADC0 FAST FILTER OUTPUT LOW */ sfr ADC0FM = 0xFD; /* ADC0 FAST FILTER OUTPUT MIDDLE */ sfr ADC0FH = 0xFE; /* ADC0 FAST FILTER OUTPUT HIGH */ sfr VDM0CN = 0xFF; /* VDD MONITOR CONTROL */ /* Bit Definitions */ /* TCON 0x88 */

sbit TF1 = 0x8F ; /* TIMER 1 OVERFLOW FLAG */ sbit TR1 = 0x8E ; /* TIMER 1 ON/OFF CONTROL */ sbit IE1 = 0x8B ; /* EXT. INTERRUPT 1 EDGE FLAG */ sbit IT1 = 0x8A ; /* EXT. INTERRUPT 1 TYPE */ sbit IE0 = 0x ; /* EXT. INTERRUPT 0 EDGE FLAG */ sbit IT0 = 0x88 ; /* EXT. INTERRUPT 0 TYPE */ /* SCON0 0x98 */

sbit S0MODE = 0x9F ; /* UART 0 MODE */ sbit MCE0 = 0x9D ; /* UART 0 MCE */ sbit REN0 = 0x9C ; /* UART 0 RX ENABLE */ sbit TB80 = 0x9B ; /* UART 0 TX BIT 8 */ sbit RB80 = 0x9A ; /* UART 0 RX BIT 8 */

58

常州工学院毕业设计论文 sbit TI0 = 0x99 ; /* UART 0 TX INTERRUPT FLAG */ sbit RI0 = 0x98 ; /* UART 0 RX INTERRUPT FLAG */ /* IE 0xA8 */

sbit EA = 0xAF ; /* GLOBAL INTERRUPT ENABLE */ sbit ESPI0 = 0xAE ; /* SPI0 INTERRUPT ENABLE */ sbit ET2 = 0xAD ; /* TIMER 2 INTERRUPT ENABLE */ sbit ES0 = 0xAC ; /* UART0 INTERRUPT ENABLE */ sbit ET1 = 0xAB ; /* TIMER 1 INTERRUPT ENABLE */ sbit EX1 = 0xAA ; /* EXTERNAL INTERRUPT 1 ENABLE */ sbit ET0 = 0xA9 ; /* TIMER 0 INTERRUPT ENABLE */ sbit EX0 = 0xA8 ; /* EXTERNAL INTERRUPT 0 ENABLE */ /* IP 0xB8 */

sbit PSPI0 = 0xBE ; /* SPI0 PRIORITY */ sbit PT2 = 0xBD ; /* TIMER 2 PRIORITY */ sbit PS0 = 0xBC ; /* UART0 PRIORITY */ sbit PT1 = 0xBB ; /* TIMER 1 PRIORITY */

sbit PX1 = 0xBA ; /* EXTERNAL INTERRUPT 1 PRIORITY */ sbit PT0 = 0xB9 ; /* TIMER 0 PRIORITY */

sbit PX0 = 0xB8 ; /* EXTERNAL INTERRUPT 0 PRIORITY */ /* PSW 0xD0 */

sbit CY = 0xD7 ; /* CARRY FLAG */

sbit AC = 0xD6 ; /* AUXILIARY CARRY FLAG */ sbit F0 = 0xD5 ; /* USER FLAG 0 */

sbit RS1 = 0xD4 ; /* REGISTER BANK SELECT 1 */ sbit RS0 = 0xD3 ; /* REGISTER BANK SELECT 0 */ sbit OV = 0xD2 ; /* OVERFLOW FLAG */ sbit F1 = 0xD1 ; /* USER FLAG 1 */

sbit P = 0xD0 ; /* ACCUMULATOR PARITY FLAG */ /* ADC0STA 0xE8 */

sbit AD0BUSY = 0xEF ; /* ADC 0 CONVERSION IN PROGRESS FLAG */ sbit AD0CBSY = 0xEE ; /* ADC 0 CALIBRATION IN PROGRESS FLAG */

59

常州工学院毕业设计论文 sbit AD0INT = 0xED ; /* ADC 0 CONVERSION COMPLETE FLAG */ sbit AD0S3C = 0xEC ; /* ADC 0 SINC3 FILTER ERROR FLAG */ sbit AD0FFC = 0xEB ; /* ADC 0 FAST FILTER ERROR FLAG */ sbit AD0CALC = 0xEA ; /* ADC 0 CALIBRATION COMPLETE FLAG */ sbit AD0ERR = 0xE9 ; /* ADC 0 ERROR FLAG */ sbit AD0OVR = 0xE8 ; /* ADC 0 OVERRUN FLAG */ //----------------------------------------------------------------------------- //C8051F350Measurement.c

//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Includes

//----------------------------------------------------------------------------- #include \"c8051F350.h\" // SFR declarations #include // Standard I/O Library #include

//----------------------------------------------------------------------------- // Global CONSTANTS

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

#define INTOSC 24500000 // Internal Oscillator frequency (Hz) #define SYSCLK 49000000 // SYSCLK frequency (Hz) #define BAUDRATE 115200 // UART0 Baudrate (bps) #define MDCLK 2450000 // Modulator Clock (Hz) #define VREF 250UL // External VREF (x 10^-2 V) #define NUMSAMPLES 1U // Number of samples per reading #define BIAS

0x52

#define SYSEN 0x02 #define LCDON 0x06 #define LCDOFF 0x04 sbit LCD_DATA = P1^1; sbit LCD_WR = P1^0; sbit LCD_CS = P0^6;

60

常州工学院毕业设计论文 sbit LCD_WR = P0^7; sbit LED0 = P0^0;

// LED0='1' means ON

//----------------------------------------------------------------------------- // Global Variables

//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Function PROTOTYPES

//----------------------------------------------------------------------------- void SYSCLK_Init (void); void PORT_Init (void); void ADC0_Init (void); void IDA0_Init (void); void UART0_Init (void); void Delay(void); /* #define #define #define #define #define #define #define #define /* #define #define #define */ #define

LCD_0

SA+SF+SE+SD+SC+SB

//;'0'

k_ g_

0x20 0x40

SA SB SC SD SE SG SF

0x10 0x20 0x40 0x08 0x04 0x02 0x01

//0b00010000 //0b00100000 //0b01000000 //0b00001000 //0b00000100 //0b00000010 //0b00000001

dot 0x80 //0b10000000

dotdot 0x08

#define LCD_1 #define LCD_2

SB+SC //;'1' //;'2'

SA+SB+SG+SE+SD

61

常州工学院毕业设计论文 #define LCD_3 #define LCD_4 #define LCD_5 #define LCD_6 #define LCD_7 #define LCD_8 #define LCD_9

SA+SB+SG+SC+SD SF+SG+SB+SC SF+SG+SC+SD+SA SA+SF+SE+SD+SC+SG SA+SB+SC

//;'3' //;'4' //;'5' //;'6' //;'7'

SA+SB+SC+SD+SE+SF+SG //;'8' SA+SB+SC+SD+SF+SG

//;'9'

code unsigned char FontTable[10] =

{LCD_0,LCD_1,LCD_2,LCD_3,LCD_4,LCD_5,LCD_6,LCD_7,LCD_8,LCD_9}; /*

void SendBit_1621(unsigned char inbyte,unsigned char cnt); void SendDataBit_1621(unsigned char inbyte,unsigned char cnt); void SendCmd(unsigned char command);

void Write_1621(unsigned char addr,unsigned char inbyte);

void WriteAll_1621(unsigned char addr,unsigned char *p, unsigned char cnt); */

code long Tens[] = { 1, 10, 100, 1000, };

unsigned char LongtoASCII(char *p_out, long source); void lcd_printfAll(void); void init_disp(void);

void send_command(unsigned char command);

void send_bit (unsigned char bitNumber,unsigned int inbyte); void send_bit_ (unsigned char bitNumber,unsigned int inbyte); void send_address (unsigned int inbyte); void Delay_50us(void); void Delay_100ns(void); void Delay_300ns(void); unsigned char lcd_buf[10]; unsigned char output_ptr,input_ptr;

unsigned char RdLcPanda(unsigned long *wgt);

62

常州工学院毕业设计论文 void main (void) {

unsigned int temp; unsigned char i; unsigned long wgt;

PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer enable ) SYSCLK_Init (); // Initialize system clock to 49 MHz

REF0CN &= ~0x01; // disable internal vref PORT_Init (); // Initialize crossbar and GPIO ADC0_Init(); // Initialize ADC0 UART0_Init(); // Initialize UART0 EA = 1; // enable global interrupts LCD_CS = 0; LCD_DATA = 0; LCD_WR = 0; LED0 = 0; /*

SendCmd(SYSEN); SendCmd(BIAS); SendCmd(LCDON); Write_1621(0x24,0x01); WriteAll_1621(0,a,5); SendCmd(LCDOFF); */

init_disp();

EIE1 &= ~0x08; // Disable ADC0 interrupts ADC0MD |= 0x01; // Init Internal Full cal while (!AD0CALC); // Wait for calibration complete ADC0MD &= ~0x07; // clear bits(put ADC0 in IDLE mode) AD0INT = 0; // clear pending interrupt

ADC0MD = 0x83; // Start continuous conversion

63

常州工学院毕业设计论文

while(1) {

LED0 = ~LED0; RAR = ~RAR;

while(AD0BUSY); // wait till conversion complete AD0INT = 0; // clear AD0 interrupt flag temp = (unsigned int)ADC0M + ((unsigned int)ADC0H << 8); adcount[input_ptr] = temp;

ProcessClear(sum); }

unsigned char LongtoASCII(char *p_out, long source) {

if(++input_ptr>MAXCOUNT-1) { }

for(i = 0;i < 10;i ++) lcd_buf[i] = 0x00;

LongtoASCII(lcd_buf, temp); lcd_printfAll(); }// end while(1)

input_ptr= 0;

unsigned char j, numdig; long temp; numdig = 4;

source= source*6250/16777216; while (numdig) {

temp = Tens[--numdig]; for (j = 0; j < 10; j++) {

source -= temp;

常州工学院毕业设计论文 }

}

if (source & 0x80000000) { }

break;

if (j==10) { }

break;

source += temp;

*(p_out) = FontTable[j]; p_out++; } if (j==10) return (1); else return (0);

void ProcessClear(long *sum) { }

//----------------------------------------------------------------------------- // SYSCLK_Init

//----------------------------------------------------------------------------- // This routine initializes the system clock to use the external 24.5MHz

65

while(Clearbutton == 1) {

if(Clearbutton == 0) { }

g_iCounts = *sum;

*sum -= g_iCounts; }

常州工学院毕业设计论文 // oscillator as its clock source, with x 2 multiply for 49 MHz operation. Also enables

//missing clock detector reset. void SYSCLK_Init (void) {

int multiplier_delay;

OSCICN = 0x00; OSCXCN = 0x67;

for(multiplier_delay=0;multiplier_delay<24400; multiplier_delay++)

{} // Delay for at least 1ms

while (!(OSCXCN & 0x80));

CLKMUL = 0x00; // Reset Clock Multiplier

CLKMUL &= ~0x03; // MULSEL = 00b (Input = SYSCLK/2) CLKMUL |= 0x80; // Enable 4x Multipler (MULEN = 1) for(multiplier_delay=0;multiplier_delay < 125; multiplier_delay++) }

//----------------------------------------------------------------------------- // PORT_Init

//----------------------------------------------------------------------------- // Configure the Crossbar and GPIO ports. void PORT_Init (void) {

P0SKIP |= 0xCC; // skip port P1SKIP |= 0x0F;

{} // Delay for at least 5us

CLKMUL |= 0xC0; // Initialize Multiplier while (!(CLKMUL & 0x20)); // Poll for Multiply Ready RSTSRC = 0x04; // enable missing clock detector CLKSEL = 0x02; // Switch to clock multiplier output

XBR0 = 0x01; // UART0 Selected XBR1 = 0x40; // Enable crossbar and weak pull-ups P0MDOUT |= 0xDf; // TX, LEDs = Push-pull

66

常州工学院毕业设计论文 }

//----------------------------------------------------------------------------- // ADC0_Init

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

// This function initializes the ADC to measure AIN0.0 and AIN0.1 on the Target // Board

void ADC0_Init (void) {

ADC0CN = 0x00; // Unipolar output codes, GAIN=1

ADC0CF = 0x04; // interrupts upon SINC3 filter output and uses external VREF ADC0CLK = (SYSCLK/MDCLK)-1; // Generate MDCLK for modulator. }

//----------------------------------------------------------------------------- // UART0_Init

//----------------------------------------------------------------------------- // Configure the UART0 using Timer1, for and 8-N-1. void UART0_Init (void) {

// Ideally, MDCLK = 2.4576 MHz ADC0BUF = 0x00; // Turn off Input Buffers

ADC0MUX = 0x01; // AIN0.1 => AIN- and AIN0.0 => AIN+ ADC0MD = 0x80; // Enable the ADC0 (IDLE Mode)

SCON0 = 0x10; // SCON0: 8-bit variable bit rate // level of STOP bit is ignored // RX enabled // ninth bits are zeros // clear RI0 and TI0 bits if (SYSCLK/BAUDRATE/2/256 < 1) {

TH1 = -(SYSCLK/BAUDRATE/2);

CKCON |= 0x08; // T1M = 1; SCA1:0 = xx

67

常州工学院毕业设计论文 }

}

else if (SYSCLK/BAUDRATE/2/256 < 4) {

TH1 = -(SYSCLK/BAUDRATE/2/4);

CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01 CKCON |= 0x01; }

else if (SYSCLK/BAUDRATE/2/256 < 12) {

TH1 = -(SYSCLK/BAUDRATE/2/12);

CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00 } else {

TH1 = -(SYSCLK/BAUDRATE/2/48);

CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10 CKCON |= 0x02; }

TL1 = TH1; // init Timer1

TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload TMOD |= 0x20;

TR1 = 1; // START Timer1 TI0 = 1; // Indicate TX0 ready

void Delay(void) {

int delay;

// for about 10us

for (delay = 0; delay < 250; delay++)

{} } #if 0

68

常州工学院毕业设计论文 // write the high part of inbyte into the ht1621(cnt bits),first is the highest bit void SendBit_1621(unsigned char inbyte,unsigned char cnt) { }

// write the low part of inbyte into ht1621(cnt bits), first is the lowest bit void SendDataBit_1621(unsigned char inbyte,unsigned char cnt) {

unsigned char i; for(i = 0;i < cnt;i++) {

if((inbyte & 0x80) == 0)

DAT = 0;

else

DAT = 1;

WR = 0; _nop_(); _nop_(); //_nop_(); //_nop_(); //_nop_(); WR = 1; inbyte <<= 1; }

unsigned char i; for(i = 0;i < cnt;i++) {

if((inbyte & 0x01) == 0)

DAT = 0;

else

DAT = 1;

WR = 0;

69

常州工学院毕业设计论文 // // // }

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); WR = 1; inbyte >>= 1; }

void SendCmd(unsigned char command) { }

void Write_1621(unsigned char addr,unsigned char inbyte) { }

void WriteAll_1621(unsigned char addr,unsigned char *p, unsigned char cnt) {

CS = 0;

SendBit_1621(0x80,4); SendBit_1621(command,8); CS = 1;

CS = 0;

SendBit_1621(0xa0,3); SendBit_1621(addr,6);

// Write the flag Code(101);

// Write the high 6bit of addr

// Write the low 4bit of inbyte

SendDataBit_1621(inbyte,4); CS = 1;

unsigned char i; CS = 0;

SendBit_1621(0xa0,3); SendBit_1621(addr,6);

// Write the flag Code (101) // Write the high 6bit of addr

// write inbyte continully

70

for(i = 0;i < cnt; i++,p++)

常州工学院毕业设计论文 }

{

SendDataBit_1621(*p,8); } CS = 1;

#endif

void lcd_printfAll(void) {

unsigned char i,temp; send_command(0x05);

//command 101(write mode)

send_address(0); //send the address(6 bit) of the register(the address is 00) for(i=0;i<4;i++)

//send the numbers

}

{

temp = lcd_buf[i]; send_bit(8,temp); }

send_bit(8,lcd_buf[4]); // the last three symbol send_bit(8,lcd_buf[5]);

//lcd_buf[i+1];

void init_disp(void) {

send_command(0x04); //write 100 send_bit_(9,0x1c6); //set as normal mode send_bit_(9,0x030); //use on_chip RC oscillator send_bit_(9,0x02);

//Turn on system oscillator

send_bit_(9,0x52); //LCD 1/3 BIAS OPTION AND 4 COMMONS OPTION send_bit_(9,0x06); LCD_CS = 1; }

///send the command ,example 100,101, void send_command(unsigned char command)

71

//TURN ON LCD BIAS GENERATOR COMMAND, //end the configu

常州工学院毕业设计论文 {

unsigned char i; LCD_CS = 1;

Delay_300ns(); //the two word up is I think shoud write,but the old scout program have'n it }

/****************************************************************** ;NAME: send_bit

;DESCRIBE: send the data to the HT1621B

;INPUT: bitNumber is the bit number of data(will send) ,\"data\" is the data will send ;OUTPUT: none ;Return value : none

;*******************************************************************/ void send_bit (unsigned char bitNumber,unsigned int inbyte) {

LCD_CS = 0; Delay_100ns(); for(i=0;i<3;i++) {

// SEND COMMAND MODE COMMAND 100

if(command&0x04)

LCD_DATA = 1;

else

LCD_DATA = 0;

command<<=1; Delay_300ns(); LCD_WR = 0; Delay_50us();

LCD_WR = 1; Delay_50us(); }

unsigned char i;

72

常州工学院毕业设计论文 }

for(i=0;iif(inbyte&0x01)

LCD_DATA = 1;

else

LCD_DATA = 0;

inbyte>>=1;

Delay_300ns(); LCD_WR = 0; Delay_50us();

LCD_WR = 1; Delay_50us(); }

void send_bit_ (unsigned char bitNumber,unsigned int inbyte) {

unsigned char i;

for(i=0;iif(inbyte&0x100)

LCD_DATA = 1;

else

LCD_DATA = 0;

inbyte<<=1; Delay_300ns(); LCD_WR = 0; Delay_50us();

LCD_WR = 1; Delay_50us(); }

73

常州工学院毕业设计论文 }

void send_address (unsigned int inbyte) { }

////the LCD_RD,LCD_WR pulse width with 3.34--125us,I set it with

50us ,Fpclk/12500 (Fpclk=1s,Fpclk/20000=1/20000=50us) void Delay_50us(void) {

unsigned int delay;

for (delay = 0; delay < 5*250; delay++)

unsigned char i; for(i=0;i<6;i++) {

if(inbyte&0x20)

LCD_DATA = 1;

else

LCD_DATA = 0;

inbyte<<=1; Delay_300ns(); LCD_WR = 0; Delay_50us();

LCD_WR = 1; Delay_50us(); }

{} }

////with the LCD_CS is LCD_WR OR LCD_RD ,the time is 100ns,Fpclk/10 000 000

(Fpclk=1s,Fpclk/10 000 000=1/10 000 000=100ns) void Delay_100ns(void) {

unsigned char delay;

74

常州工学院毕业设计论文 for (delay = 0; delay < 3; delay++)

{} }

///the LCD_CS width need 250ns ,I set it as 300ns void Delay_300ns(void) {

unsigned char delay;

for (delay = 0; delay < 10; delay++)

{} }

75

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