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

📄 main.c

📁 针对STC8051单片机的开发包
💻 C
字号:
/******************************************
STC 单片机开发程序。V0_1_1
//在KEIL uVision3中,如有不清楚的函数封装,选中后点右键,选择“GO TO Ddfinition Of 'XXXXXX'“
//可以看到该函数的原形。

//create by changshengwuji 
//email: netspider@163.com
//qq:    450353168
//2006.05.03
********************************************************************/

//5a 55 a2 51 	read addr
//5a 10 a5 0f	read integer t
//5a 10 a3 0d   read tp
//5a 10 a6 10	shut
//5a 10 a7 11   open
//5a 10 a1 0b   modify addr

#include "../inc/MCS_X51.H"
#include "../inc/hardmap.h"
#include "../inc/MCS_X51LIB.H"
#include "../inc/DS18B20.H"

#include "../inc/stc_flash.H"

#define EXT_11M      1			//外部11.0592MHz晶体
 //#define EXT_1M		1				//外部输入时钟1Mhz
 #define  UART_ERR	0XEE
#define  UART_SUC   0XA0
//------上位机命令---------------
#define  SET_ADDR	0XA1	//设置本机地址
#define  READ_ADDR	0XA2	//读取本机地址
#define  READ_T  	0XA3    //读取温湿度
#define  HEAT		0XA4	//加热命令
#define  READ_S		0XA5	//READ SHORT TEMPERATURE
#define  SHUT 		0XA6    //关
#define  OPEN		0XA7	//开
#define  TEST		0XA0	//TEST CODE

#define  HEAD     0X5A	   //帧头
#define  ADDR	  0X10		//默认本机地址

#define  ERR_ADDR	0XE1	//设置地址错误应答
#define  ERR_VERI	0XE2	//上位机发送的数据校验和不对应答。
#define	 ERR_TH		0XE3	//本机读取温湿度时出错应答。即后面的数据不可靠

#define  SUCC_ADDR	0XF1	//设置地址成功应答
#define  SUCC_TH	0XF2	//表示温湿度读数正确。
#define  ASK		0XF8	//应答
#define  SYS_ADDR	0XAA	//系统标志,表示该机的地址已经设置。
#define  RA_FLAG    0X55	//上位机读本机地址时,在地址位发送该标志。 

#define    TIMING_5MS	 0XEE00			//TIMING 5MS @ 11.0592MHz
#define    TIMING_10MS	 0XDC00			//TIMING 10MS @ 11.0592MHz
#define    NUM_SEG		3				//	数码管个数
					
//*******************************************************************
//------------uart------------------------------
bit		bit_ut_start = 0;
bit 	bit_ut_over	 = 0;

//----------ds18b20-------------------------------
bit 	bit_tpsensor = 0;
//-----------IAP---------------------------------------
bit     bit_iap = 0;
bit     bit_10ms     = 0;
bit     bit_100ms    = 0;
bit     bit_1s	     = 0;
bit     bit_400ms    = 0;

bit		bit_10ms_over  = 0;
bit		bit_400ms_over = 0;

data UINT8  t0_10ms = 0;
data UINT8  t0_400ms = 0;


data UINT8	disbuff[3];	 //显示缓冲,存放查找后的段码
data UINT8	buffer[10];	  //uart buffer
data UINT8  seg_num = 0;		//数码管点亮顺序
data UINT8  dabuff[10];			//数据缓冲
data UINT8  machine_addr;		//local address
//---------------温度	----------------
data SINT16 tp;	
data SINT8  t ;


bit      bit_disp;			//显示标志 
bit 	bit_relay;						   
UINT8    ut_num=0;
//code UINT8  table[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
code UINT8  table[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};


void relay_os(bit bit_con);
//********************************************************************
void cpu_init()
{
	relay_os(0);
	INT_GLOBAL(0);
	INT_T1(0); 
   	INT_T0(0);
	INT_UART(0);
	
	P1 = 0xff;
	P3 = 0xff;
	setup_timer(T1_START_BY_TR | T1_TIMER | T1_MODE_2 | T0_START_BY_TR | T0_TIMER | T0_MODE_1);
    #ifdef STC_12X2052X		 //定义使用STC12C2052单片机。
	#ifdef EXT_1M			 //外部1MHz时钟
	SET_T0_DIV_BY_1;	    //timer0/timer1 定时器的时钟直接使用外部时钟。不做分频
	SET_T1_DIV_BY_1;
	set_timer1(0xF3F3);		//设置波特率4800
	UART_RATE_MUL;			//波特率翻倍
	#endif
    #endif

	#ifdef EXT_11M			//使用STC89C51单片机。11059200晶振
	//set_timer1(0xFDFD);		//9600
	 set_timer1(0xFAFA);		//4800
	#endif
 	T1_START;
   	setup_uart(UART_MODE_1);	//UART工作于模式1
	ENABLE_UART_RCV;


	bit_iap = flsh_sector_rd(EEP_SECTOR1,2,dabuff);
	if(!bit_iap)
		flsh_sector_rd(EEP_SECTOR1,2,dabuff);
	if(buffer[0] == SYS_ADDR)
	{
		machine_addr = dabuff[1];
	}
	else
		machine_addr = ADDR;

	set_timer0(TIMING_5MS);
	T0_START;
	INT_GLOBAL(1);
	INT_UART(1);
	INT_T0(1);
    WDT_DIV_BY_128;
	WDT_ENABLE;
	WDT_CLR;
}

/*********************************************************************
/串口中断服务程序
//处理串口接收中断,对于发送中断不作处理
***********************************************************************/
void uart_service() interrupt 4 using 1
{
UINT8  tmp;
    if(RI)
		UART_RIIF_CLR ;
	else
		return;
	
	tmp = rd_uart();
	if(!bit_ut_start)
	{
		if(tmp == HEAD)
		{
			bit_ut_start = 1;
			bit_ut_over = 0;
			ut_num = 0;
		}
	 }
	 else
	 {
	 	buffer[ut_num] = rd_uart();
		ut_num++;
		/*
		if(ut_num == 1)
		{
			if((buffer[0] != machine_addr) && (buffer[0] !=RA_FLAG))	//地址不符
			{							  //且地址不等于RA_FLAG.退出。RA_FLAG是读本机地址标志
				ut_num = 0;		
				bit_ut_start = 0;
				return;
			}
		} */
		if(ut_num == 3)
		{
			bit_ut_over = 1	;		//接收完毕一帧数据
			bit_ut_start = 0;		//接着重新开始接收
			ut_num = 0;
		}
	}
} 
//----------------------------------------------------------------
void relay_os(bit bit_con)
{
	if(bit_con)
	{
		con1=0;
		con2=1;
		bit_relay = 1;
	}
	else
	{
		con1 = 1;
		con2 = 0;
		bit_relay = 0;
	}
		delay_10clk(10000);	//30~40ms
		con1=0;
		con2=0;
}
/*********************************************************************
使用ULN2003或者2803驱动,8位并口,输出反相。驱动电流200mA
每个数码管用一个驱动器。驱动器的控制端使用p1口。p1口留上拉位置。
扫描信号由p0口产生,使用上拉,驱动4953.

*********************************************************************/

void display() 
{
	SEG_DRV =  0Xf8;		//SHUT LED
	seg_num++;
	if((seg_num>=3) )
	{
		seg_num = 0;
		SEG_DRV = 0xf9;
	}
	else
	{
		SEG_DRV = 0XF8 + (seg_num<<1);
	}  

	SEG_PARA = disbuff[seg_num];
}

/*********************************************************************/
void t0_service() interrupt 1 using 2
{
	set_timer0(TIMING_5MS);
	if(bit_disp)
	{
		display();
	}
	if(bit_10ms)
	{
		t0_10ms++;
		if(t0_10ms >= 3)
		{
			bit_10ms_over = 1;
			bit_10ms = 0;
			t0_10ms = 0;
		}
	 }
	 if(bit_400ms)
	 {
	 	t0_400ms++;
		if(t0_400ms >= 80)
		{
			bit_400ms_over = 1;
			bit_400ms = 0;
			t0_400ms = 0;
		}
	  }
}



/**********************************************************************/

/********************************************************************
//
//通过串口,输出一帧数据到pc机
//参数:输出数据的缓冲地址,输出数据的长度,不包括校验和、帧头等。
//发送数据的格式:帧头+本机地址+数据长度+数据包+校验和

*********************************************************************/
void mcu2pc(UINT8 *p,UINT8 l)
{
UINT8 i,tmp;
    en485 = 0;				//485发送使能
	delay_7clk(2);
	uart_putc(HEAD);
	uart_putc(machine_addr);
	uart_putc(l);			//数据长度。
	tmp = HEAD + machine_addr + l;
	for(i = 0;i<l ;i++)
	{
   		uart_putc(*p);			//p指向要发送的数据
		tmp = tmp + *p;
		p++;
	}
	uart_putc(tmp);				//发送校验和。
	en485 = 1;				//485接收使能
} 
/***********************************************************************************
//命令处理程序


************************************************************************************/
void cmd_process()
{
UINT8  i,tmp;
	INT_UART(false);			//禁止中断
	if(buffer[0] != machine_addr)
	{
		if((buffer[0] != RA_FLAG) || (buffer[1] != READ_ADDR))
		{
			INT_UART(true);
			return;
		}
	}
	i = HEAD + buffer[0] + buffer[1];	//校验和
	if( i != buffer[2])
	{
		INT_UART(true);
		return;
	}
   switch(buffer[1])
   {
	case SET_ADDR:		//设置地址
		i = uart_getc();
		tmp = uart_getc();
		if( tmp != i)		
		{
	//		uart_putc(ERR_VERI);
			i = ERR_VERI;
			mcu2pc(&i,1);
			INT_UART(true);
			return;
		}
		buffer[1] = i;
		buffer[0] = SYS_ADDR;		//系统设置标志
		bit_iap = flsh_sector_wr(EEP_SECTOR1,2,buffer);		
		if(bit_iap)
		{
			i = SUCC_ADDR;
			mcu2pc(&i,1);
			machine_addr = buffer[1];
				//设置地址成功
		}
		else
		{
			i = ERR_ADDR;
			mcu2pc(&i,1);
					//设置地址失败
		}
		break;
	case READ_ADDR:		   //读本机地址
			mcu2pc(&machine_addr,1);		
		break;
	case READ_T:				//读温度
			if(bit_tpsensor)
			{
				buffer[0] = ERR_TH;
			}
			else
			{
				buffer[0] = SUCC_TH;		//读数据无误
			}
			
			buffer[1] = tp >> 8;
			buffer[2] = tp & 0x00ff;
			mcu2pc(buffer,3);			//发送3个字节。状态+温度h+温度l
		break;
	case READ_S:
			if(bit_tpsensor)
			{
				buffer[0] = ERR_TH;
			}
			else
			{
				buffer[0] = SUCC_TH;		//读数据无误
			}
			
			buffer[1] = t;
			mcu2pc(buffer,2);			//发送3个字节。状态+温度h+温度l	
		break;
	case OPEN:
			relay_os(1);
			buffer[0] = ASK;
			mcu2pc(buffer,1);
		break;
	case SHUT:
			relay_os(0);
			buffer[0] = ASK;
			mcu2pc(buffer,1);
		break;
	case TEST:
			  SEG_DRV =  uart_getc()   ;
		break;
		default:
			break;
		}
	INT_UART(true);
}
/**************************************************************************/
void look_up_code()
{
	if(dabuff[6]==0x01)
	{
		if(dabuff[2] == 0 && dabuff[3] == 0)
		{	
			disbuff[0] = ~table[11];			//first seg dark
			disbuff[1] = ~table[dabuff[4]] | 0x80;		//个位显示在Q1
			disbuff[2] = ~table[dabuff[5]];		//小数位显示在Q2
		}
		else if(dabuff[2] == 0 && dabuff[3] != 0)
		{
			disbuff[0] = ~table[dabuff[3]];		//十位显示在Q0
			disbuff[1] = ~table[dabuff[4]] | 0x80;		//个位显示在Q1
			disbuff[2] = ~table[dabuff[5]];		//小数位显示在Q2
		}
		else if(dabuff[2] != 0)
		{
			disbuff[0] = ~table[dabuff[2]];
			disbuff[1] = ~table[dabuff[3]];
			disbuff[2] = ~table[dabuff[4]];
		}
	}
	else if(dabuff[6] == 0x00)
	{
		disbuff[0] = ~table[10];
		if(dabuff[3] == 0)
		{
			disbuff[1] = ~table[dabuff[4]] | 0x80;
			disbuff[2] = ~table[dabuff[5]];
		}
		else
		{
			disbuff[1] = ~table[dabuff[3]];
			disbuff[2] = ~table[dabuff[4]];
		}
	} 
	else
	{
		dabuff[6] = 0x01;
		return;
	}
}	
/**************************************************************************/
void do_tem()
{
SINT8 tmp,tmp1;
 	ibus_reset();
	read_rom(dabuff);
	if(dabuff[0] != 0x28)
	{
		bit_tpsensor = 1;
		return;
	}
	bit_tpsensor = 0;
	read_scratchpad(dabuff);
	if((dabuff[4]&0x60) != 0x40)
	{
		dabuff[0]=125;
		dabuff[1]=-55;
		dabuff[2]=0x5f;   //1f->9bit/93.75ms;3f->10bit/187.5ms;5f->11bit/375ms;7f->12bit/750ms;
		ibus_reset();
		write_skip();
		write_scratchpad(dabuff);
		copy_scratchpad();
	}
	ibus_reset();
	write_skip();
	convert_t();
	ibus_reset();
	write_skip(); 
	read_temperature(dabuff); //read temperature
	tp = dabuff[1] << 8 | dabuff[0];
	t = (dabuff[1] << 4) | (dabuff[0] >> 4); 
	
	dabuff[2]=dabuff[3]=dabuff[4]=dabuff[5] =dabuff[6]=0;
  // 百位		十位       个位	    小数位    状态位
	tmp = t;
	tmp1 = dabuff[0] & 0x0e;
	if(tmp >= 0)
	{								 
		dabuff[6] = 0x01;			 //表示正数
		while(tmp>=100)
		{
			tmp = tmp - 100;		 //温度大于等于100度.百位加1
			dabuff[2]++;
		}
		while(tmp>=10)
		{
			tmp = tmp-10;			 //大于等于10度,十位加一
			dabuff[3]++;
		}
		dabuff[4] = tmp;			 //个位就是剩下的数
		
	}
	else
	{
		dabuff[6] = 0x00;			 //温度值小于0度,负值
		dabuff[2] = 10;				//因为负值最小为-55度,没有百位,该位用作-号		
		while(t<=10)
		{
			tmp = tmp+10;			 //负10位,加10,直到十位为0.
			dabuff[3]++;
		}
		while(tmp<0)					//个位,不断加1,计数.知道为0
		{
			tmp = tmp+1;
			dabuff[4]++;
		}
		tmp1 = tmp1 -1;
		tmp1 &= 0x0f;
		tmp1 = ~tmp1;
		
     }
	 switch(tmp1)
		{
			case 0x0:
				dabuff[5]=0;
				break;
			case 0x02:
				dabuff[5] = 1;
				break;
			case 0x04:
				dabuff[5] = 2;
				break;
			case 0x06:
				dabuff[5] = 4;
				break;
			case 0x08:
				dabuff[5] = 5;
				break;
			case 0x0a:
				dabuff[5] = 7;
				break;
			case 0x0c:
				dabuff[5] = 8;
				break;
			case 0x0e:
				dabuff[5] = 9;
				break;
			default:
				dabuff[5] = 6;
				break;
			} 
	 look_up_code();


}
/**************************************************************************/


void main(void)
{
UINT8   i;
	cpu_init();
	bit_disp = 1;    //start display scan
	//----------------------------
	while(1)
	{ 
	 WDT_CLR;
	 do_tem();
	 if(bit_ut_over)
	 {
	 	cmd_process();
		bit_ut_over = 0;	
	  }
	}

}		

⌨️ 快捷键说明

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