?? 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 + -