基于51单片机的电表电量采集系统程序

合集下载

基于51单片机的电压采集与显示系统设计

基于51单片机的电压采集与显示系统设计

课程设计题目:51单片机的电压采集与显示系统设计专业:电气工程及其自动化班级:学号:学生姓名:指导教师:2010 年 9 月5 日摘要随着电子科技的不断发展与进步,电压测量成为广大电子领域中必须掌握的过程,并且对测量的精度和采集功能的要求也越来越高,而电压的测量与显示系统甚为重要。

本文介绍的重点是电压数据的采集与显示系统,数据采集与通信控制采用了模块化的设计,数据采集与通信控制采用了单片机8051来实现,硬件部分是以单片机为核心,还包括模-数转换模块,显示模块,和串行接口部分,还有一些简单的外围电路。

8路被测电压通过通用ADC0809模-数转换,实现对采集到的数据进行模拟量到数字量的转换,由单片机对数据进行处理,用数码管显示模块来显示所采集的结果,由相关控制器完成数据接收和显示,VB程序编写了更加明了化数据显示界面。

本系统主要包括四大模块:数据采集模块、控制模块、显示模块、A/D转换模块。

绘制电路原理图与工作流程图,并进行调试,最终设计完成了该系统的硬件电路。

在软件编程上,采用了C语言进行编程,开发环境使用相关集成开发环境。

开发了显示模块程序、通道切换程序、A/D转换程序。

关键词:单片机, ADC0809,A/D转换,模块显示电压测量AbstractAlong with the development of electronic technology progress, voltage measurement of electronic fields become broad must grasp of the process, and the accuracy of measurement and collection function requirements, and more and more is also high voltage measurement and display system is very important. This paper focuses on voltage data acquisition and display system, data collection and communication control using modular design, data collection and communication control adopted MCU 8051, hardware part is, still include singlechip mode - several conversion module, display module, and the serial interface, and some simple outer circuit.8 and the voltage to be measured by general ADC0809 mode - and to count the collected data for analog to digital, by SCM processing of data, using a digital display module to show the tube, the related results of collecting data receiving and display controller, VB programming and the data showed that the interface. This system mainly including four modules: the data acquisition module, control module, display module, A/D conversion module. Draw circuit principle diagram and the work flow, and debugging, finally completed the system design of hardware circuit. In software programming, the C language program development environment, use the integrated development environment. Develop A display module procedures, channel switching procedures, A/D conversion program..Keywords: SCM, ADC0809, A/D conversion, module display voltage measurements.目录1引言 (6)2课程设计题目、任务及要求及方案 (7)3电路原理说明 (9)3.1ADC0809模数转换芯片 (9)3.2 AT89C51单片机 (10)3.3八段数码管和74LS47 (10)3.4 系统整体工作原理 (11)3.4.1硬件原理 (11)3.4.2软件原理分析 (12)4设计总体框图 (16)4.1硬件总体框图 (16)4.2程序总体框图 (16)4.3待测信号源单元电路 (17)4.4 AT89C51单片机 (18)4.5单片机控制单元 (19)4.5.1外部时钟电路 (19)4.5.2复位电路 (20)4.5.3数码管显示模块 (21)5调试报告 (22)6 总结及设计心得 (23)参考文献 (24)附录.............................................. 2错误!未定义书签。

基于51单片机的直流数字电压表设计

基于51单片机的直流数字电压表设计

基于51单片机的直流数字电压表设计概述:直流数字电压表是一种用于测量直流电压的仪器,它通过将电压信号转换为数字形式,并显示在数码管上,实现对电压的准确测量。

本文将介绍基于51单片机的直流数字电压表的设计原理和实现方法。

一、设计原理:1.1 电压信号采集:直流数字电压表的第一步是采集待测电压信号。

常用的采集方法是使用一个分压电路将待测电压降低到合适的范围,再通过运算放大器将其放大到合适的电平。

51单片机的模拟输入引脚可以接受0-5V的模拟电压信号,因此可以直接将放大后的信号接入单片机进行采集。

1.2 模数转换:采集到的模拟电压信号需要经过模数转换(A/D转换)才能被单片机读取和处理。

51单片机内部集成了一个10位的A/D转换器,可以将输入的模拟电压转换为相应的数字量。

通过设置不同的参考电压和采样精度,可以实现对不同电压范围的准确测量。

1.3 数码管显示:经过模数转换后,得到的数字量需要通过数码管进行显示。

51单片机的IO口可以通过控制段选和位选的方式,将数字量转换为相应的数码管显示。

可以根据需要选择常用的七段数码管或者液晶显示屏进行显示。

二、设计实现:2.1 硬件设计:硬件设计包括电路原理图设计和PCB布局设计两个部分。

电路原理图设计主要包括电压采集电路、运算放大器、A/D转换器和数码管驱动电路等部分。

PCB布局设计需要考虑信号的走线和电源的分布,以保证电压信号的准确采集和显示。

在设计过程中,需要注意地线和信号线的分离,以减少干扰。

2.2 软件设计:软件设计主要包括单片机的程序编写和调试。

首先需要编写采集模拟电压信号和进行A/D转换的程序,将转换后的数字量存储在单片机的内部存储器中。

然后编写数码管驱动程序,将存储的数字量转换为相应的数码管显示。

最后,通过按键或者旋转编码器等方式,可以实现对量程和精度的选择。

三、设计优化:3.1 精度优化:为了提高直流数字电压表的测量精度,可以采用更高精度的A/D转换器,增加参考电压的精度,或者通过校准电路对测量误差进行校正。

51单片机数据采集系统

51单片机数据采集系统

课程设计报告书设计任务书一、设计任务1一秒钟采集一次。

2把INO口采集的电压值放入30H单元中。

3做出原理图。

4画出流程图并写出所要运行的程序。

二、设计方案及工作原理方案: 1. 采用8051和ADC0809构成一个8通道数据采集系统。

2. 能够顺序采集各个通道的信号。

3. 采集信号的动态范围:0~5V。

4. 每个通道的采样速率:100 SPS。

5.在面包板上完成电路,将采样数据送入单片机20h~27h存储单元。

6.编写相应的单片机采集程序,到达规定的性能。

工作原理:通过一个A/D转换器循环采样模拟电压,每隔一定时间去采样一次,一次按顺序采样信号。

A/D转换器芯片AD0809将采样到的模拟信号转换为数字信号,转换完成后,CPU读取数据转换结果,并将结果送入外设即CRT/LED显示,显示电压路数和数据值。

目录第一章系统设计要求和解决方案第二章硬件系统第三章软件系统第四章实现的功能第五章缺点及可能的解决方法第六章心得体会附录一参考文献附录二硬件原理图附录三程序流程图第一章系统设计要求和解决方案根据系统基本要求,将本系统划分为如下几个部分:●信号调理电路●8路模拟信号的产生与A/D转换器●发送端的数据采集与传输控制器●人机通道的接口电路●数据传输接口电路数据采集与传输系统一般由信号调理电路,多路开关,采样保持电路,A/D,单片机,电平转换接口,接收端(单片机、PC或其它设备)组成。

系统框图如图1-1所示1.1 信号采集分析被测电压为0~5V 直流电压,可通过电位器调节产生。

1.1.1 信号采集多路数据采集系统多采用共享数据采集通道的结构形式。

数据采集方式选择程序控制数据采集。

程序控制数据采集,由硬件和软件两部分组成。

,据不同的采集需要,在程序存储器中,存放若干种信号采集程序,选择相应的采集程序进行采集工作,还可通过编新的程序,以满足不同采样任务的要求。

如图1-3所示。

程序控制数据采集的采样通道地址可随意选择,控制多路传输门开启的通道地址码由存储器中读出的指令确定。

基于51单片机的PCF8591芯片电压表

基于51单片机的PCF8591芯片电压表

PCF8591芯片电压表一、功能1、用PCF8591芯片采集电压。

2、使用IIC通信协议进行通信。

3、四位数码管显示采集电压。

4、电压表有五个档位200MV、2V、20V、200V、500V。

5、四个按键进行档位切换。

6、五个LED指示灯1~5指示相应档位。

7、电压过大,继电器自动断开,保护电路。

8、滑动变阻器可以对电压表精确度进行调节,使测量更精确。

9、采用STC89RC52单片机。

10、电源供电采用USB电源头(发货中会赠送一根)供电,插到手机直充头上就可以正常使用。

二、硬件按键功能及说明档位1/2:200MV档位和2V档位切换,LED1/2亮。

档位3:切换到20V档位,LED3亮。

档位4:切换到200V档位,LED4亮。

档位5:切换到500V档位,LED5亮。

复位:对整个电路进行复位,回到初始化状态2V档位。

三、注意事项1、程序下载程序利用串口下载,首先将下载器正确连接(说明一下,板子上下载口从左到右依次接下载器的+5V、地、TX、RX,下载器上标的有),打开STC下载器如图。

选择STC89C52RC,点击“打开程序文件”选择程序文件夹中(Output-> 电压表.HEX)的温度控制.hex文件。

点击下载,当提示上电时拔下电源再插上就可以了。

2、按键使用如上图所示,档位1/2、档位3、档位4、档位5,以及复位五个按键。

具体按键功能在上边已经介绍。

3、使用说明刚开始使用是,不要测量高电压,应该先用低电压试试电压表好坏。

测量较高的电压时,要用最高档测量一下大致电压是多少,再换用合适档位进行精确测量。

因为不同型号的电源,导致单片机的工作电压和PCF8591芯片的基准电压,都不是标准的5V,所以在测量时会有误差,这时候就需要通过对电位器进行微调来调节误差,使测量更精确。

4、注意事项需要特别注意的是测量电压千万不要高于测量档位的电压,不然会因为瞬间电流过大,直接烧坏芯片,使电压表产生损坏。

因为操作不当造成的后果,我们一概不负责,一定要特别注意。

51单片机电池电量检测系统设计

51单片机电池电量检测系统设计

51单片机电池电量检测系统设计1. 简介本文档描述了一种使用51单片机设计的电池电量检测系统。

该系统旨在监测电池的电量,并通过51单片机进行数据处理和显示。

该系统适用于需要监测电池电量的各种设备,如智能手表、无人机等。

2. 系统设计2.1 系统架构该电池电量检测系统由以下主要组件构成:•51单片机:作为系统的核心处理器,负责数据采集、处理和显示。

•电压测量模块:用于测量电池的电压。

•LCD显示模块:用于显示电池电量信息。

•按钮模块:用于系统操作和设置。

2.2 硬件设计2.2.1 电压测量模块电压测量模块主要由一个ADC转换器组成,用于将电池电压转换为数字量,以便51单片机进行处理。

2.2.2 LCD显示模块LCD显示模块用于显示电池电量信息。

可以使用基于液晶技术的LCD模块,通过51单片机控制显示电池电量的百分比或其他信息。

2.2.3 按钮模块按钮模块用于系统的操作和设置。

可以通过按钮模块实现电池电量的复位、设置电池类型等功能。

2.3 软件设计2.3.1 系统初始化系统初始化时,51单片机将初始化ADC转换器、LCD显示模块和按钮模块。

设置合适的ADC参考电压,配置LCD显示模块的参数,并对按钮模块进行初始化。

2.3.2 电池电量测量系统将定时读取ADC转换器的数值,转换为电池电压。

然后,根据电池的电压和电池类型进行电量计算,并将计算结果存储在内存中。

2.3.3 数据显示每次电池电量测量完成后,系统将更新LCD显示模块上的电量信息。

可以通过LCD显示百分比、图形等形式显示电池电量信息。

2.3.4 系统操作通过按钮模块,用户可以对系统进行操作,如复位电池电量计数、设置电池类型等。

3. 总结本文档描述了一种使用51单片机设计的电池电量检测系统。

通过ADC转换器测量电池电压,并使用LCD显示模块显示电池电量信息。

此系统可广泛应用于电池电量监测领域,提供方便和准确的电量监测功能。

基于单片机的远程智能电表抄表系统设计

基于单片机的远程智能电表抄表系统设计

基于单片机的远程智能电表抄表系统设计远程抄表技术是一个集电能表数据采集、传输、存储、共享等功能于一体,以达到为客户、电力企业的电费、计量等数据应用部门服务的自动化系统。

本文以当前电能计量与抄表系统的发展背景为依据,提出了基于单片机的远程智能抄表系统。

自动抄表改变了以往人工抄表的服务方式,实行无人查表,由物业管理公司或供给公司在控制中心集中抄收,避免了因人工抄表所造成的错抄、漏抄、估抄、抄表时间跨度大、工作效率低、存在安全隐患等弊端。

既节省了人力物力,也提高了安全性。

本文主要设计完成了以AT89C52单片机为控制核心,具有电量测量和数据通信功能的智能型电能表,为了实现智能电能表的各种功能,在硬件设计中采用了多种芯片,并提出了多种基于单片机的自动抄表系统网络结构。

硬件设计主要设计模块如下:(1)智能电能表计量模块中的单相电量计量芯片ADE7755和三相电量计量芯片ATT7026与单片机的接口电路。

(2)数据采集器、数据集中器接口电路设计。

在软件设计部分主要实现了智能电能表的主程序和部分重要功能程序流程设计。

在最后对系统的干扰进行了分析,并在硬件和软件上提出了抗干扰措施,着重分析了智能电能表误差产生的来源和误差调整的方法。

基于51单片机的多路电压采集系统的设计proteus仿真

基于51单片机的多路电压采集系统的设计proteus仿真

基于51单片机的多路数据采集器一、摘要:用51单片机控制ADC0808将模拟信号(0~0.5V)转换成数值量(0~255),再控制LED数码管以十六进制实时显示出来。

ADC0808为模/数(A/D)转换器。

在Proteus软件上实现电路设计和程序设计,并进行实时交互仿真。

本设计采用了以单片机为开发平台,控制系采用AT89C52单片机,A/D转换采用ADC0808。

系统除能确保实现要求的功能外,还可以方便进行8路其它A/D转换量的测量。

万用板经过排版、布线、焊接、调试等工作后基于51单片机的简易电压表成形。

关键字:51单片机ADC0808 LED数码显示二、设计要求1、用51单片机作为控制器,来控制ADC0808将模拟信号转换成数值量(0—255);2、可准确测量0—0.5V电压,最小分辨率2mV;3、测量误差小于5%;4、用51单片机控制两位数码管显示实时测量电压的16进制数值量;5、单片机采用中断工作方式;6、在Proteus软件上实现多路电压的测量的电路和程序设计,并进行实时仿真;三、功能创新(1) 在Proteus软件上实现了8路电压的测量设计,并仿真成功,且在万用板上焊接、调试成功;(2) 设计一个外部开关通过中断方式来选择任意一路的电压测量,并用单片机控制一位数码管显示路数;(3)通过编程实现直接在LED数码管上显示测量电压值,并精确到1mV;(4) 设计一个由LED灯和蜂鸣器组成的报警电路,当被测电压超过测量范围时,报警电路实现报警;四、硬件电路设计1、系统设计框图根据设计要求与思路,在Proteus软件上设计和仿真该系统的设计方案。

硬件电路由6个部分组成,即单片机电路、复位电路、4位LED显示电路、A/D转换电路和键盘及报警电路、放大电路。

系统设计框图如下:图1 系统框图2、单片机系统电路本次设计选择Atmel公司生产的AT89C52作为控制芯片。

AT89系列与MCS-51系列单片机相比有两大优势:第一,片内程序存储器采用闪速存储器,使程序的写入更加方便;第二,提供了更小尺寸的芯片,使整个电路体积更小。

基于单片机的远程抄表系统设计

基于单片机的远程抄表系统设计

基于单片机的远程抄表系统设计作者:张召强来源:《电子世界》2012年第24期【摘要】介绍城市水表、气表及电表远程自动抄收系统的工作原理、实现电路、程序设计及部分程序代码,给出了利用单片机实现远程通讯、数据及处理采集、编码控制等的分析及处理方法,充分发挥单片机的功能与作用。

【关键词】单片机;485总线;232总线;IC卡;自动抄收单片机在消费电子、自动化仪表、工业控制等领域已得到了广泛的应用,它以灵活的设计、低廉的成本、微小的功耗在电子器件市场中占有十分重要的地位。

今天越来越多的芯片厂商在不遗余力地竞争这个应用空间。

如INTEL,MICROCHIP,NEC,ATMEL等公司都已形成了自己强大的产品线,给产品的设计带来了越来越多的选择。

1.系统功能及各部件特点描述本系统主要有以下几个部分组成:电脑、城市电话网、数据管理机、传输总线、单元转发器及可扩展单元转发器、计量表。

在这些组成中,单元转发器是整个系统的核心,它起着水、电及气表的抄收工作,并将抄收的数据通过485总线传送到与数据管理机相联的电脑上或者通过数据管理机将数据通过公共电话网传送到远程的管理电脑上。

电脑有一套与抄收系统相适应的管理软件,能实现远程抄收、设置等工作。

1.1 单元转发器单元转发器是实现数据抄收的主要设备,它主要装在小区内的楼道内,通过数据线与每一户内的水、电及气表相联,实时监控每个表的运行状态并完成数据抄收,主要有以下功能:(1)单元转发器最大数据采集量为30块计量表,内置蓄电池,断电后可连续工作240小时。

(2)单元转发器上具有大屏幕LCD显示,可实时显示每只计量表的读数、时间、状态便于人工查询。

(3)单元转发器上带有操作键盘,可直接在转发器上进行系统设定等各项操作。

(4)单元转发器有记忆卡插口、记忆卡既可以作为管理体人员的身份识别卡,又是可作为人工抄表的数据存储卡,每张记忆卡可存储16000只表的数据。

(5)单元转发器上有专线接口,连接小区和数据管理机,实现数据自动远传和管理。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <reg51.h>//AD7135直接与单片机相连采用查询的方法多路#include <absacc.h> #include <intrins.h>#define ucharunsigned char#define uintunsigned int#define ulongunsigned long#define ADP2#define ADP0#define CD4051P1#define fosc12//晶振频率#define time02000//定时2000us#define jishu1000//假设AD输入电压与对应瞬时功率的基数//1V对应1000w uint idata jisuandu;//临时变量,用于计算电度数uint idata time0_0;//临时变量,用于计算定时sbit STAT7135= P1^7;// 7135的启动端sbit busy= P2^6;// 7135的忙端sbit st= P2^5;// 7135的选通端sbit CS7221= P1^5;// 7221的片选sbit DIN7221 = P1^4;// 7221的数据端sbit CLK7221 = P1^6;// 7221的时钟端sbit SDA=P3^1;//2416的数据端sbit SCL=P3^0;//2416的时钟端//sbit en_24c16=P3^4;uchar DISPBUF[8]={0,1,2,3,4,5,6,7};//显示缓冲区uchar ADBUF[40]=0;//AD缓冲区(万千百十个)*8uchar TIME[2]=0;//用于定时uchar BUF[5]=0;//数据处理缓冲区void delay(uint n);//延时子程序void Initial7221(void);//MAX7221初始化void WR7221(uchar addr,uchar Data);//MAX7221写程序void Max7221Display(uchar *buffer);//MAX7221显示程序void time2ms(void);//定时器0初始化程序void time0_int(void);//定时器0中断服务程序void ICL7135(void);//ICL7135 8路信号AD转换程序void SAVE(void);//电量存储转电度程序void start_bit(void);//IIC开始条件void stop_bit(void);//IIC停止条件void mast_ack(void);//IIC应答bit write_8bit(uchar ch);//IIC写8位数据uchar read24c16(uint address,uchar *shu);//IIC读字节数据uchar write24c16(uint address,uchar ddata);//IIC写字节数据uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);//IIC页写uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);//IIC页读main(){//while(page_wr(0,120,0)==0);Initial7221();Max7221Display(&DISPBUF[0]);delay(40);time2ms();while(1){if(TIME[1]%10==0){ICL7135();SAVE();}}}void WR7221(uchar addr,uchar Data){uchar i;CS7221= 0;for (i=0;i<8;i++){CLK7221 = 0;DIN7221 = (addr&(0x80>>i)) ? 1:0;_nop_();_nop_();CLK7221 = 1;_nop_();_nop_();}for (i=0;i<8;i++){CLK7221 = 0;DIN7221 = (Data&(0x80>>i)) ? 1:0;_nop_();_nop_();CLK7221 = 1;_nop_();_nop_();//初次使用时清电量数//初始化7221//开机默认显示0~7//xx//启动定时器//5秒时间到//启动8路AD转换//存储电能//MAX7221的写子程序//片选有效//写8位地址//时钟低//先发高位依次到低位//时钟高上升沿锁数据//写8位数据//时钟低//先发高位依次到低位//时钟高上升沿锁数据}CS7221= 1;//片选无效}voidInitial7221(void)//MAX7221初始化{WR7221(0x0A,0x0A);//亮度地址0AH,0x00~0x0F,0x0F最亮WR7221(0x0B,0x07);//扫描LED个数地址0BH,0x00~0x07,最多扫描8个数码管WR7221(0x0C,0x01);//工作模式地址0x0C. 0x00:关断;0x01:正常WR7221(0x09,0xFF);//编码模式地址0x09. 0x00~0xFF:哪一位为1,哪一位就支持编码}void Max7221Display(uchar *buffer)//MAX7221显示子程序{uchar i;for (i=0;i<8;i++)//MAX7221的8个数码管显示{WR7221(i+1,*(buffer+i));//调MAX7221的写子程序}}void delay(uint n)//延时程序{uint i,j;for (i=0;i<n;i++)for (j=0;j<1140;j++);}void time2ms(void)//T0定时器初始化{TMOD=0x01;// T0工作方式1/* 2ms定时设置*/time0_0 = 65536-time0*fosc/12;//计算初值//装定时器0初值TL0=(time0_0%256);TR0=1;//启动定时器0ET0=1;//打开定时器0xxEA=1;//打开总中断}/*定时器0中断服务子程序,定时用于AD转换1s约转换3次,8路信号约3s时间为了时间充裕5s采集一次电能信号*/void time0_int(void) interrupt 1{//重装定时器0初值TL0=(time0_0%256);TIME[0]++;if (TIME[0]==250)//250*2ms=500ms=0.5s时间到{TIME[0]=0;//到0.5s时TIME[0]清0TIME[1]++;//TIME[1]加1内存的0.5秒的整数倍}}void ICL7135(void)//启动8路AD转换{uchar i,j;STAT7135=1;//7135启动端使能启动AD转换CD4051=CD4051&0xf0;//设置CD4051的第一路信号输入ADfor (j=0;j<=7;j++)//8路循环测量{i=CD4051&0xf0;//读P1口的状态保护高位CD4051=j|i;//通过j调节多路开关的转换STAT7135=1;//7135启动端使能启动AD 转换i=busy;//读7135的正在转换忙端do{i=busy;}while(busy==0);//忙端为0时等待直到开始转换do{i=busy;}while(busy==1);//忙端为1时正在转换等待STAT7135=0;//7135禁止AD转换do{i=ADP2;}while((ADP2&0x010)!=0x010);//读7135的D5,直到D5为1if ((ADP2&0x010)==0x010)//D5为1开始读AD转换结果{//STAT7135=0;ADBUF[j*5]=ADP0&0x0f;//读7135的万位do{i=ADP2;}while((ADP2&0x08)!=0x08);//读7135的D4,直到D4为1ADBUF[1+j*5]=ADP0&0x0f;//读7135的千位do{i=ADP2;}while((ADP2&0x04)!=0x04);//读7135的D3,直到D3为1ADBUF[2+j*5]=ADP0&0x0f;//读7135的百位do{i=ADP2;}while((ADP2&0x02)!=0x02);//读7135的D2,直到D2为1ADBUF[3+j*5]=ADP0&0x0f;//读7135的十位do{i=ADP2;}while((ADP2&0x01)!=0x01);//读7135的D1,直到D1为1ADBUF[4+j*5]=ADP0&0x0f;//读7135的个位//ADBUF[0]=j+1;//路号//Max7221Display(&ADBUF[j*5]);//当频率慢时可以显示AD转换的结果}}}void SAVE(void)//电能处理保存{uchar k,i;ulong kk,kk1,kk2;if (TIME[1]<120)//小于1分钟时120*0.5=60s简单加{for (k=0;k<=7;k++)//8路电能循环存储{while(page_rd(k*5,5,&BUF[0])==0);//读原来的电能各路5位数字for(i=0;i<=4;i++){BUF[i]=BUF[i]+ADBUF[i+k*5];//本次的电能和原来的电能求和}while (page_wr(k*5,5,&BUF[0])==0);//存新的总电能}}if (TIME[1]==120)//等于1分钟时做电度数的处理{TIME[1]=0;for (k=0;k<=7;k++)//8路电能循环转换成电度数存储{while (page_rd(k*5,5,&BUF[0])==0);//读原来的电能各路5位数字for(i=0;i<=4;i++){BUF[i]=BUF[i]+ADBUF[i+k*5];//本次的电能和原来的电能求和}while (page_wr(k*5,5,0)==0);//清寄存的电能kk=(ulong)BUF[0]*100+(ulong)BUF[1]*1000+(ulong)BUF[2]*100+(ulong)BUF[3]* 10+(ulong)BUF[4];//把电能转化为千瓦时即度while(page_rd(100+k*2,2,&BUF[0])==0);//读上次余数kk=kk*jishu+(ulong)BUF[0]*100+(ulong)BUF[1];//(jishu*1000)/(100*12*60)=jishu/7200kk1=kk/7200;//取电度数kk2=kk%7200;//kk1为电度数kk2余数//分两部分存储电度的余数100为界BUF[1]=(uchar)(kk2%100);while(page_wr(100+k*2,2,&BUF[0])==0);//电度的存余数while (page_rd(50+k*5,5,&BUF[0])==0);//读原来电度数kk1=kk1+(ulong)BUF[0]*100+(ulong)BUF[1]*1000+(ulong)BUF[2]*100+(ulong)B UF[3]*10+(ulong)BUF[4];//原来的电度和新的电度数相加//万BUF[1]=(uchar)((kk1%100)/1000);//千BUF[2]=(uchar)(((kk1%100)%1000)/100); //百BUF[3]=(uchar)((kk1%100)/10);//十BUF[4]=(uchar)((kk1%100)%10);//个while(page_wr(50+k*5,5,&BUF[0])==0);//存新电度数DISPBUF[0]=k+1;//显示户号DISPBUF[1]=0xf;//显示2个FDISPBUF[2]=0xf;DISPBUF[3]=BUF[0];//显示此时电度数DISPBUF[4]=BUF[1];DISPBUF[5]=BUF[2];DISPBUF[6]=BUF[3];DISPBUF[7]=BUF[4];Max7221Display(&DISPBUF[0]);//送显示delay(20);//延时}}}/*----------------------------------------------- 调用方式:void start_bit(void)函数说明:开始位-----------------------------------------------*/void start_bit(void){SCL=1;_nop_();SDA=1;_nop_();SDA=0;_nop_();SCL=0;_nop_();}/*----------------------------------------------- 调用方式:void stop_bit(void)函数说明:停止位-----------------------------------------------*/void stop_bit(void){SDA=0;_nop_();SCL=1;_nop_();SDA=1;_nop_();}/*----------------------------------------------- 调用方式:void mast_ack(void)函数说明:主答函数-----------------------------------------------*/void mast_ack(void){SCL=0;_nop_();SDA=0;_nop_();SCL=1;_nop_();SCL=0;_nop_();SDA=1;_nop_();}/*----------------------------------------------- 调用方式:write_8bit(uchar ch)函数说明:写一个字节(8位)数据-----------------------------------------------*/bit write_8bit(uchar ch){uchar i=8;bit fan_w;SCL=0;_nop_();while (i--){SDA=(bit)(ch&0x80);_nop_();ch<<=1;SCL=1;_nop_();SCL=0;_nop_();}SDA=1;_nop_();SCL=1;_nop_();fan_w=SDA;SCL=0;_nop_();return(fan_w);}/*----------------------------------------------调用方式:uchar read24c16(uint address,uchar *shu)函数说明:读24c16指定地址数据(字节读)-----------------------------------------------*/uchar read24c16(uint address,uchar *shu){uchar data rdata; uchar i=8;EA=0;//避免与串口通讯等xx冲突start_bit();if (write_8bit(0xA0)!=0){stop_bit();EA=1;return(0);}if (write_8bit(address)!=0){stop_bit();EA=1;return(0);}start_bit();if (write_8bit(0xA1)!=0){(0);}while (i--){rdata<<=1;SCL=1;_nop_();if (SDA) rdata|=0x01;SCL=0;_nop_();}stop_bit();EA=1;*shu=rdata;return(1);}/*-----------------------------------------------调用方式:void write24c16(uint address,uchar ddata)函数说明:写数据到24c16的指定地址(字节写)-----------------------------------------------*/uchar write24c16(uint address,uchar ddata){EA=0;//避免与串口通讯等中断冲突start_bit();if (write_8bit(0xA0)!=0){stop_bit();EA=1;return(0);}if (write_8bit(address)!=0){stop_bit();EA=1;return(0);}if (write_8bit(ddata)!=0){(0);}stop_bit();EA=1;return(1);}/*-----------------------------------------------调用方式:void page_wr(uint firstw_ad,uint counter,uint data *firstr_ad)函数说明:页面写函数,firstw_ad为写入字节单元的首地址,*firstr-ad为被写入数据所在首地址指针counter为写入数据字节数-----------------------------------------------*/uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad){uchar data *ufirstr_ad;ufirstr_ad=firstr_ad;start_bit();if (write_8bit(0xA0)!=0){stop_bit();return(0);}if (write_8bit(firstw_ad)!=0){stop_bit();return(0);}while (counter--){if (write_8bit(*ufirstr_ad)!=0){stop_bit();return(0);}ufirstr_ad++;}stop_bit();return(1);}/*-----------------------------------------------调用方式:void page_rd(uint firstrd_ad,uint count,uint firstwr_ad)函数说明:页面读函数,firstrd-ad为所读字节首地址,count为读字节数*ufirstwr-ad为读出数据存储首地址指针-----------------------------------------------*/uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad){uchar j=8; uchar data *ufirstwr_ad;ufirstwr_ad=firstwr_ad;start_bit();if (write_8bit(0xA0)!=0){stop_bit();return(0);}if (write_8bit(firstrd_ad)!=0){stop_bit();return(0);}start_bit();if (write_8bit(0xA1)!=0){stop_bit();return(0);}while (count--){uchar i=8;while (i--){(*ufirstwr_ad)<<=1;SCL=1;_nop_();if (SDA) (*ufirstwr_ad)|=0x01;SCL=0; _nop_();}ufirstwr_ad++;mast_ack();}while (j--){(*ufirstwr_ad)<<=1; SCL=0;_nop_();_nop_();SCL=1;if (SDA) (*ufirstwr_ad)|=0x01;}stop_bit(); return(1);}。

相关文档
最新文档