📄 main.c
字号:
//======================================================================
// The information contained herein is the exclusive property of
// Sunnnorth Technology Co. And shall not be distributed, reproduced,
// or disclosed in whole in part without prior written permission.
// (C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO.
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorized copies.
//======================================================================
//====================================================================================
//工 程 名: Temperature.spj
//功能描述: 水温的测量、控制等功能
//包含文件: main.c
// isr.asm\key.asm\led.asm、system.asm
// SPCE061A.h\key.h\system.h
// SPCE061A.inc\key.inc
//硬件连接:
// IOA0~2 KEY1~3
// IOA4 A/D输入
// IOA7 继电器控制信号Ctrl
// IOA8~15 SEG(a~f,dp)
// IOB3~5 DIG4~6
// IOB7 Rx1
// IOB10 Tx1
//维护记录: 2006年9月20 v1.0
//====================================================================================
//====================================================================================
//文 件 名: main.c
//功能描述: 水温的测量、控制
//维护记录: 2006年9月20 v1.0
//====================================================================================
#include "key.h"
#include "system.h"
#include "SPCE061A.h"
typedef struct PID
{
float SetPoint; // 设定目标 Desired Value
float Proportion; // 比例常数 Proportional Const
float Integral; // 积分常数 Integral Const
float Derivative; // 微分常数 Derivative Const
int LastError; // Error[1]
int SumError; // 误差累计值
} PID;
PID stPID;
int fOut = 0; // PID计算结果
float fT,K,B;
float PIDCalc( PID *pp, int NextPoint ); // PID计算函数
void ADC_temperature(void); // AD值的数值处理
void Send_temperature(void); // 温度值的通信
void Control_temperature(void); // 温度控制处理
void PIDinit(void); // PID初始化
int adc_data_cmp(); // ADC结果处理
void SetPointValue(); // 设置目标温度
unsigned int giADC_DataSave[18] ; // ADC转换的数据
unsigned int guiLED_Value[3] ={0,0,0}; // 保存显示的LED数字
unsigned int G_ADC_flag = 0;
unsigned int uiStep = 1; // 设置目标温度的位数指针
unsigned int uiBlink; // 设置目标温度的闪烁指针
//====================================================================================
//语法格式:int main(void)
//功能描述: 主函数
//入口参数: 无
//出口参数: 无
//====================================================================================
int main(void)
{
int iKeyValue;
System_Initial(); // 系统初始化
while(1)
{
SP_INT_IRQ5(); // 允许ADC
System_ServiceLoop(); // 键盘扫描
iKeyValue = SP_GetCh(); // 取键值
if(iKeyValue == 4 )
SetPointValue(); // 设置目标温度
if(G_ADC_flag == 1)
{
ADC_temperature(); // ADC结果处理得温度
if (uiStep == 0)
{
Send_temperature(); // 温度送PC机
Control_temperature(); // 根据当前温度执行控制
}
}
*P_Watchdog_Clear = 0x0001; // 清看门狗
}
}
//=============================================================
// 语法格式: void PIDinit(void);
// 实现功能: PID初始化
//入口参数: 无
//出口参数: 无
//====================================================================================
void PIDinit(void)
{
stPID.LastError = 0;
stPID.SumError = 0;
}
//=============================================================
// 语法格式: PIDCalc( PID *pp, int NextPoint);
// 实现功能: PID运算处理
// 入口参数: PID *pp:PID指针;
// int NextPoint:当前温度结果
// 出口参数: PID运算结果
//=============================================================
float PIDCalc( PID *pp, int NextPoint )
{
int dError,Error;
Error = pp->SetPoint*10 - NextPoint; // 偏差
dError = Error - pp->LastError; // 当前微分
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
- pp->Derivative * dError // 微分项
);
}
//=============================================================
// 语法格式: void ADC_temperature(void);
// 实现功能: 将ADC_Value转换为温度值
// 入口参数: 无
// 出口参数: 无
//=============================================================
void ADC_temperature(void)
{
int adc_data;
adc_data = adc_data_cmp();
adc_data /= 16; // 计算温度平均值
K = 0.1555; // 确定温度系数
B = 32.4; // 调整温度偏差
fT = (adc_data * K) - B; // 换算成温度值
// 将温度值转换成十进制
guiLED_Value[0] = (int)fT/10; // 温度十位
guiLED_Value[1] = (int)fT%10; // 温度个位
guiLED_Value[2] = (int)(fT*10)%10; // 温度小数位
G_ADC_flag = 0;
}
//=============================================================
// 语法格式: Send_temperature(void);
// 实现功能: 将温度值传送至上位机
// 入口参数: 无
// 出口参数: 无
//=============================================================
void Send_temperature(void) //Uart Send
{
*P_UART_Data = 0xaa; //桢头
while((*P_UART_Command2&0x0040)==0); //Wait
*P_UART_Data = (int)fT; //整数部分
while((*P_UART_Command2&0x0040)==0); //Wait
*P_UART_Data = guiLED_Value[2]; //小数部分
while((*P_UART_Command2&0x0040)==0); //Wait
*P_UART_Data = 0x55; //桢尾
}
//=============================================================
// 语法格式: Control_temperature();
// 实现功能: 设置PID调解参数,并跟据PID运算结果控制加热器
// 入口参数: 无
// 出口参数: 无
//=============================================================
void Control_temperature()
{
stPID.Proportion = 2; //设置PID比例值
stPID.Integral = 0; //设置PID积分值
stPID.Derivative = 5; //设置PID微分值
fOut = PIDCalc ( &stPID,(int)(fT*10) ); //PID计算
if(fOut<=0)
*P_IOA_Buffer &= 0xff7f; //温度高于设定值,关闭电炉
else
*P_IOA_Buffer |= 0x0080; //温度低于设定值,打开电炉
}
//=============================================================
// 语法格式: adc_data_cmp();
// 实现功能: ADC参数处理,去掉最大值和最小值
// 入口参数: 无
// 出口参数: 去除最大值和最小值后的16次采样总和
//=============================================================
int adc_data_cmp()
{
int max;
int min;
int Sum=0;
int i;
max = giADC_DataSave[0];
for(i=0;i<18;i++)
{
if(giADC_DataSave[i]>max)
max = giADC_DataSave[i]; //取出最大值
}
min = giADC_DataSave[0];
for(i=0;i<18;i++){
if(giADC_DataSave[i]<min)
min = giADC_DataSave[i]; //取出最小值
}
for(i=0;i<18;i++)
Sum += giADC_DataSave[i]; //累计值
Sum = Sum - max-min; //排除最大最小值
return(Sum);
}
//=============================================================
// 语法格式: void SetPointValue();
// 实现功能: 设置目标温度
// 入口参数: 无
// 出口参数: 无
//=============================================================
void SetPointValue()
{
unsigned int iKeyValue;
*P_INT_Ctrl_New |= 0x0008; // 打开4Hz,用于闪烁数码管,表明当前设置位数
uiStep = 0x3;
uiBlink = 0x8; // 闪烁
*P_IOA_Buffer &= 0xff7f;
while(1)
{
*P_Watchdog_Clear = 0x0001;
System_ServiceLoop(); // 键盘扫描
iKeyValue = SP_GetCh(); // 取键值
if (iKeyValue == 4)
{
*P_IOB_Dir |= 0x0038 ;
uiStep-- ;
uiBlink = uiBlink << 1;
if(uiStep == 0)
{
stPID.SetPoint = guiLED_Value[0]*10
+ guiLED_Value[1]
+ 0.1*guiLED_Value[2];
break; // 跳出while
}
}
switch(uiStep)
{
case 3:
if (iKeyValue == 2)
{
guiLED_Value[0]++; // 温度值增加
if(guiLED_Value[0]==10)
guiLED_Value[0] = 0;
}
else if (iKeyValue == 1)
{
if(guiLED_Value[0]==0)
guiLED_Value[0] = 9;
else
guiLED_Value[0]--; // 温度值增加
}
break;
case 2:
if (iKeyValue == 2)
{
guiLED_Value[1]++; // 温度值增加
if(guiLED_Value[1]==10)
guiLED_Value[1] = 0;
}
else if (iKeyValue == 1)
{
if(guiLED_Value[1]==0)
guiLED_Value[1] = 9;
else
guiLED_Value[1]--; // 温度值增加
}
break;
case 1:
if (iKeyValue == 2)
{
guiLED_Value[2]++; // 温度值增加
if(guiLED_Value[2]==10)
guiLED_Value[2] = 0;
}
else if (iKeyValue == 1)
{
if(guiLED_Value[2]==0)
guiLED_Value[2] = 9;
else
guiLED_Value[2]--; // 温度值增加
}
break;
}
}
*P_INT_Ctrl_New &= 0xFFF7; // 关闭4Hz
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -