📄 or100.c
字号:
/*************************************************************************
* Vers Date Changes
* ---- ---------- ---------------------------------------------------*
* v1.0 2008-10-19 main.c 主程序及入口
* ************************************************************************/
//#define DEBUG
//#include <STC12C5410.H>
#include <myheadfile.h>
//#include <math.h>
//常数定义
//**************** 全局变量,以'_G'为后缀 *******************
unsigned char idata netlayer_buff_G[BUFF_MAX_LENTH]; //既做下行网络层接收BUFFER,又做擦写EEPROM时的BUFFER
unsigned char seriers_flag_G; //在串口中断中设置,只有在接收到正确的MAC包后才设置为有效ON,否则设为ERROR或OFF
unsigned char sample_data_G[CHANEL_SUM]; //平均后的采样值,输入光功率1 = AD[0];输入光功率1 = AD[1]
struct { //变量区,共21字节,详见《单向光接收机数据结构》
unsigned int work_statue; //当前工作状态
unsigned char else_preset; //其它设置
unsigned char else_statue; //其它状态
float temperature; //设备温度
float optical_power1; //第1路接收光功率
float optical_power2;
float level_rf1; //第1路RF输出电平
char attenuation1; //第1路输出衰减量
float level_rf2;
char attenuation2;
float level_rf3;
char attenuation3;
float level_rf4;
char attenuation4;
float p24v_supply1;
float p5v_supply1;
float n5v_supply1;
float p3v_supply1;
float p24v_supply2;
float p5v_supply2;
float n5v_supply2;
float p3v_supply2;
} value_G;
//****************************************************
extern void Initital(void); //初始化
extern unsigned char Adc8Filt(unsigned char, unsigned char); //ADC和平均
//extern unsigned char Safeguard(unsigned char);
extern unsigned char Check8Alarm(float,float);
extern unsigned char RdConst8Value(void);
extern unsigned char RdSet(void);
extern unsigned char WriteValue(void);
extern unsigned char ResetDefault(void);
extern void AckIllegal(unsigned char);
extern void AckWrCom(unsigned char);
extern float ByteReversal(float);
//extern unsigned char Rd_DS1820(void);
extern unsigned char GetTemperature(unsigned char);
extern unsigned char code ReserveValue[];
signed char OpticalPowerDetect(unsigned char);
unsigned char OpPowDetect_mW(unsigned char);
void OpticalAgc(signed char);
void Display(signed char);
unsigned char RfLevel(unsigned char);
/*************************************************************************/
/*任务定义:main() */
/*功能描述: 入口,主循环 */
/* 主循环任务 */
/*************************************************************************/
main()
{
//union { float flt; unsigned char bytes[4]; } float2byte ;
unsigned char i,count;
unsigned char temp,tempeX2_avr; //平均后的温度(未对从DS1820采样值做除2处理)
//union{ unsigned char tempeX2[2]; unsigned int union2tempe; } tempe_un;
signed char temp_s;
Initital();
seriers_flag_G = 0x0; //未收到任何下传的数据包
value_G.work_statue = 0x0000;//当前状态
value_G.else_statue = 0x00; //其它状态
value_G.else_preset = 0x00; //其它设置
//-------------------以下为未实现的参数的处理,为固定值-------------------------
value_G.optical_power2 = 0.0; //第2路输入光功率(mW)为最低
/* float2byte.bytes[3] = ReserveValue[0]; //RF输出电平是保留值
float2byte.bytes[2] = ReserveValue[1]; //存在保留量里的数据没有倒序,所以这里要倒序
float2byte.bytes[1] = ReserveValue[2];
float2byte.bytes[0] = ReserveValue[3];
value_G.level_rf1 = float2byte.flt; //包括位倒序,
value_G.level_rf2 = value_G.level_rf1; */
value_G.level_rf3 = 0.0; //本光接收机是两路输出的,所以3、4路为0
value_G.level_rf4 = 0.0;
value_G.attenuation1 = ReserveValue[4]; //RF输出衰减是保留值
value_G.attenuation2 = value_G.attenuation1;
value_G.attenuation3 = 0.0;
value_G.attenuation4 = 0.0;
value_G.p3v_supply1 = 0.0; //ByteReversal(3.3);
value_G.p3v_supply2 = value_G.p3v_supply1;
value_G.n5v_supply1 = 0.0;
value_G.n5v_supply2 = value_G.n5v_supply1;
value_G.p5v_supply2 = 0.0;
value_G.p24v_supply2 = 0.0;
//--------------------------------------------
while(1)
{
// measure execute clock of below code
for(i = 0; i < CHANEL_SUM; i++) sample_data_G[i] = Adc8Filt(sample_data_G[i], i); //ADC并平均
////8个采样通道,+24V电源=AD[0],温度=AD[1];P2口电平=AD[2],P1口电平=AD[3],+5V电源=AD[4];空=AD[5],AD[6];第1路输入光功率=AD[7],
/* ----以浮点格式存贮到变量区中---- */
value_G.p5v_supply1 = ByteReversal(sample_data_G[4]*0.0391);
value_G.p24v_supply1 = ByteReversal(sample_data_G[0]*0.1172);
temp = RfLevel(sample_data_G[3]);
value_G.level_rf1 = ByteReversal(temp*1.0);
temp = RfLevel(sample_data_G[2]);
value_G.level_rf2 = ByteReversal(temp*1.0);
temp_s = OpticalPowerDetect(sample_data_G[7]); //输入光功率(dBm)
Display(temp_s);
OpticalAgc(temp_s);
if(temp_s<-80)
{
value_G.work_statue = value_G.work_statue | 0x4; //如果输入光功率小于-8dBm则认为不正常
value_G.optical_power1 = 0.0;
}
else
{
value_G.work_statue = value_G.work_statue & (~0x4); //输入光功率正常
temp = OpPowDetect_mW(sample_data_G[7]); //计算输入光功率mW
value_G.optical_power1 = ByteReversal(temp/10.0);
}
//-----------------------------------------------------
count = count+1;
if(count==0) //每采样一次温度最大要750ms,所以以下代码不必每次都执行
{
temp = GetTemperature(sample_data_G[1]);//Rd_DS1820();
if(temp>10 && temp<99)
{
tempeX2_avr = (tempeX2_avr + temp)/2; //从DS1820中读取温度,平均
value_G.temperature = ByteReversal(tempeX2_avr*1.0);
}
}
//---------------------------------------------------
if(COVER_DETECT) value_G.work_statue = value_G.work_statue | 0x2; //开盖状态检测
else value_G.work_statue = value_G.work_statue & (~0x2);
// value_G.else_status = Status(); //除采样值以外的其它工作状态(比如某些开关量)的检查更新
// measure execute clock of upward code
/**************************************************************************/
if(seriers_flag_G!=OK && seriers_flag_G!=0x00) //如果超时或者校验错
{
AckIllegal(seriers_flag_G); //上传MAC层错误的响应
seriers_flag_G=0x00;
}
if(seriers_flag_G==OK) //如果上位机发来了给自己的有效指令,MAC层已经在串口中断中剥去,netlayer_buff_G只剩下网络层
{
/*下行网络层包结构:command+offset+lenth+(write_data) */
seriers_flag_G=0x00;
switch(netlayer_buff_G[0]) // command
{
case 0x01: //读常量
case 0x02: //读变量
i = RdConst8Value();
if(i==FAULS) AckIllegal(0x14); //上传网络层超界错误的响应
break;
case 0x03: //写变量
i = WriteValue();
AckWrCom(i);
break;
case 0x04: //读控制量
i = RdSet();
if(i==FAULS) AckIllegal(0x14); //上传网络层超界错误的响应
break;
case 0x05: //写控制量
if(netlayer_buff_G[1]==0x0&&netlayer_buff_G[3]==0x55)
{
i = ResetDefault(); //恢复出厂默认设置
AckWrCom(i);
}
else
{ //对"其它设置"、“输出RF衰减”等的写
i = RIGHT; //目前预留,直接返回正确
AckWrCom(i);
}
break;
default: AckIllegal(0x11); //非法指令则上传网络层错误的响应
}
}
}
}
/*************************************************************************/
/*任务定义:串口中断 */
/*输入:无 */
/*输出:seriers_flag_G, OK:收到正确MAC层数据, 0x1:错误A5, 0x2:校验错误, 0x4:其它MAC错误 */
/*算法:*/
/* 接收包结构为:同步(1byte)+MAC地址(1byte)+长度(1byte)+净负荷(n byte)+校验(1byte) */
//返回:netlayer_buff_G中存有网络层的数据,seriers_flag_G:=0表示没有接收到数据,=OK表示接收到MAC层正确的数据,其它:MAC层错误
/*************************************************************************/
void SER_int() interrupt 4 using 2
{
static unsigned char state_mathine = 0x0;
static unsigned char check_sum = 0x0, lenth_MAC = 0x0, index = 0x0, flagA5_bit = 0;
unsigned char recv_data;
unsigned char temp;
if (RI)
{
RI = 0;
recv_data = SBUF;
if(TF0==1) //如果这时定时器已经溢出,则说明已经超时,强行进入初始状态
{
TF0=0;
TH0 = TIMER0_OV;
state_mathine = 0x0; //错误并返回到初始状态
}
switch(state_mathine)
{
case 0x0: //起始接收,初始状态
if(recv_data == 0xA5)
{
state_mathine = 0x1;
check_sum = 0x0;
flagA5_bit = 0;
seriers_flag_G = 0x0;
index = 0x0;
TH0 = TIMER0_OV;
TR0 = 1; // 启动超时计数器
} // 否则什么也不做,仍然保持在等待接收同步头状态
break;
case 0x1: //已经收到同步头,MAC地址比较
TH0 = TIMER0_OV; // 重置超时计数器
if(recv_data != 0xA5) //如果不再是0xA5,表示真正有效数据开始,接收的是MAC地址
{
temp = SELF_MAC_ADDR ; //获取本机MAC地址
if(recv_data == temp) //如果地址相符
{
state_mathine = 0x2;
check_sum += recv_data; //累加校验和
// flagA5_bit = 0;
// seriers_flag_G = 0x0;
// index = 0x0;
}
else
{
state_mathine = 0x0; //地址不符,不是呼叫本机,回到初始状态
// check_sum = 0;
// flagA5_bit = 0;
seriers_flag_G = 0x0;
// index = 0x0;
TR0 = 0;
}
} // 如果还是0xA5则什么也不做,仍然保持在等待接收有效数据状态
break;
case 0x2: //地址符合后,取长度
TH0 = TIMER0_OV; // 重置超时计数器
// 长度不可能是A5,所以不用做A5判别,即使是A5,也会在长度是否超长判别时剔除
if(recv_data > BUFF_MAX_LENTH) //如果长度超过缓冲区的长度
{
state_mathine = 0x0; //错误并返回到初始状态
check_sum = 0;
flagA5_bit = 0;
seriers_flag_G = 0x3; //超长错误
index = 0x0;
TR0 = 0;
}
else
{
state_mathine = 0x3;
check_sum += recv_data; //累加校验和
flagA5_bit = 0; //清标记
seriers_flag_G = 0x0;
index = 0x0;
lenth_MAC = recv_data; //获取长度
}
break;
case 0x3: //取出长度后,按长度取网络层数据
TH0 = TIMER0_OV; // 重置超时计数器
if(flagA5_bit == 1 && recv_data != 0xA5) //如果之前收到的是A5而且新收到的不是A5
{
state_mathine = 0x0; //错误并返回到初始状态
check_sum = 0;
flagA5_bit = 0;
seriers_flag_G = 0x1; //A5错误
index = 0x0;
TR0 = 0;
}
else if(flagA5_bit==0 && recv_data == 0xA5) //如果收到A5而且是第一个A5
flagA5_bit = 1; //设标记,仍然保持当前的状态,准备接收下一个A5
else //其它情况(收到A5而且是第二个A5,或者根本不是A5)
{
check_sum += recv_data; //累加校验和
flagA5_bit = 0; //清标记
seriers_flag_G = 0x0;
netlayer_buff_G[index] = recv_data; //获取数据
index++;
state_mathine = (index == lenth_MAC) ? 0x4 : 0x3; //如果没取完网络层数据则仍然保持目前状态
}
break;
case 0x4: //取完网络层数据后,比较校验和
TH0 = TIMER0_OV; // 重置超时计数器
if(flagA5_bit == 1 && recv_data != 0xA5) //如果之前收到的是A5而且新收到的不是A5
{
state_mathine = 0x0; //错误并返回到初始状态
check_sum = 0;
flagA5_bit = 0;
seriers_flag_G = 0x1; //A5错误
index = 0x0;
TR0 = 0;
}
else if(flagA5_bit==0 && recv_data == 0xA5) //如果收到A5而且是第一个A5
flagA5_bit = 1; //设标记,仍然保持当前的状态,准备接收下一个A5
else //其它情况(收到A5而且是第二个A5,或者根本不是A5)
{
state_mathine = 0x0;
flagA5_bit = 0; //清标记
recv_data = -recv_data; //获取校验和
#ifdef DEBUG
seriers_flag_G = OK;
#else
seriers_flag_G = (check_sum == recv_data) ? OK : 0x02; //校验错误
#endif
check_sum = 0;
index = 0;
TR0 = 0;
}
break;
default : //其它情况
state_mathine = 0x0; //错误并返回到初始状态
check_sum = 0;
flagA5_bit = 0;
seriers_flag_G = 0x4; //其它错误
index = 0x0;
TR0 = 0;
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -