📄 main.c
字号:
#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 + -