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

📄 main.c

📁 水温控制系统,凌阳的61板做的
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "s480.h"
#define	P_IOA_Data   			(volatile unsigned int *)0x7000
#define P_IOA_Buffer        	(volatile unsigned int *)0x7001
#define P_IOA_Dir           	(volatile unsigned int *)0x7002
#define P_IOA_Attrib        	(volatile unsigned int *)0x7003
#define P_IOB_Data				(volatile unsigned int *)0x7005
#define P_IOB_Dir           	(volatile unsigned int *)0x7007
#define P_IOB_Attrib        	(volatile unsigned int *)0x7008
#define P_TimerA_Data        	(volatile unsigned int *)0x700A 
#define P_TimerA_Ctrl        	(volatile unsigned int *)0x700B
#define P_INT_Ctrl				(volatile unsigned int *)0x7010
#define ClearWDog				*(volatile unsigned int *)0x7012=1
#define P_ADC_Ctrl				(volatile unsigned int *)0x7015
#define P_UART_Command1			(volatile unsigned int *)0x7021
#define P_UART_Command2			(volatile unsigned int *)0x7022
#define P_UART_Data				(volatile unsigned int *)0x7023
#define P_UART_BaudScalarLow	(volatile unsigned int *)0x7024
#define P_UART_BaudScalarHigh	(volatile unsigned int *)0x7025
#define P_ADC_MUX_Ctrl			(volatile unsigned int *)0x702B
#define P_ADC_MUX_Data			(volatile unsigned int *)0x702C
#define P_INT_Ctrl_New			(volatile unsigned int *)0x702D
#define HaveKey  1
#define NoKey    0

typedef struct PID {
        unsigned int    TempValSet;         //  设定目标 Desired Value
        unsigned int    TempValShould;		//  当前应烧到的温度
        float  Proportion;         //  比例常数 Proportional Const
        float  Integral;           //  积分常数 Integral Const
        float  Derivative;         //  微分常数 Derivative Const
        unsigned int    LastError;          //  Error[1]
        unsigned int    PrevError;          //  Error[2]
        unsigned int    SumError;           //  误差累计值

} PID;
PID  stPID;

void Delay(unsigned int n);		//延时
void InitAll();					//初始化
void ScanKey();					//键盘扫描
void BaoYinProg();				//报当前温度
void InputProg();				//"输入温度"键处理
void ResetProg();				//"复位"键处理
void DingBaoProg();				//"定时报音"键处理
void NoProg();					//"取消"键处理
void YesProg();					//"确定"键处理
void NumProg(unsigned int i);	//数字键处理
void AD2Temp();					//读AD,转换成温度
void PIDCal();					//PID运算
void Up2Com();					//当前温度上传到计算机
void Warn();					//干烧报警

unsigned int  KeyVal;
unsigned int  KeyDownTimes;     //保存按键次数
unsigned int  KeyFlag;          //按键标识

unsigned int  TempPress;		//  1:按下"输入温度";  0:没按
unsigned int  ResetPress;		//  1:按下"复位";  0:没按
unsigned int  TempSet;			//  1:输入完温度;  0:没输入完
unsigned int  DingShi;			//  1:5分钟定时报音;  0:不定时报音
unsigned int  Boil;				//  1:要烧开;  0:不烧开
unsigned int  BoiledOK;			//  1:保温状态;  0:加热状态
unsigned int ADOK;				//  1:AD转换完成;  0:没完成
unsigned int DispIt;			//  1:刷新LCD;  0:不刷新 (0.5s)

unsigned int  Num;				//输入数字的个数(0,1,2)
unsigned int  TempValTemp;		//临时保存设定温度
float  TempValNow;				//当前温度
unsigned int  DingShiTime;		//定时报音时间累计
unsigned int  UpTime;			//上传时间累计
unsigned int  HeatTime;			//加热时间(毫秒)
unsigned int ADCDataSave[10];	//读取的10次AD值
unsigned int TempRecent[20];	//近20次的AD值
float	max20;	//20次的最高温度
float	min20;	//20次的最高温度

unsigned int ShiWei,GeWei,DianHou;

//=============================================================================================== 
// 函数: main()
// 描述:主函数
//============================================================================================
int main()
{
unsigned int i;
InitAll();			//初始化
while(1)
	{
	ClearWDog;
	if(ADOK=1)
		{
		AD2Temp();
		}
	if(TempPress==0&&ResetPress==0&&DispIt==1)
		{
		DispIt=0;
		Disp(7);
		}
	if(UpTime>=10)	//5s,上传到电脑
		{
		UpTime=0;
		Up2Com();					
		}
	if(DingShiTime>=600)	//定时5分钟,报音
		{
		DingShiTime=0;
		BaoYinProg();							
		}
	if(BoiledOK==0)	//加热状态
		{
		if(TempRecent[19]!=0)
			{
			if((max20-min20)<2)	//温度已不变
				{
				if(TempValNow<stPID.TempValSet)	//不能达到设定温度
					{
					Disp(10);
					for(i=0;i<10;i++)
						Warn();
					Delay(0x00af);
					Disp(7);
					}
				else	//烧开了
					{
					Disp(9);
					stPID.TempValShould=stPID.TempValSet;
					BoiledOK=1;
					*P_IOB_Data|=0x000f;	//烧开指示灯
					*P_IOB_Data&=0xffdf;	//关继电器
					}
				}
			else	//温度在上升
				{
				if(TempValNow<(stPID.TempValShould-3))	//没加热到设定值
					{
					PIDCal();
					}
				else	//达到设定温度
					{
					BoiledOK=1;
					*P_IOB_Data&=0xffdf;	//关继电器
					}
				}
			}
		}
	else	//保温状态
		{
		if(TempValNow<(stPID.TempValShould-3))	//小于设定-3度,要加热
			{
			BoiledOK=0;
			PIDCal();
			}
		}
	ScanKey();
	}
}

//=============================================
//函数: Delay
//语法: void Delay(unsigned int n)
//输入参数:  n: 延时外循环次数
//说明: 延时函数
//=============================================
void Delay(unsigned int n)
{

unsigned int i,j;
for(i=1;i<=n;i++)
	for(j=1;j<=0x0fff;j++)
		ClearWDog;
}


//=============================================
//函数: InitAll
//语法: void InitAll()
//参数: 无
//说明: 初始化系统
//=============================================
void InitAll()
{
			 			//fedcba9876543210
*P_IOA_Dir=0xf0c0;		//1111000011000000		A8-A15:键盘扫描;
*P_IOA_Attrib=0xf0c1;	//1111000011000001		A7:LCD-SI	A6:LCD-SCL
*P_IOA_Data=0xf041;		//1111000001000001		A0:ADC输入

*P_IOB_Dir=0x0438;		//0000010000111000		B3:烧开指示灯; B4:定时报音指示灯
*P_IOB_Attrib=0x0438;	//0000010000111000		B5:继电器控制;
*P_IOB_Data=0x0410;		//0000010000010000		B7:RS232输入; B10:RS232输出

InitGraphic();
F_UART_Initial();

*P_TimerA_Ctrl=0x0033;		//时钟源A:8K  时钟源B:1
*P_TimerA_Data=0xff7f;		//10 ms

*P_ADC_MUX_Ctrl=0;				//LINE_IN-------IOA0
*P_ADC_Ctrl=0x0003;				//2V_REF,MIC_OFF_,ADC enable
ADCDataSave[0]=*P_ADC_MUX_Data;	//ADC start

stPID.TempValSet=0;
stPID.TempValShould=0;
stPID.Proportion=1;		//  设置PID比例值
stPID.Integral=0.5;   	//  设置PID积分值
stPID.Derivative=0.0;   //  设置PID微分值
stPID.LastError=0;
stPID.PrevError=0;
stPID.SumError=0;

KeyVal=0;
KeyDownTimes = 0;
KeyFlag = NoKey;

TempPress=0;
ResetPress=0;
TempSet=0;
DingShi=1;
Boil=0;
BoiledOK=0;
ADOK=0;
DispIt=0;

Num=0;
TempValTemp=0;
TempValNow=0;
DingShiTime=0;
UpTime=0;
HeatTime=0;
max20=0;
min20=0;

Disp(1);
Delay(0x00af);
Disp(7);

*P_INT_Ctrl_New=0x3004;			//开中断
asm("INT FIQ,IRQ");
BaoYinProg();

}


//=============================================
//函数: ScanKey
//语法: void ScanKey()
//参数: 无
//说明: 键盘扫描
//=============================================
void ScanKey()
{
F_Key_Scan();
while(KeyFlag == HaveKey)
	{			
	KeyVal=F_Get_Key();
	if(KeyVal!=0)
		{
	  	switch(KeyVal)
	  		{
	  		case 0x1100:KeyVal=1;break;				//输入1
	  		case 0x1200:KeyVal=2;break;				//输入2
	  		case 0x1400:KeyVal=3;break;				//输入3
	  		case 0x1800:KeyVal=4;break;				//输入4
	  		case 0x2100:KeyVal=5;break;				//输入5
	  		case 0x2200:KeyVal=6;break;				//输入6
	  		case 0x2400:KeyVal=7;break;				//输入7
	  		case 0x2800:KeyVal=8;break;				//输入8
	  		case 0x4100:KeyVal=9;break;				//输入9
	  		case 0x4200:KeyVal=0;break;				//输入0
	  		case 0x4400:							//输入“报音”
	  					BaoYinProg();		
	  					break;
	  		case 0x4800:							//输入“输入温度”
	  					InputProg();
	  					break;
	  		case 0x8100:							//输入“复位”
	  					ResetProg();
	  					break;
	  		case 0x8200:							//输入“定时报音”
	  					DingBaoProg();
	  					break;
	  		case 0x8400:							//输入“取消”
	  					NoProg();
	  					break;
	  		case 0x8800:							//输入“确定”
	  					YesProg();
	  					break;
	  		default:
	  		}
	  	if(KeyVal>=0&&KeyVal<10)
	  		NumProg(KeyVal);
		}
	KeyFlag = NoKey;
	}
}


//=============================================
//函数: BaoYinProg
//语法:void BaoYinProg(unsigned int i)
//参数:无
//说明:“报音”对应的函数
//==============================================
void BaoYinProg()
{
unsigned int temp;
ClearWDog;
*P_INT_Ctrl_New&=0xfffb;				//关2Hz中断
temp=(int)(TempValNow*10);
DianHou=temp%10;
GeWei=(temp/10)%10;
ShiWei=temp/100;
if(ShiWei!=0)
	{
	if(ShiWei!=1)
		{
		SACM_S480_Initial(1);
		SACM_S480_Play(ShiWei,3,3);
		while((SACM_S480_Status()&0x0001)!=0)
			{
			ClearWDog;
			SACM_S480_ServiceLoop(); 
			}
		SACM_S480_Stop();
		}
	SACM_S480_Initial(1);
	SACM_S480_Play(10,3,3);
	while((SACM_S480_Status()&0x0001)!=0)
		{
		ClearWDog;
		SACM_S480_ServiceLoop(); 
		}
	SACM_S480_Stop();
	}
if(ShiWei==0||GeWei!=0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -