⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmeter.c

📁 红外抄表。CPU = LPC921F
💻 C
字号:
#include <REG922.H>

#include "rMeter.h"

struct FLASH_SET code FLA_set[MAX_METER]={{0,0,0,50,0,0},{0,0,0,50,0,0},{0,0,0,50,0,0},
											{0,0,0,50,0,0},{0,0,0,50,0,0},{0,0,0,50,0,0},
											{0,0,0,50,0,0},{0,0,0,50,0,0}};
uchar code FLApluseL[MAX_METER][100];
uchar code FLAinMark[MAX_METER]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

uchar ucRbuf[BUF_SIZE];
uchar ucOffset;
uint unPluseCnt[MAX_METER];
uchar *pucData,*pucAddr;



//void   (*GotoIsp)();  //定义函数指针  
void delay100us(uchar i);
void UART_Init(void); 
bit  WriteFlash(unsigned int unFlashAddr, unsigned char ucData); 
void SendChar(unsigned char ucData);
void T1_Init(void);


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main()
{
	uchar uctmp,ucPackOff;
	uint *punTail,untmp;
	uchar ucInState,ucOldState,ci,uccnt[MAX_METER];
	uchar ucInData;

	delay100us(100);
	delay100us(100);


	ucOffset=0;
	for(ci=0;ci<MAX_METER;ci++)
	{
		unPluseCnt[ci]=FLA_set[ci].ucCurPluseH;
		unPluseCnt[ci]=unPluseCnt[ci]*256+FLApluseL[ci][FLA_set[ci].unCurPluseLoff];
	}

 	P0M1=0x80;
	P0M2=0x80;

 	P1M1=0x00;
	P1M2=0x00;

//	GotoIsp=0x0F00;  //for LPC921

/*
	PCON=PCON&0xdf;     //配置成掉电中断 
	PCON=PCON|0x10; 
	RSTSRC=RSTSRC&0x0f;    //清除上电和掉电检测标志位 
	IEN0=IEN0|0xa0;      //开掉电检测中断 
*/

	T1_Init();
  	UART_Init(); 

 	//test
	pucData=(uchar *)&unPluseCnt[1];
//	uctmp=((uint)pucData)>>8;
//	SendChar(uctmp);
//	uctmp=((uint)pucData)&0xff;
//	SendChar(uctmp);
	SendChar('\x33');
	SendChar(*pucData);
	SendChar(*(pucData+1));


  	while(1)
	{
		ucOldState = ucInState;
//		ucInState = 0;

		for(ci=0;ci<MAX_METER;ci++) uccnt[ci]=0;
		for(uctmp=0;uctmp<5;uctmp++)
		{
			ucInData = ((P1 & 0x10)<<3);
//			ucInData = P1^4; ucInData <<=7;
//			if(P1^4) ucInData = 0x80;
//			else ucInData = 0;

			ucInData |= (P0 & 0x7f);//////////

			for(ci=0;ci<MAX_METER;ci++)
			{
				if(ucInData & FLAinMark[ci])	uccnt[ci]++;
			}

			delay100us(2);
		}
		for(ci=0;ci<MAX_METER;ci++)
		{
/*
			if(uccnt[ci]>3 && !(ucOldState & FLAinMark[ci]))  //0 -> 1
			{
				for(uctmp=0;uctmp<5;uctmp++)
				{
//					ucInData = ((P1 & 0x10)<<3);
					ucInData = P1^4; ucInData <<=7;
					ucInData |= (P0 & 0x7f);//////////

					if(ucInData & FLAinMark[ci]) uccnt[ci]++;
				}
				if(uccnt[ci]>7)
					ucInState |= FLAinMark[ci];
			}
			else if(uccnt[ci]<2 && (ucOldState & FLAinMark[ci]))    // 1 -> 0
			{
				for(uctmp=0;uctmp<5;uctmp++)
				{
//					ucInData = ((P1 & 0x10)<<3);
					ucInData = P1^4; ucInData <<=7;
					ucInData |= (P0 & 0x7f);//////////

					if(ucInData & FLAinMark[ci]) uccnt[ci]++;
				}
				if(uccnt[ci]<3)
					ucInState &= (~FLAinMark[ci]);
			}
*/			

			if(uccnt[ci]>3)
				ucInState |= FLAinMark[ci];
			else if(uccnt[ci]<2 && (ucOldState & FLAinMark[ci]))
				ucInState &= (~FLAinMark[ci]);

		}


		for(ci=0;ci<MAX_METER;ci++)
		{
			if((ucOldState & FLAinMark[ci]) && !(ucInState & FLAinMark[ci]))
			{

				unPluseCnt[ci]++;

//test
SendChar('\xCC');
SendChar(ci+1);
uctmp=unPluseCnt[ci];
SendChar(uctmp);


				if(unPluseCnt[ci]==FLA_set[ci].unPlusePDgr)	//更新度数
				{
					untmp=FLA_set[ci].unCurDgr+1;
					pucData=(uchar *)&untmp;
					pucAddr=(uchar *)&FLA_set[ci].unCurDgr;
					WriteFlash((uint)pucAddr,*pucData);				//保存度数
					WriteFlash((uint)(pucAddr+1),*(pucData+1));

					WriteFlash((uint)&FLA_set[ci].ucCurPluseH,'\0');	//脉冲数清0
					WriteFlash((uint)&(FLApluseL[ci]+FLA_set[ci].unCurPluseLoff),'\0');
					unPluseCnt[ci]=0;

//test
SendChar('\xDD');
SendChar(*pucData);
SendChar(*(pucData+1));



				}
				if(!(unPluseCnt[ci] & 0x00ff))	//发生低字节向高字节进位时
				{
					pucData=(uchar *)&unPluseCnt[ci];
					WriteFlash((uint)&FLA_set[ci].ucCurPluseH,*pucData);
					WriteFlash((uint)&(FLApluseL[ci]+FLA_set[ci].unCurPluseLoff),'\0');

//test
SendChar('\xAA');
SendChar(FLA_set[ci].ucCurPluseH);
SendChar(FLApluseL[ci][FLA_set[ci].unCurPluseLoff]);
					
					
				}
				if(unPluseCnt[ci] % (FLA_set[ci].unPlusePDgr / WRITE_TIMES)==0)
				{
					pucData=(uchar *)&unPluseCnt[ci];
					pucData++;
					WriteFlash((uint)&(FLApluseL[ci]+FLA_set[ci].unCurPluseLoff),*pucData);

uctmp=*pucData;
//test
/*
SendChar('\xBB');
SendChar(FLA_set[ci].ucCurPluseH);
SendChar(FLApluseL[ci][FLA_set[ci].unCurPluseLoff]);
*/

					if(FLApluseL[ci][FLA_set[ci].unCurPluseLoff] != uctmp /* *pucData */)	//该单元可能坏
					{
						WriteFlash((uint)&(FLApluseL[ci]+FLA_set[ci].unCurPluseLoff),*pucData);  //重试一遍
SendChar('\x11');
SendChar('\x11');
SendChar('\x11');

						if(FLApluseL[ci][FLA_set[ci].unCurPluseLoff] != *pucData)	//该单元可能坏
						{
							WriteFlash((uint)&(FLApluseL[ci]+FLA_set[ci].unCurPluseLoff+1),*pucData);  //重试一遍

							untmp=FLA_set[ci].unCurPluseLoff+1;
							pucData=(uchar *)&untmp;
							pucAddr=(uchar *)FLA_set[ci].unCurPluseLoff;
							WriteFlash((uint)pucAddr,*pucData);
							WriteFlash((uint)(pucAddr+1),*(pucData+1));
SendChar('\x22');
SendChar('\x22');
SendChar('\x22');
						}
					}   //if 换单元

				}  //if Write
			} //if Pluse
		}  //for 通道
		


		if(ucOffset >= PACK_SIZE)
		{
			punTail=(uint *)(ucRbuf+ucOffset-2);
			if(*punTail==PACK_TAIL)
			{

				ucPackOff=ucOffset-PACK_SIZE+2;
				switch(*(ucRbuf+ucPackOff))
				{
				case CMD_SET_SN  :
					break;
				case CMD_READ    :
					break;
				case CMD_READ_R  :
					break;
				case CMD_SET_BASE:
					break;
				case CMD_SET_PLU :
					break;
				case CMD_SET_TYPE:
					break;
				}
			}
		}

/*
		if(ucOffset != unPluseCnt[0])
		{
			unPluseCnt[0]=ucOffset;
	SendChar(ucOffset);
//			WriteFlash((uint)&FLA_set.unCurPluse,*(pucPluseCnt+1));
		}
*/
		if(ucOffset == BUF_SIZE) ucOffset=0;  //清除缓冲区

//		if(P1^6 == 0) GotoIsp(); //暂时使用,第三脚接地
	} 
}



//--------------------------------------------------------
//功能:100us级延时
//出口参数:i,延时i x 100us
//--------------------------------------------------------
void delay100us(uchar i)				//在7.373MHz时,精确延时100us,误差0.5us
{
	uchar	j;
	while(i>0)
	{
		for(j=0;j<118;j++);
		i--;
	}
}



/*
7.3728MHz
BRGR1:BRGR0				5FF0H  17F0H  0BF0H 05F0H 	02F0H 	0170H 00F0H 00B0H  0070H  0030H 
实际波特率				300  	1200  2400 	4800 	9600 	19201 28801 38401  57602  115203
*/ 
void UART_Init() 
{ 
  P1M1=0x00; 
  P1M2=0x00;        //端口初始化 
 
  SCON=0x50;        //使能接收 选择串口模式 1 
  SSTAT=0xE0;        //选择独立的 Tx/Rx 中断 
  BRGR0=0xF0;        //1200 baud @ 7.373MHz 
  BRGR1=0x17; 
//  BRGR0=0xF0;        //9600 baud @ 7.373MHz 
//  BRGR1=0x02; 
  BRGCON =0x03;          //使能 BRG 
 
  ESR=1;       //ESR=Enable Serial Recieve  
//  EST=1;       //EST=Enable Serial Transmit 
  EA=1;      //使能中断 
} 




void Rcv_ISR()  interrupt  4
{ //当接收完一个字节 RI 置 1 进入 Recieve 中断 
	EA=0; 
 
	if(!RI) return;        
  	ucRbuf[ucOffset]=SBUF;        //保存所读取的数据 
  	RI=0;      					 //RI 清 0 以等待下次发送 
 
   	EA=1; 

	SendChar(ucRbuf[ucOffset]);//for test only

	ucOffset++;
} 

void SendChar(unsigned char ucData)
{
	EA=0; 
  	SBUF=ucData;        //发送数据 
  	while(!TI);        //当 TI 为 1 时 发送完毕 
 	TI=0;       //TI 清 0 准备下一次发送 
   	EA=1; 
}

/*************************************************************************** 
* 名称:     T1_Init() 
* 功能:     定时器 1 初始化,使 T1(P0.7)输出 38KHz,50%占空比的方波, 
*           作为红外线的载波 当使用 6MHz 晶振时  
*           红外线载频 CCLK/(4 (256 定时器重载值) 
*           定时器重装值=256-CCLK/(4*红外线载频)=256-7372800/(4*38000)=0CFH 
****************************************************************************/ 
void T1_Init() 
{ 
    TH1=0xcf;               //定时器 1 重载值  
    TAMOD=0; 
    TMOD=0x20;                  //定时器 1 工作于模式 2 自动重载  
    AUXR1 |= 0x20;                //置位 ENT1,当 T1 溢出时触发 P0.7 翻转 
    TR1=1;                      //启动定时器 
} 
 

/*
掉电检测中断
*/
/*
void pdown() interrupt 5     
{ 
   	PCONA=0xaf;       //关闭除E PROM外其它所有片内外设的电源 

	WriteFlash((uint)&FLA_set.unCurPluse,*(pucPluseCnt+1));
 
	while(1);    //??   
}
*/

bit  WriteFlash(unsigned int unFlashAddr, unsigned char ucData)
{ 
	 
	
	FMCON = LOAD;              //  装载命令,清除页寄存器 
	FMADRH = (uchar)(unFlashAddr >> 8);          // 
	FMADRL = (uchar)(unFlashAddr & 0xff);          //  页地址写入地址寄存器 
   	FMDATA = ucData ; 

    FMCON = EP;              //  擦除&编程页命令 
//    Fm_stat = FMCON;          //  读结果状态 

    if  ( ( FMCON & 0xF ) !=0 )  return 1 ;
    else return 0 ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -