第7章基于单片机的电表抄表系统.docx
- 文档编号:4347578
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:24
- 大小:22.63KB
第7章基于单片机的电表抄表系统.docx
《第7章基于单片机的电表抄表系统.docx》由会员分享,可在线阅读,更多相关《第7章基于单片机的电表抄表系统.docx(24页珍藏版)》请在冰豆网上搜索。
第7章基于单片机的电表抄表系统
7.3.2掉电数据保护功能的实现
使用不带硬件总线驱动的单片机对IICEEPROM的读写操作的难点在于用软件模拟IIC总线的时序,下面是本例中的IICEEPROM的读写驱动程序,此驱动程序支持24c01,24c02,24c04,24c08,24c16,24c32,24c64,24c128,24c256系列IICEEPROM。
#include
#include
#define ERRORCOUNT 10
sbit SDA=P1^0;
sbit SCL=P1^1;
enum eepromtype {24c01,24c02,24c04,24c08,24c16,24c32,24c64,24c128,24c256};
enum eepromtype EepromType;
/********************************************************************************
** 函数名称:
RW24XX
** 入口参数:
DataBuff为读写数据输入/输出缓冲区的首址
**ByteQuantity 为要读写数据的字节数量
**Address 为EEPROM的片内地址
**ControlByte 为EEPROM的控制字节具体形式为
(1)(0)
(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址
** 出口参数:
若返回1表示此次操作失效,0表示操作成功
**其他调用:
函数:
IICStart,IICStop,IICRecAck,IICNoAck,IICAck,IICReceiveByte
**IICSendByte
**变量:
EepromType为枚举变量,需为24c01至24c256中的一种,ERRORCOUNT为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1
**功能描述:
24c系列IICEEPROM驱动包
********************************************************************************/
bitRW24XX(unsignedchar*DataBuff,unsignedcharByteQuantity,unsignedint
Address,unsignedcharControlByte,enumeepromtypeEepromType)
{
voidDelay(unsignedcharDelayCount);
voidIICStart(void);
voidIICStop(void);
bitIICRecAck(void);
voidIICNoAck(void);
voidIICAck(void);
unsignedcharIICReceiveByte(void);
voidIICSendByte(unsignedcharsendbyte);
unsignedchardataj,i=ERRORCOUNT;
biterrorflag=1;
while(i--)
{
IICStart();
IICSendByte(ControlByte&0xfe);
if(IICRecAck())
continue;
if(EepromType>24C16)
{
IICSendByte((unsignedchar)(Address>>8));
if(IICRecAck())
continue;
}
IICSendByte((unsignedchar)Address);
if(IICRecAck())
continue;
if(!
(ControlByte&0x01))
{
j=ByteQuantity;
errorflag=0;//clrerrorflag
while(j--)
{
IICSendByte(*DataBuff++);
if(!
IICRecAck())
continue;
errorflag=1;
break;
}
if(errorflag==1)
continue;
break;
}
else
{
IICStart();
IICSendByte(ControlByte);
if(IICRecAck())
continue;
while(--ByteQuantity)
{
*DataBuff++=IICReceiveByte();
IICAck();
}
*DataBuff=IICReceiveByte();//readlastbytedata
IICNoAck();
errorflag=0;
break;
}
}
IICStop();
if(!
(ControlByte&0x01))
{
Delay(255);
Delay(255);
Delay(255);
Delay(255);
}
return(errorflag);
}
/*******************************************************************************
**函数名称:
IICStart
**入口参数:
无
**出口参数:
无
**功能描述:
启动总线
********************************************************************************/
voidIICStart(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();_nop_();_nop_();
SDA=0;
_nop_();_nop_();_nop_();
SCL=0;
SDA=1;
}
/*******************************************************************************
**函数名称:
IICStop
**入口参数:
无
**出口参数:
无
**功能描述:
停止IIC总线
********************************************************************************/
voidIICStop(void)
{
SCL=0;
SDA=0;
SCL=1;
_nop_();_nop_();_nop_();
SDA=1;
_nop_();_nop_();_nop_();
SCL=0;
}
/*******************************************************************************
**函数名称:
IICRecAck
**入口参数:
无
**出口参数:
0代表收到应答
**功能描述:
检查应答位
********************************************************************************/
bitIICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();_nop_();_nop_();_nop_();
CY=SDA;//因为返回值总是放在CY中的
SCL=0;
return(CY);
}
/*******************************************************************************
**函数名称:
IICACK
**入口参数:
无
**出口参数:
无
**功能描述:
对IIC总线产生应答
********************************************************************************/
voidIICACK(void)
{
SDA=0;
SCL=1;
_nop_();_nop_();_nop_();
SCL=0;
_nop_();_nop_();_nop_();
SDA=1;
}
/*******************************************************************************
**函数名称:
IICNoAck
**入口参数:
无
**出口参数:
无
**功能描述:
不对IIC总线产生应答
********************************************************************************/
/*****************不对IIC总线产生应答***************/
voidIICNoAck(void)
{
SDA=1;
SCL=1;
_nop_();_nop_();_nop_();_nop_();
SCL=0;
}
/*******************************************************************************
**函数名称:
IICSendByte
**入口参数:
sendbyte要写入的字节数据
**出口参数:
无
**功能描述:
向IIC总线写数据
********************************************************************************/
voidIICSendByte(unsignedcharsendbyte)
{
unsignedchardataj=8;
for(;j>0;j--)
{
SCL=0;
sendbyte<<=1;//始终使CY=sendbyte^7;
SDA=CY;
SCL=1;
}
SCL=0;
}
/*******************************************************************************
**函数名称:
IICReceiveByte
**入口参数:
无
**出口参数:
读到的字节数据
**功能描述:
从IIC总线上读数据
********************************************************************************/
unsignedcharIICReceiveByte(void)
{
registerreceivebyte,i=8;
SCL=0;
while(i--)
{
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}
/***************一个简单延时程序************************/
voidDelay(unsignedcharDelayCount)
{
while(DelayCount--);
}
7.3.3RS-232、RS-485串行通信设计
/*-------------------------------------------------------------------------
W77e58寄存器定义头文件
--------------------------------------------------------------------------*/
/*BYTERegisters*/
sfrP0=0x80;sfrP1=0x90;sfrP2=0xA0;
sfrP3=0xB0;sfrPSW=0xD0;sfrACC=0xE0;
sfrB=0xF0;sfrSP=0x81;sfrDPL=0x82;
sfrDPH=0x83;sfrPCON=0x87;sfrTCON=0x88;
sfrTMOD=0x89;sfrTL0=0x8A;sfrTL1=0x8B;
sfrTH0=0x8C;sfrTH1=0x8D;sfrIE=0xA8;
sfrIP=0xB8;sfrSCON=0x98;sfrSBUF=0x99;
sfrSCON0=0x98;sfrSBUF0=0x99;
/*W77E532Extensions*/
sfrDPL1=0x84;sfrDPH1=0x85;sfrDPS=0x86;
sfrCKCON=0x8E;sfrEXIF=0x91;sfrP4CONA=0x92;
sfrP4CONB=0x93;sfrP40AL=0x94;sfrP40AH=0x95;
sfrP41AL=0x96;sfrP41AH=0x97;sfrP42AL=0x9A;
sfrP42AH=0x9B;sfrP43AL=0x9C;sfrP43AH=0x9D;
sfrCHPCON=0x9F;sfrP4CSIN=0xA2;sfrP4=0xA5;
sfrSADDR=0xA9;sfrSADDR1=0xAA;sfrROMCON=0xAB;
sfrSFRAL=0xAC;sfrSFRAH=0xAD;sfrSFRFD=0xAE;
sfrSFRCN=0xAF;sfrSADEN0=0xB9;sfrSADEN1=0xBA;
sfrSCON1=0xC0;sfrSBUF1=0xC1;sfrWSCON=0xC2;
sfrPMR=0xC4;sfrSTATUS=0xC5;sfrNVMSEL=0xC6;
sfrTA=0xC7;sfrT2CON=0xC8;sfrT2MOD=0xC9;
sfrRCAP2L=0xCA;sfrRCAP2H=0xCB;sfrTL2=0xCC;
sfrTH2=0xCD;sfrNVMCON=0xCE;sfrNVMDAT=0xCF;
sfrWDCON=0xD8;sfrEIE=0xE8;sfrEIP=0xF8;
/*BITRegisters*/
/*PSW*/
sbitCY=PSW^7;sbitAC=PSW^6;sbitF0=PSW^5;
sbitRS1=PSW^4;sbitRS0=PSW^3;sbitOV=PSW^2;
sbitFL=PSW^1;sbitP=PSW^0;
/*TCON*/
sbitTF1=TCON^7;sbitTR1=TCON^6;sbitTF0=TCON^5;
sbitTR0=TCON^4;sbitIE1=TCON^3;sbitIT1=TCON^2;
sbitIE0=TCON^1;sbitIT0=TCON^0;
/*IE*/
sbitEA=IE^7;sbitES1=IE^6;sbitET2=IE^5;
sbitES0=IE^4;sbitET1=IE^3;sbitEX1=IE^2;
sbitET0=IE^1;sbitEX0=IE^0;
/*IP*/
sbitPS1=IP^6;sbitPT2=IP^5;sbitPS0=IP^4;
sbitPT1=IP^3;sbitPX1=IP^2;sbitPT0=IP^1;
sbitPX0=IP^0;
/*P1*/
sbitINT5=P1^7;sbitINT4=P1^6;sbitINT3=P1^5;
sbitINT2=P1^4;sbitTXD1=P1^3;sbitRXD1=P1^2;
sbitT2EX=P1^1;sbitT2=P1^0;
/*P3*/
sbitRD=P3^7;sbitWR=P3^6;sbitT1=P3^5;
sbitT0=P3^4;sbitINT1=P3^3;sbitINT0=P3^2;
sbitTXD0=P3^1;sbitRXD0=P3^0;
/*SCON0*/
sbitSM0=SCON0^7;sbitSM1=SCON0^6;sbitSM2=SCON0^5;
sbitREN=SCON0^4;sbitTB8=SCON0^3;sbitRB8=SCON0^2;
sbitTI=SCON0^1;sbitRI=SCON0^0;
/*SCON1*/
sbitSM01=SCON1^7;sbitSM11=SCON1^6;sbitSM21=SCON1^5;
sbitREN1=SCON1^4;sbitTB81=SCON1^3;sbitRB81=SCON1^2;
sbitTI1=SCON1^1;sbitRI1=SCON1^0;
/*T2CON*/
sbitTF2=T2CON^7;sbitEXF2=T2CON^6;sbitRCLK=T2CON^5;
sbitTCLK=T2CON^4;sbitEXEN2=T2CON^3;sbitTR2=T2CON^2;
sbitC_T2=T2CON^1;sbitCP_RL2=T2CON^0;
/*WDCON*/
sbitSMOD_1=WDCON^7;sbitPOR=WDCON^6;sbitEPFI=WDCON^5;
sbitPFI=WDCON^4;sbitWDIF=WDCON^3;sbitWTRF=WDCON^2;
sbitEWT=WDCON^1;sbitRWT=WDCON^0;
/*EIE*/
sbitEWDI=EIE^4;sbitEX5=EIE^3;sbitEX4=EIE^2;
sbitEX3=EIE^1;sbitEX2=EIE^0;
/*EIP*/
sbitPWDI=EIP^4;sbitPX5=EIP^3;sbitPX4=EIP^2;
sbitPX3=EIP^1;sbitPX2=EIP^0;
使用串口实现数据通信,串口的工作方式有四种,其中方式0是作为同步移位一位寄存器,可以通过外接移位寄存器芯片实现扩展I/O接口功能。
方式1是8位数据异步通信接口,波特率可变。
波特率定时器T1或者T2的溢出率经分频后得到。
方式2是9位数据异步通信接口,波特率由主频fosc分频得到,当SMOD=1时,波特率为fosc/32,当SMOD=0时,波特率为fosc/64。
方式3是9位数据异步通信接口,波特率可变。
波特率由定时器T1或T2的溢出率经分频后得到。
下面是本例中的双串口初始化和相关操作程序。
#include
/**************************************************
串口0队列
**************************************************/
unsignedcharxdataxBuf_Send_0[XBUFSERIAL0SEND];
unsignedcharxdataxBuf_Reci_0[XBUFSERIAL0RECI];
unsignedcharxdata*Seri0_ReadSendPoint=xBuf_Send_0;
unsignedcharxdata*Seri0_WriteSendPoint=xBuf_Send_0;
unsignedchardataSeri0_SendNum;
unsignedcharxdata*Seri0_ReadReciPoint=xBuf_Reci_0;
unsignedcharxdata*Seri0_WriteReciPoint=xBuf_Reci_0;
unsignedintdataSeri0_ReciNum;
/**************************************************
压入单数据串口0发送队列
**************************************************/
voidSeri0_PushSend(unsignedcharmData)
{
*Seri0_WriteSendPoint=mData;
if(Seri0_WriteSendPoint==(xBuf_Send_0+XBUFSERIAL0SEND-1))
Seri0_WriteSendPoint=xBuf_Send_0;
elseSeri0_WriteSendPoint++;
Seri0_SendNum++;
if(fSeri0_Send_Ok==0){fSeri0_Send_Ok=1;TI=1;}
}
/**************************************************
弹出串口0接收队列单数据
**************************************************/
unsignedcharSeri0_PopReci()
{
unsignedchari;
i=*Seri0_ReadReciPoint;
if(Seri0_ReadReciPoint==(xBuf_Reci_0+XBUFSERIAL0RECI-1))
Seri0_ReadReciPoint=xBuf_Reci_0;
elseSeri0_ReadReciPoint++;
Seri0_ReciNum--;
returni;
}
/**************************************************
读出串口0接收队列指定序号数据
******
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第7章 基于单片机的电表抄表系统 基于 单片机 电表 系统
![提示](https://static.bdocx.com/images/bang_tan.gif)