基于单片机的电能表设计

更新时间:2024-05-23 12:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于单片机的电能表设计

设计分工:本次电能表设计中,我主要负责电能计量模块、实时时钟模块和IC卡模块的软硬件设计。

1.1 设计任务

利用单片机和接口技术设计、研制一种新型电能表,可实现峰谷用电量和剩余金额,并用LCD显示。

1.2 设计目的

(1)进一步了解有关单片机、存储电路、IC卡的应用; (2)掌握信号获取、传输、处理及检测的一般方法;

(3)综合运用已有的理论和技术,制定设计方案,掌握用电量的测量方法; (4)学会应用存储电路、IC卡、单片机组建一个实际测量系统,提高设计者的应用能力;

(5)通过测量、计算、显示,能运用所学知识并学会查阅有关资料,培养仪器仪表设计的基本技能,为今后的深入学习等奠定基础。

1.3 设计要求

参考利用存储电路、IC卡、单片机及其接口技术研制出一种新型电能表,设计内容包括:

(1)详细了解所选用的存储电路、IC卡、单片机的工作原理和工作特性; (2)设计合理的计算测量电路;

(3)用单片机、IC卡、LCD的显示技术实现测量电路,单片机的指令系统开发相关的应用程序,并对程序作详细的分析和解释。

(4)列出制作该装置的元器件,搭建试验电路,并进行试验验证调试。 (5)撰写详细的设计技术报告。

1.4 设计方案与技术分析

此电能表主要由计量模块、单片机、IC卡模块、LCD显示、EEPROM存储器、实时时钟电路及电源电路等部分组成。其硬件系统框图如下图1所示。其中,单片机以AT89C51为电能表的核心控制芯片,它是电能表的“大脑”,外围所有的硬件模块都是在它的控制协调下进行工作的。单片机通过控制在其中的各种程序,控制着其它硬件模块的工作状态,由它智能化地形成并可靠地提供电能计算、时段判断、费率切换、IC卡读写、电能量控制及负荷控制等功能。

1.4.1 AT89C51单片机简介 Ⅰ、89C51单片机的基本组成

本电能表的硬件设计原则是在低功耗的前提下,实现多功能目的,该芯片功耗低,特别适用于电能表控制线路多、功能全、功耗低的要求。它能方便地读取IC卡的数据,并控制液晶显示器的工作,同时还可以将电能表的数据存入EEPROM进行永久保存并可通过串口送至表外的数据终端,大大地提高了电能表的智能化功能。在一小块芯片上,集成了一个微型计算机的各个组成部分,即89C51单片机芯片内包括:

(1)一个8位的微处理器(CPU)。

(2)片内256字节数据存储器RAM/SFR,用以存放可以读/写的数据,如运算的中间结果、最终结果以及欲显示的数据等。

(3)片内4KB程序存储器Flash ROM,用以存放程序、一些原始数据和表格。 (4)4个8位并行I/O端口P0-P3,每个端口既可以用作输入,也可以用作输出。 (5)两个16位的定时器/计数器,每个定时器/计数器都可以设置成计数方式。 (6)具有5个中断源、两个中断优先级的中断控制系统。

LCD显示 IC卡模块 EEPROM 存储器 单片机(AT89C51) 电能 计量芯片 实时时钟电路 图1 硬件系统框图

电源电路

(7)一个全双工UART的串行I/O口,用于实现单片机之间或单片机与PC机之间的串行通信。

(8)片内振荡器和时钟产生电路,但石英晶体和微调电容需要外接。 (9)具有节电工作方式,即休闲方式和掉电方式。 以上各个部分通过片内八位数据总线相连接。 Ⅱ、89C51单片机引脚及其功能

如图2所示为单片机AT89C51的引脚图。

1

图2 单片机AT89C51的引脚图

(1)XTAL1(19脚):振荡器反相放大器及内部时钟发生器的输入端。 (2)XTAL2(18脚):振荡器反相放大器的输出端。

(3)RST(9脚):复位输入,当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。

(4)P0口(39~32脚):P0口是一个漏极开路的8位准双向I/O端口。作为漏极开路的输出端口,每位能驱动8个LS型TTL负载。当P0口作为输入口使用时,应先向口锁存器写入全1,此时P0口的全部引脚浮空,可作为高阻抗输入。

(5)P3口(10~17脚):P3口是一组带有内部上拉电阻的8位双向I/O多功能口。P3口输出缓冲器可驱动4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口,此时,被外部拉低的P3口将用上拉电阻输出电流。当CPU不对P3口进行SFR寻址访问时,即用作第二功能输出/输入线时,由内部硬件使锁存器Q置1。

整个PEROM阵列和三个锁定位的电擦除可通过正确的控制信号组合,并保持ALE管脚处低电平10ms来完成。在芯片擦除操作中,代码陈列全被写“1”且在任何非空存储字节被重复编程以前,该操作必须被执行。此外,AT89C51设有稳态逻辑,支持两种软件可选的掉电模式。在闲置模式下,CPU停止工作。但RAM,定时器,计数器,串口和中断系统仍在工作。在掉电模式下,保存RAM的内容并且冻结振荡器,禁止所用其他芯片功能,直到下一个硬件复位为止。

1.4.2 电能计量芯片模块

采用现在比较流行的电能计量芯片CS5460A实现对电能等电量的采集和测量。CS5460A 是Crystal 公司推出的用于测电流、电压、功率等的芯片, 是CS5460 的增强版, 精度高、性能强且成本低。CS5460A 包含两个ΔΣ模-数转换器(ADC)、高速电能计算功能和一个串行接口的高度集成的ΔΣ 模-数转换器。它可以精确测量和计算有功电能、瞬时功率、IRMS

2

和VRMS ,用于研制开发单相2 线或3 线电表。CS5460A可以使用低成本的分流器或互感器测量电流,使用分压电阻或电压互感器测量电压。CS5460A具有与微控制器通讯的双向串口,芯片的脉冲输出频率与有功能量成正比。CS5460A 具有方便的片上AC/DC 系统校准功能。“自引导”的特点使CS5460A 能独自工作,在系统上电后自动初始化。在自引导模式中,CS5460A 从一个外部EEPROM 中读取校准数据和启动指令。使用该模式时,CS5460A 工作时不需要外加微控制器,因此当电表用于大批量住宅电能测量时,可降低电表的成本。并且本芯片集成度较高便于编程控制,故本设计采用此方案。 CS5460A概述 Ⅰ、基本结构及功能

图3 CS5460内部结构图

CS5460A的内部机构图如上图3所示,其组成模块如下: 2 一个电流通道可编程增益放大器其增益为10和50可选 2一个电压通道固定增益放大器,其增益为10 2两个同时采样的AD模数转换器 2两个高速数字滤波器 2两个可选用的高通滤波器 2一个功率计算引擎 2一个片内电压基准

2一个可以检测电力不足或电源故障的电源监视器 2 一个持续监视串口通讯的看门狗 2 一个可选的内部时钟发生器 2 一个双向串行接口

3

2 一个电能、脉冲变换器 2 一个校准用SRAM Ⅱ、主要特性

(1)在片计算和处理功能;

(2)可以从串行E2PROM 智能“自引导”,不需要微控制器,具有电能-脉冲转换功能; (3)具有AC或DC系统校准功能;

(4)具有简单的三线数字串行接口,可以方便地进行读写; (5)看门狗定时器;

(6)片上 2.5 V 基准(60310-6/OC),单电源 +5 V 或双向 2.5V±10℅电源; (7)具有功率方向输出指示;

(8)能够测量瞬时电压、瞬时电流、瞬时功率、电能、电压有效值和电流有效值,能完成电能/脉冲转换;

(9)电能测量精度:0.1%;

(10)具有相位补偿和系统校准功能; (11)具有机械计度器/步进电机驱动器; (12)内带电源监视器;

(13)电能数据线性度:在1000 :1 动态范围内线性度为 ±0.1%; (14)功率消耗<12mW;

(15)电源配置: VA+=+5V,VA-=0V;VD+=+3V至+5V 或VA+=2.5V,VA-=-2.5V;VD+=+3V 1、控制命令字

CS5460A 包含一系列控制命令,对CS5460A 写入指定的控制字,即可完成相应的操作。这些控制命令包括:

(1)、启动转换命令(Oxe8)

只要对CS5460A 写OXE8 控制命令,CS5460A 即开始进行AD 转换,并输出计算结果,这

个命令一般在CS5460A 复位操作完成后输入,以使CS5460A 进入正常工作状态。 (2)、同步命令0(OXFE)及同步命令1(OXFF)

这两个命令主要用在一连串的读写命令之前,复位串行通信接口。 (3)Power_up/Halt Control(OXAO)

这个命令主要用在系统校准之前,以中断CS5460A 正在执行的操作,而执行系统校准命令。

(4)系统校准命令字:1 1 0 V I R G O

这个命令完成指定的某项系统校准。V、I、R、G、O 的说明如下:

4

电时可利用电池或大容量电容器为显示各项参数提供能量,并且比较美观。液晶显示模块选用图形液晶显示模块GXM12864,它内含KS0108B/HD61202控制器,是一种采用低功耗CMOS技术实现的点阵图形LCD模块,有8位的微处理器接口,通过内部的128364位映射DDRAM实现128点364点大小的平板显示。该液晶显示模块使用KS0108B作为列驱动器,同时使用KS0107B作为行驱动器。KS0107B不与CPU发生联系,只要提供电源就能产生行驱动信号和各种同步信号,比较简单。

液晶显示模块GXM12864的工作原理图如图8所示。

图8 LCD显示模块GXM12864的工作原理图

电位器R15的作用是调节提供给驱动器的供压,从而调节液晶显示的对比度。RST是复位脚,接高电平Vout1。数据线DB0~DB7和单片机的P0口相连,控制线D/I、R/W和片选线/CSA、/CSB分别与单片机P2口的6、5、1、0脚相连,使能线与P2.3相连。

在进行液晶显示模块的硬件调试时务必注意正确的接线,尤其是正负电源的接线不能有错,否则会烧坏电路上的芯片。为避免液晶模块的损坏,在加液晶驱动电压V0/VEE时需要比加逻辑电压VDD滞后50ms;在关电时,液晶驱动电压V0/VEE需要比逻辑电压VDD提前50ms关断。

GXM12864的引脚定义如表1所示。

表1 GXM12864的引脚定义

引脚名称 /CSA、/CSB 引脚定义 片选1、2 10

VSS VDD V0 D/I R/W E DB0-DB7 RST VEE A、K 数字地 逻辑电源+5V 对比度调节 指令数据通道 读/写选择 使能信号、高电平有效 8位数据线 复位信号 液晶驱动电源 背光正电源端、背光接地端

1.4.5 电源电路模块

在一般情况下,液晶器件的驱动需要两种不同的电源电压,一种是+5V(工作电压),另一种是-10V(背景光对比度调节电压)。所以,使用液晶模块时,需要设计专门的液晶电源电路。液晶电源电路的作用就是将电压转换成这两种电压信号输出,为液晶显示模块提供工作电压。

本设计中系统采用电池供电,其输入电压为+3V,所以电源部分的设计要求为+3V输入,+5V和-10V双电压输出。

MAX1677是双电压输出升压DC-DC变换器,它是一种专门为LCD提供电源的芯片,可以产生两种可调电压输出。其输入电压范围(0.7-5.5V)较大,可以依据不同系统提供的安装电池的空间和所需的不同电池电压与容量,灵活的选择电池的种类。

电源模块电路如图9所示。图中,MAX1677的输入电压Vin=3V,输出两路电压Vout1和Vout2,分别是+5V和-10V,+5V为系统电源,而-10V作为液晶显示模块的背光电源。

11

图9 直流电源的设计

电路中的其他器件说明如下。

L1、L2为CoilCraft的DO1608C-103表贴磁芯电感,电感值为10Uh。

D1、D2是反相耐压大于16V的肖特基二极管,也可选用具有相同耐压参数的其他型号二极管。

电阻R11和R12的比值决定了主输出电压值Vout(对应图中的Vout1)需满足下面的公式:

R11=R12*[Vout/1.25-1] (R12的取值范围为10-200千欧姆)

电阻R14和R13的比值决定了LCD对比度输出的电压值VLCD(对应图中的Vout2)需满足下面的公式:

R14=R13*|VLCD|/1.25(V) (R14的取值范围为500-2000千欧姆)

电阻R8和R7的比值决定了系统欠电压监测的门槛电压值VTRIP需满足下面的公式: R8=R7*[VTRIP/0.614-1] (R7≤130千欧姆)

当电池正常时,电池电压过低,输出引脚LBO输出保持高电平;一旦电池电压低于门槛电压,LBO引脚输出为低电平。如果不是用欠电压监测的话,只需要将第三引脚(LBI)接地即可。

在原理图中,Vin为电源电路的输入端,连接两节1.5V的电池形成便携式仪表的电源;Vout1连接MAX1677的第16引脚,输出+5V的电压,作为系统的电源电压;Vout2连接MAX1677的10引脚,输出-10V的电压,作为液晶显示模块的背光电源电压。 前端电路调理模块的设计 1、电压调理部分

对于系统的前端电压调理部分,我们采用变比为2mA/2mA的电流互感器和高精度电阻作

12

为输入电路部分电路如图10所示。系统设计采用220V的市电电压输入,首先外接Rx=110k电阻得到2mA的电流,然后通过变比为2mA/2mA的互感器,然后在二次侧连接1个125Ω的定值电阻得到所需的输入电压,可以为CS5460A提供电压信号,不超出芯片的测量范围。当然电阻R2值可以根据不同的电压来调整。并加入RC滤波网络对信号初步滤波,并加入放抖动电容保护芯片。 2、电流调理部分

电流调理部分采用变比2000:1 的电流互感器,然后经一精密电阻将电流信号转变成电压信号。并加入RC滤波网络对信号初步滤波,并加入放抖动电容保护芯片。经变换后的补测信号以差模电压的形式接到CS5460A的模拟信号输入端。由于互感器角差的影响,可能造成输入信号的相移,使功率测量的误差增大。而CS5460A 具有相位补偿功能(可进行-2.4°至+2.5°的相位补偿,步进0.34°),可以大大减小互感器角差的影响。

图10 前端调理电路

1.4.6 实时时钟电路模块

分时计费电度表中利用单片机内部定时器作为时钟基准,无需附加外部元件,通过软件编程和单片机内部的中断就可实现实时时钟功能。但是这种做法有很多缺点。由于受到单片机主晶振以及与其相连电容的影响较大,无法做到很高的精度,累计误差大。主电源掉电时为了维持时钟不停,必须要有外接电池给整个单片机供电,导致仪表本身功耗增大。外接专用实时时钟是一种专门用于产生同期时钟信息的集成电路芯片,它可以独立于单片机而工作,不受MCU主晶振及其电容的影响,计时精确,月累积误差一般小于lOs。芯片还具有主

13

电源掉电情况下的时钟保护电路和备份电源自动切换控制电路,可以保证在主电源掉电和其他一些恶劣环境下系统实时实钟的定时准确性。实时时钟芯片内部集成有一定容量,具有掉电保护特性的静态RAM,可用于保存一些重要数据。由于芯片可独立工作,主电源掉电时备份电源只需为该时钟芯片供电,可有效降低仪表功耗。实时时钟芯片与单片机的接口根据其数据传送方式可分为两种:一种是以并行方式与MCU接口,其数据传送速度较快,但接口扩展电路较复杂,需要考虑接口扩展时的驱动能力,而且并行接口芯片本身占用较大的印制版空间,连线多,不利于缩小仪表体积。另一种是以串行方式与MCU接口,这种芯片通常为8脚DIP封装,占用空间小,连线简单,一般只需占用CPU的2至3条I/O口线,可有效减小仪表体积,提高工作可靠性。本设计中采用DSl302芯片,它是美国DALLAS公司推出的串行接口专用实时时钟芯片。芯片内部具有可编程日历时钟和31个字节的静态RAM,日历时钟可自动进行闰年补偿,计时准确,接口简单,工作电压范围(2.5V至5.5V),功耗低芯片自身还具有对备份电池进行涓流充电的功能,有效延长了备用电池的使用寿命。时钟芯片DSl302的接口电路如图11所示。

图11 时钟芯片DSl302的接口电路

采用三线串行通讯方式,/RST为通信允许信号,/RST=l,允许通信,/RST=0禁止通信。SCLK为串行数据的位同步脉冲信号。为双向串行数据传送信号。AT89C51单片机通过控制/RST,SCLK和I/O信号实现两芯片的数据传送。DSl302芯片的X1和X2端外接32.768KHz的石英晶振,VCCl和VCC2是电源引脚,单电源供电时接VCCl脚,双电源供电时主电源接VCC2脚,采用可充电电池,启用内部涓流充电器在主电压正常时向电池充电,以延长电池使用时间。备份电池也可以使用1微法以上的超容量电容代替,需要注意的是备份电池电压应略低于主电源工作电压。

数据传送是以AT89C51单片机为主控芯片进行的,每次传送时由AT89C51向DSl302写入一个命令字节开始。命令字节格式如图12所示:

14

图12 命令字节格式

命令字节的最高位必须为l,RAM/CK位为RAM/时钟选择位,RAM/CK=l选择RAM操作,RAM/CK=0选择时钟操作。A4至A0为片内日历时钟寄存器或RAM地址选择位。选择时钟操作时A4至A0为00H至06H对应日历时钟寄存器地址,分别存放秒,分,时,日,月,星期,和年等信息。秒寄存器的最高位为时钟暂停控制位,该位为0时时钟振荡器暂停,DSl302进入低功耗状态,该位为1时启动时钟。地址07H为写保护寄存器,用以控制对片内日历时钟寄存器的写允许,地址08H为涓 流充电控制寄存器,控制内部涓流充电过程及充电电路的连接方式。

选择片内RAM操作时A4至AO用于表示片内RAM单元地址,地址范围为 00H~1EH,RD/W位为读写控制位,RD/W=1为读操作,表示DSl302接受完命令字节后,按指定的选择对象及寄存器(或RAM)地址,读取数据并通过I/O线传送给单片机AT89C51,RD/W=0为写操作,表示DSl302接受完命令字节后,紧跟着再接收来自于单片机AT89C51数据字节并写入到DSl302相应的寄存器或RAM单元中。DSl302与AT89C51之间通过I/0线传送串行数据,SCLK为串行通信时的位同步时钟,一个SCLK脉冲传送一位数据。每次数据传送时都以字节为单位,低位在前,高位在后,传送一个字节数据需要8个SCLK脉冲。字节传送时序如图13所示:

图13 字节传送时序

1.4.7 IC卡模块 1、Mifare 1射频IC卡

Mifare 1射频IC卡的核心是Philips公司制造的Mifare 1 IC S50系列微晶片,其内部包括1KB高速EEPROM、数字控制模块和一个高效率射频天线模块。卡片本身不带电池供电,工作时将卡片放在读写器的有效工作区域,卡片读写器的天线发送无线电载波信号耦合到卡片上的天线提供电源能量,其电压可达2V以上,足以满足卡片上的IC电路供电需要。在信道保证和数据完整性方面,Mifare 1标准还提供了信道检测、存储数据冗余校验、三次传递认证以及防冲突机制等功能,保证了数据交换过程的安全。Mifare 1射频IC卡的主要性能指标如下。

(1)1KB的EEPROM,分为16个扇区,每个扇区分为4块,每块16B,以块为存取单位。 (2)每个扇区有独立的一组(2个)密码及存取权限设置。 (3)每张卡有唯一的32位序列号。

15

(4)具有防冲突机制、支持多卡操作。

(5)无电源,自带天线,内含加密控制逻辑和通信逻辑电路。 (6)数据可保存10年,可反复写10万次。 (7)工作频率为13.56MHZ。 (8)106kbps 的快速数据传输速率。

(9)读写距离最大可达10cm(取决于天线设计)。 (10)工作温度范围:-20-- +50。C。

Mifare 1射频卡包含了两个部分:RF射频接口电路和数字电路部分。 2、H6152读写模块

图14 H6152基本结构示意图

H6152的基本结构如图14所示。图中,对外通信的接口为J3和J4。

J3口共有7针,包括RS-232/422的接口引脚和读写器模块的电源端,接地端,J4口为4针接口,提供电源和操作状态的LED灯指示信号,H6152读写模块操作简单方便,读写过程稳定有效。它集成了PCB板载天线电路和RS-232/422接口的集成读写模块,还提供了RS-232/422接口与TTL接口的转换电路。H6152需外界+5V电源供电。主要性能指标如下:

(1)工作频率:13.56MHz。

(2)串行通信波特率:9600bps、19200bps、38400bps和57600bps4种可选。 (3)接口:RS-232/422/485。 (4)天线输出阻抗:50K欧姆。 (5)天线尺寸:45mm370mm。 (6)电源电压:+5V。 (7)电流供应:80mA。 (8)工作温度:-40~+85℃. (9)最大读写距离:50mm。

16

3、IC卡读写电路的原理及说明

IC卡应用系统的硬件设计结构框图如图15所示。单片机AT89C51是本设计的核心器件,它主要完成了对射频卡(MIFARE 1卡)的读写操作。H6152读写器对射频卡进行读写后通过串口电平转换电路将RS-232电平转换为单片机所识别的TTL电平,从而达到了使用AT89C51单片机来控制射频卡的读写过程。

报警电路

单片机 AT89C51 串口电平 转换电路 IC卡 IC卡读写器

图15 硬件设计结构框图

硬件电路由单片机模块、串口电平转换模块和H6152读写模块3部分电路组成,其工作原理分别如图16、图17、图18所示。

图16 单片机模块

17

图17 串口电平转换模块

图18 H6152读写模块

U1为单片机芯片AT89C51,其P1.0脚为单片机对H6152的控制输出,它控制H6152的工作状态,该引脚为高电平时,H6152停止工作;P1.1脚为单片机对蜂鸣器的控制输出,为低电平时,蜂鸣器发出蜂鸣声。XTAL0 和 XTAL1 分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器,石晶振荡和陶瓷均可采用。如采用外部时钟源驱动器件,则XTAL1不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。本设计的外部时钟电路是将XTAL0(18脚)和XTAL1(19)脚分别对接外部晶体和微调电容的两端所构成。另外单片机中还带有复位端,为了安全方便,单片机采用了上电自动复位和手动复位两种。

串口电平转换电路采用Maxim公司的MAX3232实现。MAX3232将单片机的TTL电平转为RS-232,然后与H6152的RS-232接口直接相连。RS-232C是数据终端设备(DTE)和数据通信设备(DCE)之间的接口标准,是在微机接口应用中常用的一种串行通信总线标准,全称为EIA-RS-232C标准(Electoronic Industrial Associate Recommended Standard-232C)。

18

RS-232C标准的信号线共25根,其中只定义了22根。这22根信号线又分为主、辅两个信道,大多数微机串行通信系统中都只使用主信道的信号线。在通信中,即便是只使用主信道,也并非主信道的所有信号都要连接,一般情况下只需使用其中的9根信号线,这就是为什么在微机的机箱上串行通信接口(如COM1、COM2)只有9根的原因。RS-232C串行通信接口标准中,对于发送端,规定-5V~-15V表示逻辑“1”(MARK信号),用+5V~+15V表示逻辑“0”(SPACE信号),内阻为几百欧姆,可以带2500pF的电容负载。负载开路时电压不得超过±25V。对于接收端,电压低于-3V表示逻辑“1”,高于+3V表示逻辑“0”。 1.4.8 电能表程序设计

如图19所示为电能表主流程图:

开始 电能采集 实时时钟 是峰电? 谷电加 峰电加 数据存储 LCD显示 IC卡<5° 断电

图19 主流程图

程序如下: #include #include #include sbit SDA=P1^3;

19

sbit SCL=P1^4;

#define uchar unsigned char #define lcd P0 sbit rw = P2^5 sbit rs = P2^2 sbit e= P2^3 sbit busy=ACC^7 unsigned char count

unsigned char timer //峰谷时钟 unsigned countA unsigned countB

unsigned count1 //峰值电量 unsigned count2 unsigned count unsigned decount countA=0;

void main() //主函数程序 {

countB=Read Memory(); //读电量计数模块值 decount=countB-countA;

//判读前后两次读入的值是否一样,一样则重新循环,不

//谷值电量

一样则开始计数;

while(decount==0) { }

20

count++; while(count<100) {

timer=readbyte(); //读峰谷时间 if(timer>12)

count1++ ;

else

count2++ ;

Remain=total-count1*0.5-count2*0.6;

//计算剩余的金额

write(count1); }

write(count2); write(Remain);

//向IC卡内分别写入峰值电量、谷值电量、剩余金额

}

if(remian<5.0) flag=1;

//如果剩余金额不足则置报警显示位

unsigned char Control,enum eepromtype enumer) // EEPROM程序 {

void Delay(unsigned char DelayCount); /* 延时 */ void Start(void); /* 启动总线 */ void Stop(void); /* 停止IIC总线 */ bit RecAck(void); /* 检查应答位 */

void NoAck(void); /* 不对IIC总线产生应答 */ void Ack(void); /* 对IIC总线产生应答 */

unsigned char Receive(void); /* 从IIC总线上读数据子程序 */ void Send(unsigned char sendbyte); /* 向IIC总线写数据 */ unsigned char data j,i=ERROR; bit errorflag=1; /* 出错标志 */ while(i--) {

Start(); /* 启动总线 */

Send(Control & 0xfe); /* 向IIC总线写数据,器件地址 */ if(RecAck()) continue; /* 如写不正确结束本次循环 */ if(RecAck())continue; }

Send((unsigned char)Addr); /* 向IIC总线写数据 */ if(RecAck()) continue; /* 如写正确结束本次循环 */ if(!(Control & 0x01)) //判断是读器件还是写器件 {

j=Length;

errorflag=0; /* 清错误特征位 */ while(j--) {

Send(*DataBuff++); /* 向IIC总线写数据 */ if(!RecAck()) continue; /* 如写正确结束本次循环 */ errorflag=1; break;

21

}

if(errorflag==1) continue; break;

} else {

Start(); /* 启动总线 */

Send(Control); /* 向IIC总线写数据 */

if(RecAck()) continue;//器件没应答结束本次本层循环 while(--Length) /* 字节长为0结束 */ {

*DataBuff ++= Receive(); Ack(); /* 对IIC总线产生应答 */ }

*DataBuff=Receive(); /* 读最后一个字节 */ NoAck(); /* 不对IIC总线产生应答 */ errorflag=0; break; }

Stop(); /* 停止IIC总线 */ if(!(Control & 0x01)) {

Delay(255); Delay(255); Delay(255); Delay(255); return(errorflag); }

/* * * * * 以下是对IIC总线的操作子程序 * * * * */ /* * * * * * 启动总线 * * * * */ void Start(void) {

SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */ SDA=1; /* 一个 \开始 \状态,该状态必须在其他命令之前执行 */ SCL=1;

_nop_(); _nop_(); _nop_(); SDA=0;

_nop_(); _nop_(); _nop_(); _nop_(); SCL=0; SDA=1;

22

}

/* * * * * 停止IIC总线 * * * * */ void Stop(void) {

SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */ SDA=0; /*表示一个 \停止 \状态,该状态终止所有通讯 */ SCL=1;

_nop_(); _nop_(); _nop_(); /* 空操作 */ SDA=1;

_nop_(); _nop_(); _nop_(); SCL=0; }

/* * * * * 检查应答位 * * * * */ bit RecAck(void) {

SCL=0; SDA=1; SCL=1;

_nop_(); _nop_(); _nop_(); _nop_();

CY=SDA; /* 因为返回值总是放在CY中的 */ SCL=0; return(CY); }

/* * * * *对IIC总线产生应答 * * * * */ void Ack(void) {

SDA=0; /* EEPROM通过在收到每个地址或数据之后, */ SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */ _nop_(); _nop_(); _nop_(); _nop_(); SCL=0; _nop_(); SDA=1; }

/* * * * * * * * * 不对IIC总线产生应答 * * * * */ void NoAck(void) {

SDA=1;

23

SCL=1;

_nop_(); _nop_(); _nop_(); _nop_();

SCL=0;

}

/* * * * * * * * * 向IIC总线写数据 * * * * */ void Send(unsigned char sendbyte) {

unsigned char data j=8; for(;j>0;j--) {

SCL=0;

sendbyte <<= 1; /* 使CY=sendbyte^7; */ SDA=CY; /* CY 进位标志位 */ SCL=1; } SCL=0; }

/* * * * * * * * * 从IIC总线上读数据子程序 * * * * */ unsigned char Receive(void) {

register receivebyte,i=8; SCL=0; while(i--) {

SCL=1;

receivebyte = (receivebyte <<1 ) | SDA; SCL=0; }

return(receivebyte); }

/* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */ void Delay(unsigned char DelayCount) {

while(DelayCount--); }

void lcd_mwcode(uchar i) //LCD液晶显示, { rw=1;

24

rs=0;

lcd=0; e=1; do {

ACC=lcd; //是否忙

e=0; }

while(busy); rw=0; lcd=i; e=1;

e=0; }

void lcd_mwdata(uchar i) //输入数据, { rw=1; rs=0; lcd=0; e=1; do {

ACC=lcd; e=0; }

while(busy); rw=0; rs=1; lcd=i; e=1; e=0; }

void setpos(uchar row , uchar col) //选择行,列, {

lcd_mwcode(0xb8+row); lcd_mwcode(0x40+col); }

void lcd_init(void) //初始化 {

lcd_mwcode(0xc0); lcd_mwcode(0x3f); }

25

void disp1(uchar code *hz) //显示汉字上半区, {

uchar i;

for(i=0;i<16;i++) lcd_mwdata(*(hz+i)); }

void disp2(uchar code *hz) //显示汉字下半区 , {

uchar i;

for(i=16;i<32;i++) lcd_mwdata(*(hz+i)); }

void select(uchar x)

{

switch(x) {

case 1:cs1=0;cs2=1;break; //左屏, case 2:cs1=1;cs2=0;break; //右屏, default :cs2=0;cs2=0;} } }

uchar readbyte(temp) //时钟程序 {

uchar i; Iongdelay0; temp=0; for(i=0;i<8;i++)

{

temp=temp>>1:

if(dat==1)temp=temp+0x80; clk=1:

shortdelay0;

clk=0; //时钟下降沿读出有效 shortdelay0; }

return temp; }

uchar DateWrite(1ong *_Value,uchar_LgeAdr,uchar_block,uchar idata * _ bur) 序

26

// IC卡程

{

uchar temp=(uchar * )_Value; //转存指针 uchar writecheck=DATA_ERR; //写入状态标记,用于返回值 _buf[0]=* (temp+3); _buf[1]=* (temp+2);

_buf[2]= (temp+1);

_buf[3]=*temp; //数据转存到缓冲区 _ buf[4]=~_buf[0]; _buf[5]=~_buf[1]; _buf[6]= _buf[2];

_buf[7]=~_buf[3]; //值备份 _ buf[8]=_bur[0]; _buf[9]=_buf[1]; _buf[10]= _buf[2]; _buf[11]=_buf[3]; _ buf[12]=_LgeAdr;

_buf[13]=~_LgcAdr; _bull14]=一LgcAdr;

_buf[15]=~_LgcAdr; //转存地址,并备份

writecheck= writecheck & mifs_write(_block+1,_buf); //将数据写入备份块 writecheck= writecheck& mifs_ write(_block,_buf); //将数据写入数据块 retum writecheck; //返回最终发送状态

}

reset_5460=0; //reset_5460 为CS5460A 的复位脚 //计量模块 Delay_10MS();

reset_5460=1; //复位CS5460A buf[0]=0xff; //SYNC1 buf[1]=0xff; //SYNC1 buf[2]=0xff; //SYNC1

buf[3]=0xfe; //SYNC0

Write_CS5460A(buf,4); //写3 个同步命令1 之后再写1 个同步命令0 buf[0]=0x40; //写配置寄存器

buf[1]=0x01; //GI=1,电流通道增益=50 buf[2]=0x00;

buf[3]=0x01; //DCLK=MCLK/1 Read_Memory(&temp,phase_addr,1); if(temp==0xA5) {

Read_Memory(&temp,phase_addr+1,1); buf5460[1]=temp;

}

//假如已经执行过相位补偿,设置相位补偿值,否则设置相位补偿值为0 Write_CS5460A(buf,4);

27

//假如指定地址单元等于OXA5,则接下来的3BYTES 即是校准值。 buf[0]=0x5e; buf[1]=0xff; buf[2]=0xff; buf[3]=0xff;

Write_CS5460A(buf,4); //清状态寄存器 buf[0]=0x74; buf[1]=0x00; buf[2]=0x00;

buf[3]=0x00;

Write_CS5460A(buf,4); //写中断屏蔽寄存器,缺省值 buf[0]=0x78;

buf[1]=0x00; buf[2]=0x00;

buf[3]=0x00; //缺省值

Write_CS5460A(buf,4); //写控制寄存器 buf[0]=0x4c; buf[1]=0x00; buf[2]=0x34;

buf[3]=0x9C;

Write_CS5460A(buf,4); //写EOUT 脉冲输出寄存器 buf[0]=0x4A; buf[1]=0x00;

buf[2]=0x01; //每秒钟计算10 次,N=400

buf[3]=0x90;

Write_CS5460A(buf,4); //写CYCLE COUNT 寄存器 Read_CS5460A(0x1e,buf); //读状态寄存器 Buf[3]=buf[2]; Buf[2]=buf[1]; Buf[1]=buf[0];

Buf[0]=0X5E;

Write_CS5460A(buf,4); //写状态寄存器 Buf[0]=0xe8;

Write_CS5460A(buf,1); //启动CS5460A }

1.5 实验验证与结论

根据方案设计的要求,测试过程共分为三大部分:硬件调试、软件调试和软硬件联调。电路按模块调试,各模块逐个调试后,再进行联调。单片机软件先在最小系统板上调试,确保外部电路正常工作后,再与硬件系统联调。 1.5.1 电能表硬件调试

硬件调试,查看个硬件模块电路的连线是否与逻辑图一致,用万用表检测有无短路或短路现象,器件的规格、极性是否有误。检查完毕,用万用表测量一下电路板正负电源端之间

28

示。

1.5.4 实验结论

1.5.2 电能表软件调试

1.5.3 电能表软硬件联调

的电阻,排除电源短路的可能性。

合,通过不断地实践才能很好的解决困难,从而达到我们的设计目标。

能判断语法差错和逻辑差错,判断程序无误后,可以直接下载到单片机中进行调试。

准调试。调好后,即该芯片能正常工作后,再通以交流市电进行进一步校准调试。等模块逐

一调通后,再进行联调。再连接成一个完整的系统调试。电能表总硬件电路图如下图19所

在软件和硬件都基本调通的情况下,进行系统的软硬件联调。按照由上向下,模块化设

的各个模块以及主程序进行编程,从理论上基本能实现电能表的设计要求,在设计过程中通

思路以及方向,也学到了不少知识,让我们深刻地领会到做一项设计要具备持之以恒,要有

过各种方法的搜索资料,也让我们学到了不少的搜索方法,并且也大致了解了在做项目中的

流通道通入满量程信号,根据液晶显示对芯片内的校准寄存器进行设置,进而对测量进行校

以致没有完全达到我们的预期设计目标,这也提醒我们在今后的设计中要把理论与实践多结

计的理念对模块逐个调试:首先,调通液晶显示模块,接着给芯片CS5460A的电压通道和电

在这段时间里,在电能表硬件部分设计好的同时,在软件方面,我们用C语言对电能表

本系统的软件调试因AT89C51核心模块的使用而变得相对容易,keilc软件开发环境,

严谨的设计思路。由于我们对C语言编程知识的有限,在调试过程中没有进行充分的调试,

29

图19 电能表总硬件电路图

30

本文来源:https://www.bwwdw.com/article/wr57.html

Top