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

📄 main.c

📁 KEILC RTX51tiny开发的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -