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

📄 main.c

📁 《增强型8051单片机实用开发技术》例程代码
💻 C
字号:
/* 本例程uCOS-II 版本为2.51*/  #include "includes.h"

sbit POSITIVE=P2^5;
sbit NEGATIVE=P2^4;
sbit RUN=P2^0;
sbit ALARM=P2^3;
sbit BITR=P2^7;
sbit SEGR=P2^6;
sbit BITG=P2^1;
sbit SEGG=P2^2;
sbit KEY1=P0^0;
sbit KEY2=P0^1;
sbit KEY3=P0^2;
sbit KEY4=P0^3;

OS_STK Task1Stk[MaxStkSize+1];	//任务堆栈
OS_STK Task2Stk[MaxStkSize+1];
OS_STK Task3Stk[MaxStkSize+1];
OS_STK Task4Stk[MaxStkSize+1];
OS_STK Task5Stk[MaxStkSize+1];

INT8U code LED[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//LED编码表
INT8U code g[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};			   //位码控制表
INT8U xdata flashbit=0;
INT8U xdata flash=0;
INT8U xdata adcr;
INT16U xdata sec=0;
INT8U xdata key_last0=1,key_last1=1,key_last2=1,key_last3=1,key_num=0xff;
INT8U xdata sec0,sec1,minute0,minute1;
INT8U xdata dispressure=0;
INT8U xdata HIlimit=80,LOWlimit=20;
INT8U err;

//----------------------- AD转换值的刷新 -----------------//
unsigned char Get_data(void) reentrant	          
{
	unsigned int xdata adc_res0,adc_res1;		   
    
	ADC_CONTR|=0x08;            		//启动A/D转换
	while((ADC_CONTR&0x10)==0); 		//等待A/D转换结束        
	ADC_CONTR&=0xE7;
	adc_res0=ADC_RES;
	adc_res1=adc_res0*39/100;			//进行相应的工程变换
	return((unsigned char)(adc_res1));	//BCD编码
}
//--------------------- 显示数据发送 ---------------------//
void sendspi(unsigned char spidata,unsigned char isBit)	reentrant
{   
	unsigned char xdata t,spi1_status=0;
	//EA=0;       				//关中断, 为了避免传输数据过程中被中断而显示乱码
	SPDAT=spidata;
	while(spi1_status==0) 		//等传输完毕
	{
		spi1_status=SPSTAT;
		spi1_status=spi1_status&0x80;
	}
	if (isBit==1)
	{
		BITR=1;
		for(t=0;t<15;t++);
		BITR=0;            		//位锁存信号输出
	}
	else
	{
		SEGR=1;
		for(t=0;t<15;t++);
		SEGR=0;               	//段锁存信号输出
	}
	SPSTAT=0xC0;         		//写1清SPIF标志位
	//EA=1;                		//开中断
}
//--------------------- 显示数据子程序--------------------//
void displayLED(unsigned char* disbuf,unsigned char flashbit) reentrant
{
	unsigned char xdata i;
	
	for(i=0;i<8;i++) 
	{
		SEGG=1;
		sendspi(g[i],1);
		sendspi(disbuf[i],0);
		if(i+1==flashbit) SEGG=flash; 
		else SEGG=0;
		OSTimeDlyHMSM(0,0,0,2);
	}
}
//----------------------- 获取按键 -----------------------//
void getkey(void) reentrant
{
	if(KEY1==0&&key_last0==1)
	{
	  	OSTimeDlyHMSM(0,0,0,20);
		if(KEY1==0&&key_last0==1)	
		{
			 key_num=0;
			 key_last0=0;
		}
	    else if(KEY1==1) key_last0=1;
    }
	else if(KEY1==1) key_last0=1;
	
	if(KEY2==0&&key_last1==1)
	{
	  	OSTimeDlyHMSM(0,0,0,20);
		if(KEY2==0&&key_last1==1)	
		{
			 key_num=1;
			 key_last1=0;
		}
	    else if(KEY2==1) key_last1=1;
    }
	else if(KEY2==1) key_last1=1;
    
	if(KEY3==0&&key_last2==1)
	{
	  	OSTimeDlyHMSM(0,0,0,20);
		if(KEY3==0&&key_last2==1)	
		{
			 key_num=2;
			 key_last2=0;
		}
	    else if(KEY3==1) key_last2=1;
    }
	else if(KEY3==1) key_last2=1;
	
	if(KEY4==0&&key_last3==1)
	{
	  	OSTimeDlyHMSM(0,0,0,20);
		if(KEY4==0&&key_last3==1)	
		{
			 key_num=3;
			 key_last3=0;
		}
	    else if(KEY4==1) key_last3=1;
    }
	else if(KEY4==1) key_last3=1;	
}
//----------------------按键处理子程序 -------------------//
void keyhandle(void) reentrant
{  
	unsigned char xdata low0,low1,hi0,hi1;
	
	low0=LOWlimit%10;
	low1=LOWlimit/10;
	hi0=HIlimit%10;
	hi1=HIlimit/10;
	switch(key_num)
	{
		case 0:
			if(flashbit==8) flashbit=0;
			flashbit++;
			dispressure=1;
			break;
		case 1: 
		  	if(flashbit==1)
			{
				low0++;
				if(low0==10) low0=0;
			}
			if(flashbit==2)
			{
				low1++;
				if(low1==10) low1=0;
			}
			if(flashbit==3)
			{
				hi0++;
				if(hi0==10) hi0=0;
			}
			if(flashbit==4)
			{
				hi1++;
				if(hi1==10) hi1=0;
			}
			if(flashbit==5)
			{
				sec0++;
				if(sec0==10) sec0=0;
			}
			if(flashbit==6)
			{
				sec1++;
				if(sec1==6) sec1=0;
			}
			if(flashbit==7)
			{
				minute0++;
				if(minute0==10) minute0=0;
			}
			if(flashbit==8)
			{
				minute1++;
				if(minute1==6) minute1=0;
			}
			break;
		case 2:
			if(flashbit==1)
			{
				if(low0==0) low0=10;
				low0--;
			}
			if(flashbit==2)
			{
				if(low1==0) low1=10;
				low1--;
			}
			if(flashbit==3)
			{
				if(hi0==0) hi0=10;
				hi0--;
			}
			if(flashbit==4)
			{
				if(hi1==0) hi1=10;
				hi1--;
			}
			if(flashbit==5)
			{
				if(sec0==0) sec0=9;
				sec0--;
			}
			if(flashbit==6)
			{	
				if(sec1==0) sec1=6;
				sec1--;
			}
			if(flashbit==7)
			{
				if(minute0==0) minute0=10;
				minute0--;
			}
			if(flashbit==8)
			{
				if(minute1==0) minute1=6;
				minute1--;
			}
			break;
		case 3:
		  	flashbit=0;
			dispressure=0;
			break;
	}
	HIlimit=hi0+hi1*10;
	LOWlimit=low0+low1*10;
	sec=minute1*600+minute0*60+sec1*10+sec0;
}
/////////////////////////////////////////////////////////////////////
void Task1(void *ppdata) reentrant   //AD转换+串口显示任务
{
	unsigned char xdata adcl,adch;

	ppdata=ppdata;	//防止警告
	ET0=1;			//开时钟节拍中断--根据杨屹文章更改
	BITG=0;
  	SEGG=0;
  	PrintChar('H');
	PrintChar('E');
	PrintChar('L');
	PrintChar('L');
	PrintChar('O');
	PrintChar('\r');
	PrintChar('\n');

for(;;)
  {
		adcr=Get_data();						 //AD转换
		adcl=(adcr%10)|0x30;
		adch=(adcr/10)|0x30;
		PrintChar(adch);						 //发送AD转换结果
		PrintChar(adcl);
		PrintChar('\r');
		PrintChar('\n');
		flash=~flash;
		OSTimeDly(OS_TICKS_PER_SEC/4);	
  }    
}

void Task2(void *ppdata) reentrant	 //时钟任务
{
	ppdata=ppdata;

	for(;;)
  	{ 
		sec++;
		if(sec>5999) sec=0;
	  	PrintChar('O');
		PrintChar('K');
		PrintChar('\r');
		PrintChar('\n');
		OSTimeDlyHMSM(0,0,0,999);
  	}    
}

void Task3(void *ppdata) reentrant	 //报警任务
{
	ppdata=ppdata;

	for(;;)
  	{	
		if(adcr>HIlimit)								 //上限报警
		{
			CMOD=0x0c;
			PCA_PWM1=0x00;
			CCAP1H=0x10;
			OSTimeDly(OS_TICKS_PER_SEC/4);
			PCA_PWM1=0x03;
			POSITIVE=0;
			ALARM=0;
			OSTimeDly(OS_TICKS_PER_SEC/2);
		} 
		else if(adcr<LOWlimit)					 		//下限报警
		{
		 	CMOD=0x00;
			PCA_PWM1=0x00;
			CCAP1H=0x40;
			OSTimeDly(OS_TICKS_PER_SEC/2);
			PCA_PWM1=0x03;
			NEGATIVE =0;
ALARM=0;
			OSTimeDly(OS_TICKS_PER_SEC);
		}
		else 
{
POSITIVE=1;
NEGATIVE =1;
ALARM=1;
OSTimeDlyHMSM(0,0,5,0);
}
   	}    
}

void Task4(void *ppdata) reentrant	 //数码管显示任务
{
	unsigned char xdata disbuf[8]={0,0,0x31,0x63,0,0,0,0};

	ppdata=ppdata;

	for(;;)
  	{	
		sec0=(sec%60)%10;
		sec1=(sec%60)/10;
		minute0=(sec/60)%10;
		minute1=(sec/60)/10;
		disbuf[4]=LED[sec0];						 	//显示时间
		disbuf[5]=LED[sec1];
		disbuf[6]=LED[minute0];
		disbuf[7]=LED[minute1];					 
		if(dispressure==0)							 	//当前压力
		{
		  disbuf[0]=LED[adcr%10];
			disbuf[1]=LED[adcr/10];
			disbuf[2]=0x31;
			disbuf[3]=0x63;
		}
		else										 	//显示报警上下限
		{
			disbuf[0]=LED[LOWlimit%10];
			disbuf[1]=LED[LOWlimit/10];
			disbuf[2]=LED[HIlimit%10];
			disbuf[3]=LED[HIlimit/10];
		}
		
		displayLED(disbuf,flashbit);		 			//闪烁控制
  }    
}

void Task5(void *ppdata) reentrant	 //按键任务
{
	ppdata=ppdata;

	for(;;)
  {	
		getkey();				//获取按键
		if(key_num!=0xff)      	//确保每按一次按键执行一次按键处理程序
		{
			 keyhandle(); 		//处理按键
			 key_num=0xff;
		}
		OSTimeDly(10);
  }    
} 

void main(void)
{																	
	OSInit();									//操作系统初始化
	InitHardware();								//硬件初始化

	//FirstSem=OSSemCreate(0);					//定义一个信号量
	//FirstMbox=OSMboxCreate((void*)0);			//定义一个邮箱

	OSTaskCreate(Task1,(void*)0,&Task1Stk[0],0);//创建5个任务
	OSTaskCreate(Task2,(void*)0,&Task2Stk[0],1);
	OSTaskCreate(Task3,(void*)0,&Task3Stk[0],3);
	OSTaskCreate(Task4,(void*)0,&Task4Stk[0],4);
	OSTaskCreate(Task5,(void*)0,&Task5Stk[0],2);

	OSStart();									 //启动操作系统
}

⌨️ 快捷键说明

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