📄 main.c
字号:
#include<STC12C5410AD.H>
#include<MATH.H>
#include<Key.H> //按键定义
#include<rtx51tny.H>
#define byte unsigned char
#define T1_Reload_CNT 0x98 //晶振为16MHz,1T模式下,SMOD=1,波特率为9600时,T1的自动装载值
#define True 1
#define False 0
#define SendReData 0 //指令0表示回传接收到的数据
#define SendYValue 1 //指令1表示回传m值
#define SendMValue 2 //指令2表示回传y值
#define conSampNo 0x04 //采样数达到多少时,计算均值
#define condispVolval1 1 //显示控制常数 ,显示电压值1
#define condispYval 2 // 显示控制常数 ,显示Y值
#define condispVolval2 3 //显示控制常数,显示电压值2
#define condispMval 4 //显示控制常数,显示M值
#define conArrowReturn 1 //光标位置为返回
#define conArrowReset 2 //光标位置为复位
#define conArrowSetD 3 //光标位置为设定d值
#define conArrowSetPara 4 //光标位置为标定
#define conFaceDispItemName 1 //项目名称界面
#define conFaceDispSysSet 2 //系统设定界面
#define conTmrClr 4000000000 //清屏定时常数
#define task_INIT 0 //任务0,初始化任务
#define task_CalVal 1 //任务1, 计算各值任务
#define task_SetPara 2 //任务2,设定参数任务
//外部函数定义
extern void displayItemName(); //OCMJ15X20D.C中定义 ,显示采集数据的项目名称
extern displayFloat(float FloatVal,unsigned char orignX,unsigned orignY);// OCMJ15X20D中定义,显示小数
extern void displayFloat2(float FloatVal,unsigned char orignX,unsigned orignY); //OCJ15X20D中定义,显示一位小数和三位整数
extern void displayFloat4(float FloatVal,unsigned char orignX,unsigned orignY); //OCJ15X20D中定义,显示一位小数和三位整数
extern void displaySignFloat(float FloatVal,unsigned char orignX,unsigned orignY); //OCJ15X20D中定义,显示一位小数和三位整数 (带负号) 数)
extern void dispInitial(); //OCMJ15X20D中定义,LCM模块初始化
extern void Delay(unsigned char DelayTM); //OCMJ15X20D中定义,延时子程序,延时 单位为ms
extern unsigned char readKey(); //OCMJ15X20D中定义,读取按键子程序
extern void displayArrow(unsigned char orignX,unsigned orignY); //OCMJ15X20D中定义,显示光标
extern void clearDispData(unsigned char orignX,unsigned orignY); //OCMJ15X20D中义,按坐定标清除显示
extern void displaySysSet(); //OCMJ15X20D中义,显示系统设定界面
extern void displayInteger(unsigned char IntVal,unsigned char orignX,unsigned orignY); //OCMJ15X20D中定义,显示整数
extern void LCM_Clr(); //OCMJ15X20D中定义,液晶模块清屏
extern void displayOk(unsigned char orignX,unsigned orignY); //OCMJ15X20D中定义,显示'OK'
extern void adInit(void); //ad7705中定义,AD转换初始化
extern unsigned int get(unsigned char chanNo); //读取AD7705的采样值
extern void selectChan0(void); //ad7705中定义,选择通道0
extern void selectChan1(void); //ad7705中定义,选择通道1
extern void HC595Output(unsigned int outData); //在74HC595中定义,串并转换发送数据函数
extern void E2PROM_Close(); //E2PROM.C中定义,关闭E2PROM
extern unsigned char E2PROM_Read(unsigned char E2addrH,unsigned char E2addrL); //E2PROM.C中定义,读E2PROM
extern void E2PROM_Write(unsigned char E2addrH,unsigned char E2addrL,unsigned char E2Data); //E2PROM.C中定义,写E2PROM
extern void E2PROM_Erase(unsigned char E2addrH,unsigned char E2addrL); //擦除扇区
//函数定义
void mainInitial(); //初始化函数
float calVoltage(unsigned int sampVal); //根据采样值计算电压值
void UART_Initial(); //UART初始化函数
void UART_SendByte(unsigned char SByte); //UART发送字节函数
bit CheckFrame(); //用于判断1桢数据是否接收完毕
void DoIns(); //执行指令函数
void mainDisplay(); //主显示函数
void changeArrow(); //移动箭头函数
void saveDValue(float dValue); //存储D值到E2PROM (E2PROM地址:0x28,0x00)
float readDValue(void); //读取D值
void saveI0P0Val(void); //存储I0Val,P0Val到E2PROM (E2PROM地址:0x2A00,0x00)
void readI0P0Value(void); //读取Samp值(I0Val,P0Val)到E2PROM (E2PROM地址:0x2A00,0x00)
//全局变量定义
unsigned long sampInt; //存储AD7705的通道0采样值的和
unsigned int smpAvrInt; //存储AD7705的通道0采样值的均值
unsigned char sampNum; //存储AD7705的通道0采样点数目
unsigned long sampInt1; //存储AD7705的通道1采样值的和
unsigned int smpAvrInt1; //存储AD7705的通道1采样值的均值
unsigned char sampNum1; //存储AD7705的通道1采样点数目
unsigned char FrameNo; //数据桢序号,用于存储接收数据和判断数据桢是否接收完毕
bit isReceiveData; //是否接受数据以及接收数据是否处理完毕标志
//(True-接收到数据,False-未接收到数据或者接收数据已处理完毕)
unsigned char flagDispFace; //标示界面状态
unsigned char flagSapChan; //表示采集通道
unsigned char FrameData[4]; //桢数据数组,存储1桢数据中的各个字节
unsigned ArrowState; //记录光标位置
unsigned char ArrowOriX; //光标的坐标
unsigned char ArrowOriY;
unsigned char fInt,fPoint1,fPoint2; //整数部分,小数点后1位,后2位
float P0Value,PValue,DZHI; //计算m值,
float I0Value,IValue,IZHI; //计算y值时用
float voltage,voltage2,mValue,yValue; //采样电压,m值,y值
float dValue;
unsigned int tmpMval,tmpYval; //临时变量用存储M值和Y值取整
unsigned char dispctr; //显示控制变量
unsigned long ctrlClr1,ctrlClr2; //用于清屏循环控制
//函数实现
//主程序初始化
void mainInitial()
{
CLK_DIV=0x00; //设置时钟分频寄存器 (不分频)
FrameNo=0; //数据桢序号赋初值
FrameData[0]=0;
FrameData[1]=0;
sampInt=0;
sampNum=0;
sampInt1=0;
sampNum1=0;
ArrowState=0; //光标位置赋初值 (不显示光标)
ArrowOriX=0x0A;
ArrowOriY=0x30;
fInt=0; //小数寄存器初始化
fPoint1=0;
fPoint2=0;
dispctr=condispVolval1;
dispInitial(); //显示初始化
adInit(); //AD7705初始化
UART_Initial(); //串口初始化
}
//根据采样值计算电压值
float calVoltage(unsigned int sampVal)
{float sampVoltage;
sampVoltage=sampVal*2.5/65535;
return(sampVoltage);
}
//UART初始化函数
void UART_Initial()
{
SCON=0x50; //串口工作在方式1,无奇偶校验,8位可变波特率
TMOD=0x21; //设置定时器1为8位自动重装方式
TH1=T1_Reload_CNT;
TL1=T1_Reload_CNT;
PCON=PCON|(0x80); //波特率加倍
AUXR=AUXR|(0x40); //定时器1工作在1T模式下,波特率可以快12倍
TR1=1; //启动定时器1
ES=1; //串行中断允许位
EA=1; //总中断允许位
}
//UART发送字节函数
void UART_SendByte(unsigned char SByte)
{
TI=0; //清发送中断标志
SBUF=SByte; //字节写入缓冲区
while(!TI) //等待发送完毕
{;};
TI=0; //清0发送标志
}
//判断一桢数据是否接收完毕
bit CheckFrame()
{
if(isReceiveData==True) //若接收到数据
{
isReceiveData=False;
//判断接收的桢数据是否完毕
if (FrameNo==FrameData[0]) //接收完毕
{
FrameNo=0;
return True;
}
else //未接收完毕
{
FrameNo++; //序号加1
return False;
}
}
else
{
return False;
}
}
//主显示函数
void mainDisplay()
{
switch(dispctr)
{
case condispVolval1: //显示减光率
{
if(DZHI>=1)
{
displayFloat4((1-1/DZHI)*100,0x16,0x20); //显示D值(比例数)
}
else if(DZHI<1)
{
displaySignFloat((1-DZHI)*100,0x16,0x20); //显示D值(比例数)
}
//displayFloat3(100,0x18,0x10);
dispctr=condispYval;
break;
}
case condispYval: // 显示Y值
{
displayFloat(yValue,0x18,0xB0); //显示y值
dispctr=condispVolval2;
break;
}
case condispVolval2: //显示电离室电流
{
displayFloat4(IZHI*100.0,0x16,0x80); //显示I值(比例数)
dispctr=condispMval;
break;
}
case condispMval: //显示M值
{
displayFloat(mValue,0x18,0x50);
dispctr=condispVolval1;
break;
}
}
}
//执行指令函数
/*在此程序中要对中断中的一部份变量进行处理,所以在程序执行过程中一定记得关中断 */
void DoIns()
{
unsigned char tmp,tmp2; //临时变量
unsigned int tmpInt;
if (CheckFrame()==True) //若桢数据接收完毕
{
switch(FrameData[1]) //判断指令代码
{
case SendReData: //指令0表示回传接收到的数据
{
for(tmp=2;tmp<=FrameData[0];tmp++)
{
UART_SendByte(FrameData[tmp]);
}
break;
}
case SendYValue: //指令1表示回传Y值
{
tmp2=tmpYval&(0x00FF); //tmp2存储tmpYval低8位
tmpInt=tmpYval;
tmpInt>>=8;
tmp=tmpInt&(0x00FF); //tmp存储tmpYval高8位
UART_SendByte(tmp2);
UART_SendByte(tmp);
//UART_SendByte(170);
//UART_SendByte(85);
break;
}
case SendMValue: //指令2表示回传M值
{
tmp2=tmpMval&(0x00FF); //tmp2存储tmpYval低8位
tmpInt=tmpMval;
tmpInt>>=8;
tmp=(tmpInt)&(0x00FF); //tmp存储tmpYval高8位
UART_SendByte(tmp2);
UART_SendByte(tmp);
//UART_SendByte(170);
//UART_SendByte(85);
break;
}
}
}
}
//串口接收中断函数
void UART_ReceiveByte() interrupt 4
{
RI=0; //清接收中断标志
FrameData[FrameNo]=SBUF; //接收数据放入桢数据数组
isReceiveData=True;
DoIns();
}
void init(void) _task_ task_INIT//任务0
{
dValue=readDValue();
dValue=0.95;
mainInitial(); //初始化
displayItemName(); //液晶显示 项目名称
readI0P0Value();
selectChan0(); //选择AD通道0
flagDispFace=conFaceDispItemName; //项目名称界面
flagSapChan=0; //表示当前采集通道为通道0
WDT_CONTR=0x3C; //喂狗
os_create_task(task_CalVal); //建立任务1
os_create_task(task_SetPara); //建立任务2
os_delete_task(task_INIT); //删除任务0
}
void calvalue(void) _task_ task_CalVal//任务1
{
while(1)
{
WDT_CONTR=0x3C; //喂狗
ctrlClr1++; //清屏循环控制变量加1
if (ctrlClr1>=conTmrClr) //若清屏循环控制达到要求
{
ctrlClr1=0; //清屏循环控制清0
if(flagDispFace==conFaceDispItemName) //若在主界面
{
LCM_Clr(); //清屏
displayItemName(); //液晶显示 项目名称
}
}
switch(flagSapChan)
{
case 0: //AD采样通道为通道0
{
sampInt=sampInt+get(0);
sampNum++; //采样个数加1;
selectChan1(); //选择AD通道为通道1
flagSapChan=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -