📄 main.c
字号:
#include <Reg931.h>
#include <Meter_def.h>
#include <Rscomm.h>
#include <General.h>
#ifdef uchar
#define READYDEF 1 //宏uchar已定义
#else
#define uchar unsigned char
#endif
//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
// 变量定义
//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
uchar bdata MeterFlag; //电表运行状态字
sbit Battery = MeterFlag^0; //电池状态
sbit Hardware = MeterFlag^1; //硬件状态
sbit RsComm = MeterFlag^2; //通讯状态
sbit AdjTime = MeterFlag^3; //时钟状态
sbit EryRev = MeterFlag^4; //电能方向
sbit AdjDate = MeterFlag^5; //校时期允许
sbit Fee0 = MeterFlag^6; //费率位0
sbit Fee1 = MeterFlag^7; //费率位1
uchar bdata Flag; //状态标志位1
sbit TimeAdj = Flag^0; //校时时间
sbit TimeProg = Flag^1; //编程时间
sbit RxdFlag = Flag^2; //接收结束
sbit TxdFlag = Flag^3; //应答开关
sbit TxdWork = Flag^4; //发送状态
sbit DspType = Flag^5; //显示类型
sbit DspPage = Flag^6; //显示页
sbit DspFlag = Flag^7; //显示刷新
uchar bdata SystemStates; //状态标志位2
sbit Comm_RTC_Err = SystemStates^0; //实时时钟通讯错误
sbit Comm_EPM_Err = SystemStates^1; //EEPROM通讯错误
sbit Data_RTC_Err = SystemStates^2; //实时时钟数据错误
sbit Data_EPM_Err = SystemStates^3; //EEPROM数据错误
sbit EryBln_Flag = SystemStates^4; //电量结算标志
sbit Prog_Flag = SystemStates^5; //编程允许开关
sbit Fee_Flag = SystemStates^6; //时段费率检查标志
sbit CommFlag = SystemStates^7; //通讯标志
uchar DspSec; //轮显时间秒计数
uchar RevSec; //反向时间秒计数
uchar CommSec; //通讯指示灯显示时间
uchar DspPtr; //轮显指针
uchar ComPtr; //通信缓冲区指针
uchar CommTimer; //通讯帧间隔时间计数
uchar Addr[2]; //地址数据
uchar Len[2]; //地址空间、数据空间长度
uchar PulseTmp[6]; //剩余脉冲数+校验
uchar EryTmp[6]; //电量小数+校验
uchar Ptr[8]; //缓存区指针
uchar RTC[8]; //时间数据+校验
uchar DspPara[4]; //3位显示控制+1位检验和
uchar DspExch[6]; //显示交换区
uchar idata ComBuf[RS_MaxSize]; //通信缓冲区
unsigned int MSSum; //毫秒和
unsigned int ProgTimer; //编程状态计时
//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
// 函数定义、引用
//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
void McuInit(void); //MCU系统配置及初始化
void MeterInit(void); //电表系统初始化
void Int1_isr(void); //外部中断1服务程序(电能脉冲输入处理)
void CMP_isr(void); //比较器中断服务程序(电源和电池电压检测)
void Timer0_isr(void); //Timer0服务程序(通讯超时监测)
void Keyboard_isr(void); //键盘中断服务程序(RS485通讯触发)
void UART_isr(void); //串行中断通讯服务程序
void Watchdogrtc_isr(void); //RTC中断服务程序
//Measure.c
extern void Resume(void); //电表数据恢复
extern void Measure(void); //电能计量
extern void WriteEPMData(uchar idata *ptr); //写数据
extern bit ReadData(uchar idata *ptr);
//RTC_DSP.C
extern void DspPara_Read(void); //读显示控制参数
extern void RTC_Dsp_Proc(void); //时间、显示处理
extern void RTC_Init(void); //RTC初始化设置
extern void RTC_Read(void); //读时间
extern void Fee_CHK(void); //时段、费率检查
extern void Ery_Balance(void); //电量结算
extern void Display(uchar idata *ptr); //数据显示
extern void RTC_Set(uchar staddr,uchar idata *ptr,uchar len);//实时时钟设置
extern bit DateTerm(void); //日期条件判断
//RSCOMM.C
extern void Comm_Proc(void); //通讯处理
//**********************************************************
//名称:main()
//功能:
//说明:主函数
//**********************************************************
void main(void)
{
McuInit(); //MCU初始化
MeterInit(); //电表初始化
while(1)
{
Measure(); //计量处理
RTC_Dsp_Proc(); //时钟、显示处理
Comm_Proc(); //通讯处理
}
}
//**********************************************************
//名称:McuInit()
//功能:
//说明:MCU初始化
//**********************************************************
void McuInit(void)
{
uchar i;
//======================================================
//配置I/O口工作模式
//======================================================
P0M1=0xCA; //11001010
P0M2=0xB5; //10110101
//P0.7开漏 :38K载波
//P0.6输入 :RS485通讯唤醒
//P0.5推挽输出 :RS485收发控制
//P0.4推挽输出 :PDA
//P0.3输入 :电源检测
//P0.2推挽输出 :LED_COMM
//P0.1输入 :电池检测
//P0.0推挽输出 :LED_G
P1M1=0x3F; //00111111
P1M2=0xCD; //11001101
//P1.7推挽输出 :LED_F
//P1.6推挽输出 :通讯信道选择
//P1.5输入 :RST(不可配置,仅为输入模式)
//P1.4输入 :PULSE(电能脉冲)
//P1.3开漏 :SDA
//P1.2开漏 :SCL
//P1.1输入 :RXD
//P1.0开漏 :TXD
P2M1=0x00; //00000000
P2M2=0xFF; //11111111
//P2.7推挽输出
//P2.6推挽输出
//P2.5推挽输出
//P2.4推挽输出
//P2.3推挽输出
//P2.2推挽输出
//P2.1推挽输出
//P2.0推挽输出
P3M1=0x03; //00000011
P3M2=0x00; //00000000
//P3.1输入 :PROG 编程开关
//P3.0输入 :REVP 电能方向
DIVM = 0x00; //振荡器初始化
TRIM &= ~0x40; //P3.0无时钟输出
//TRIM |= 0x40; //P3.0 时钟输出
PT0AD = 0x0A; //P0.1(CIN2B)、P0.3(CIN1B)模拟输入使能
DelayNms(200); //上电延时200mS
//看门狗初始化(2S)
WDL = 0xC2;
//EA = 0;
WDCON = 0xE5;
WFEED1 = 0xA5;
WFEED2 = 0x5A;
//EA = 1;
//EA = 0;
//======================================================
//外部中断1初始化,电能脉冲输入
//======================================================
IT1 = 1; //外部中断1为下降沿触发
IP0H |= 0x04; //设置外部中断1的中断优先级 2级
IP0 &=~0x04;
EX1 = 1; //外部中断1使能
//======================================================
//电源检测、电池检测配置
//======================================================
CMP1 = 0x38; //CE1,CP1,CN1,OE1 = 1110
//正向输入为CIN1B(P0.3)
//选择内部参考电压
CMP2 = 0x38; //CE2,CP2,CN2,OE2 = 1110
//正向输入为CIN2B(P0.1)
//选择内部参考电压
i = 0x18; //延时13uS
while(--i);
CMP1 &= 0xFE; //清楚比较器1的中断标志
CMP2 &= 0xFE; //清楚比较器2的中断标志
IP1H |= 0x04; //设置中断优先级 2级
IP1 &=~0x04;
EC = 1;
//======================================================
//初始化Timer1定时器,使其P0.7发生翻转,输出38K的调制频率
//N=PCLK/(2*38KHz)=3.686400/76000=0x30,定时值=0x100-0x30=0xD0
//======================================================
//HW38K = 1; //P0.7置高
TMOD |= 0x21; //设置Timer0,选择定时器模式1--通讯超时检测
//设置Timer1,选择定时器模式2--红外载波
TAMOD = 0x00; //T0M2=0,T1M1=0,T1M0=1
//T1M2=0,T1M1=1,T1M0=0
TH0 = 0x53; //Timer0定时12mS初值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -