1、基于51单片机的电表电量采集系统程序#include /AD7135直接与单片机相连 采用查询的方法 多路#include #include #define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define ADP2 P2#define ADP0 P0#define CD4051 P1#define fosc 12 / 晶振频率#define time0 2000 / 定时2000us#define jishu 1000 / 假设AD输入电压与对应瞬时功率的基数 / 1V对应1000wu
2、int idata jisuandu; / 临时变量,用于计算电度数uint idata time0_0; / 临时变量,用于计算定时sbit STAT7135= P17; / 7135的启动端sbit busy = P26; / 7135的忙端sbit st = P25; / 7135的选通端sbit CS7221 = P15; / 7221的片选sbit DIN7221 = P14; / 7221的数据端sbit CLK7221 = P16; / 7221的时钟端sbit SDA=P31; /2416的数据端sbit SCL=P30; /2416的时钟端/sbit en_24c16=P34
3、;uchar DISPBUF8=0,1,2,3,4,5,6,7; /显示缓冲区uchar ADBUF40=0; /AD缓冲区 (万千百十个)*8uchar TIME2=0; /用于定时uchar BUF5=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初始化程序
4、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 addre
5、ss,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(); /初始化7221 Max7221Display(&DISPBUF0); /开机默认显示07 delay(40); /延时 time2ms(); /启动定时器 w
6、hile(1) if(TIME1%10=0) /5秒时间到 ICL7135(); /启动8路AD转换 SAVE(); /存储电能 void WR7221(uchar addr,uchar Data) /MAX7221的写子程序 uchar i; CS7221 = 0; /片选有效 for (i=0;ii) ? 1:0; /先发高位 依次到低位 _nop_(); _nop_(); CLK7221 = 1; /时钟高 上升沿锁数据 _nop_(); _nop_(); for (i=0;ii) ? 1:0; /先发高位 依次到低位 _nop_(); _nop_(); CLK7221 = 1; /时钟
7、高 上升沿锁数据 _nop_(); _nop_(); CS7221 = 1; /片选无效void Initial7221(void) /MAX7221初始化 WR7221(0x0A,0x0A); /亮度地址0AH,0x000x0F,0x0F最亮 WR7221(0x0B,0x07); /扫描LED个数地址0BH,0x000x07,最多扫描8个数码管 WR7221(0x0C,0x01); /工作模式地址0x0C. 0x00:关断;0x01:正常 WR7221(0x09,0xFF); /编码模式地址0x09. 0x000xFF:哪一位为1,哪一位就支持编码void Max7221Display(uc
8、har *buffer) /MAX7221显示子程序 uchar i; for (i=0;i8;i+) /MAX7221的8个数码管显示 WR7221(i+1,*(buffer+i); /调MAX7221的写子程序 void delay(uint n) /延时程序 uint i,j; for (i=0;in;i+) for (j=0;j1140;j+);void time2ms(void) /T0定时器初始化 TMOD=0x01; / T0工作方式1 /* 2ms 定时设置 */ time0_0 = 65536-time0*fosc/12; /计算初值 TH0=(time0_0/256); /
9、装定时器0初值 TL0=(time0_0%256); TR0=1; /启动定时器0 ET0=1; /打开定时器0中断 EA=1; /打开总中断/* 定时器0中断服务子程序,定时用于AD转换 1s约转换3次,8路信号约3s时间 为了时间充裕 5s采集一次电能信号 */void time0_int(void) interrupt 1 TH0=(time0_0/256); /重装定时器0初值 TL0=(time0_0%256); TIME0+; if (TIME0=250) /250*2ms=500ms=0.5s时间到 TIME0=0; /到0.5s时 TIME0清0 TIME1+; /TIME1加
10、1 内存的0.5秒的整数倍 void ICL7135(void) /启动8路AD转换 uchar i,j; STAT7135=1; /7135启动端使能 启动AD转换 CD4051=CD4051&0xf0; /设置CD4051的第一路信号输入AD for (j=0;j=7;j+) /8路循环测量 i=CD4051&0xf0; /读P1口的状态 保护高位 CD4051=j|i; /通过j调节 多路开关的转换 STAT7135=1; /7135启动端使能 启动AD转换 i=busy; /读7135的正在转换 忙端 doi=busy;while(busy=0); /忙端为0时 等待 直到开始转换 d
11、oi=busy;while(busy=1); /忙端为1时 正在转换 等待 STAT7135=0; /7135 禁止AD转换 doi=ADP2;while(ADP2&0x010)!=0x010); /读7135的D5,直到D5为1 if (ADP2&0x010)=0x010) /D5为1开始读AD转换结果 /STAT7135=0; ADBUFj*5=ADP0&0x0f; /读7135的万位 doi=ADP2;while(ADP2&0x08)!=0x08);/读7135的D4,直到D4为1 ADBUF1+j*5=ADP0&0x0f; /读7135的千位 doi=ADP2;while(ADP2&0
12、x04)!=0x04);/读7135的D3,直到D3为1 ADBUF2+j*5=ADP0&0x0f; /读7135的百位 doi=ADP2;while(ADP2&0x02)!=0x02);/读7135的D2,直到D2为1 ADBUF3+j*5=ADP0&0x0f; /读7135的十位 doi=ADP2;while(ADP2&0x01)!=0x01);/读7135的D1,直到D1为1 ADBUF4+j*5=ADP0&0x0f; /读7135的个位 /ADBUF0=j+1; /路号 /Max7221Display(&ADBUFj*5); /当频率慢时可以显示AD转换的结果 void SAVE(void) /电能处理 保存 uchar k,i; ulong kk,kk1,kk2; if (TIME1120) /小于1分钟时 120*0.5=60s 简单加 for (k=0;k=7;k+) /8路电能循环存储 while (page_rd(k*5,5,&BUF0)=0); /读原来的电能 各路5位数字 for (i=0;i=4;i+) BUFi=BUFi+ADBUFi+k*5; /本次的电能和原来的电能求和 while (page_wr(k*5,5,&BUF0)=0); /存新的总电能
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1