📄 rmeter.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 + -