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

📄 mainproc.c

📁 用单片机进行温度控制
💻 C
字号:
#include<intrins.h>
#include<HeadFile.h>

static uint    SetTemp      = 600;			//系统设定初始温度为20摄氏度
static uint    NowTemp      = 0;			//实测温度,初始为0
static uint    WaveNum      = 0;			//波数
static uint    WaveForWork  = 0;			//加热波数
static uchar   KeyFlag      = 0;			//键盘标志
static uchar   KeyNum       = 0;			//键码


uchar code space = 0x20;
uchar code SetTemperature[] = {"SetTemp:        "};
uchar code NowTemperature[] = {"NowTemp:        "};
//测试用字符串
uchar code copyright1[]     = {"Copyright@2005  "};
uchar code copyright2[]     = {"Designed By PSD "};

void main(void)
{
    InitSys();
	HeatDrive = 0;
	EA=0;
	DisplayListChar(0,0,SetTemperature);
	DisplayListChar(0,1,NowTemperature);
	DisplaySetTemp();
	DisplayOneChar(15,0,0x43);
	DisplayNowTemp();
	DisplayOneChar(15,1,0x43);
	EA  = 1;
	while(1)
	{
		KeyScan();
		EX0 = 0;
		DisplaySetTemp();
		DisplayNowTemp();
		EX0 = 1;
	}
} 
void KeyScan(void)
{
	KeyNum = P1&0x0f;
	if(KeyNum!=0x0f)						//检测是否有键按下?
	{
		Delay5Ms();							//去抖
		if(KeyFlag)return;
		switch(KeyNum)
		{
			case  0x0e:
				{
					if(SetTemp<1000)
					{
						SetTemp+=5;
					}
				}break;						//温度加
			case  0x0d:
				{
					if(SetTemp>5)
					{
						SetTemp-=5;
					}
				}break;						//温度减
			default:   break;
		}
		KeyFlag = 1;
	}
	else KeyFlag = 0; 
}

//写数据
void WriteDataLCD(uchar WDLCD)
{
	ReadStatusLCD();						//检测忙
	LCD_Data = WDLCD;	
	LCD_RS = 1;
	LCD_RW = 0;
	LCD_E = 0;
	LCD_E = 0;
	LCD_E = 1;
}

//写指令
void WriteCommandLCD(uchar WCLCD,BusyC) 	//BusyC为0时忽略忙检测
{
	ReadStatusLCD(); 
	LCD_Data = WCLCD;
	LCD_RS = 0;
	LCD_RW = 0;
	LCD_E = 0;
	LCD_E = 0;
	LCD_E = 1;
}

//读数据
uchar ReadDataLCD(void)
{
	LCD_RS = 1; 
	LCD_RW = 1;
	LCD_E = 0;
	LCD_E = 0;
	LCD_E = 1;
	return(LCD_Data);
}

//读状态
uchar ReadStatusLCD(void)
{
	LCD_Data = 0xFF; 
	LCD_RS = 0;
	LCD_RW = 1;
	LCD_E = 0;
	LCD_E = 0;
	LCD_E = 1;
	while (LCD_Data & Busy); //检测忙信号
	return(LCD_Data);
}

void LCDInit(void) //LCD初始化
{
	LCD_Data = 0;
	WriteCommandLCD(0x38,0); 						//三次显示模式设置,不检测忙信号
	Delay5Ms(); 
	WriteCommandLCD(0x38,0);
	Delay5Ms(); 
	WriteCommandLCD(0x38,0);
	Delay5Ms(); 
	WriteCommandLCD(0x38,1); 						//显示模式设置,开始要求每次检测忙信号
	WriteCommandLCD(0x08,1); 						//关闭显示
	WriteCommandLCD(0x01,1); 						//显示清屏
	WriteCommandLCD(0x06,1); 						// 显示光标移动设置
	WriteCommandLCD(0x0C,1); 						// 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
	Y &= 0x1;
	X &= 0xF; 										//限制X不能大于15,Y不能大于1
	if (Y) X |= 0x40; 								//当要显示第二行时地址码+0x40;
	X |= 0x80; 										//算出指令码
	WriteCommandLCD(X, 0); 							//这里不检测忙信号,发送地址码
	WriteDataLCD(DData);
}

//按指定位置显示一串字符
void DisplayListChar(uchar X, uchar Y, uchar code *DData)
{
	uchar ListLength;
	ListLength = 0;
	Y &= 0x1;
	X &= 0xF; 										//限制X不能大于15,Y不能大于1
	while (DData[ListLength]>0x00) 					//若到达字串尾则退出
	{
		if (X <= 0xF)								//X坐标应小于0xF
		{
			DisplayOneChar(X, Y, DData[ListLength]);//显示单个字符
			ListLength++;
			X++;
		}
	}
}

//5ms延时
void Delay5Ms(void)
{
	uint TempCyc = 5552;
	while(TempCyc--);
}


//400ms延时
void Delay400Ms(void)
{
	uchar TempCycA = 5;
	uint  TempCycB;
	while(TempCycA--)
	{
		TempCycB=7269;
		while(TempCycB--);
	}
}

void delay(uint i)
{
	uint a;
	for(a=0;a<i;a++)
	{;}
}

void InitSys(void)
{
	EA = 0;
	HeatDrive = 0;
	Delay400Ms(); 						//启动等待,等LCM讲入工作状态
	LCDInit(); 							//LCD初始化
	Delay5Ms(); 						//延时片刻
	DisplayListChar(0, 0, copyright1);
	DisplayListChar(0, 1, copyright2);
	Delay400Ms();
}

void DisplaySetTemp(void)
{
	uchar a,b,c;
	a=SetTemp/100;
	b=SetTemp/10%10;
	c=SetTemp%10;	
	a|=0x30;
	b|=0x30;
	c|=0x30;
	DisplayOneChar(10,0,a);
	DisplayOneChar(11,0,b);
	DisplayOneChar(12,0,0x2e);
	DisplayOneChar(13,0,c);
}

void DisplayNowTemp(void)
{
	uchar a,b,c;
	a=NowTemp/100;
	b=NowTemp/10%10;
	c=NowTemp%10;
	a|=0x30;
	a&=0x3f;
	b|=0x30;
	c|=0x30;
	DisplayOneChar(10,1,a);
	DisplayOneChar(11,1,b);
	DisplayOneChar(12,1,0x2e);
	DisplayOneChar(13,1,c);
}

uint PIDFunction(void)
{
	uint WaveRequired;
	ErrorFormer2=ErrorFormer1;	
	ErrorFormer1=ErrorPresent;
	if(SetTemp<=NowTemp)
		ErrorPresent=0;
	else
		ErrorPresent=SetTemp-NowTemp;
	WaveRequired=((GainP+GainI+GainD)*ErrorPresent-(GainP+GainI+GainD)*ErrorFormer1+GainD*ErrorFormer2)/16;
	if(WaveRequired>WavePerCircle)
	  WaveRequired=WavePerCircle;
	return(WaveRequired);
}

void Control() interrupt 0
{
	EA  = 0;
	EX0 = 0;
	WaveNum++;
	if(WaveNum==WavePerCircle)
	{
		WaveNum = 0;
		NowTemp = ReadTemperature();
		WaveForWork = PIDFunction();
	}
	if(WaveNum<=WaveForWork)
	  HeatDrive = 1;
	else
	  HeatDrive = 0;
	EX0 = 1;
	EA  = 1;
}

⌨️ 快捷键说明

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